summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-06-06 14:53:28 +0000
committerGerald Carter <jerry@samba.org>2003-06-06 14:53:28 +0000
commit7e7904e91ebf6c33cea422e903762409099717d1 (patch)
tree6efec48ab63a369d1597c4b9c8fa9fa1a39599d8
parent3fbef9f51c5b3741c53752834352db04e1c2660d (diff)
downloadsamba-7e7904e91ebf6c33cea422e903762409099717d1.tar.gz
working on creating the 3.0 release tree
-rw-r--r--source/Makefile.in208
-rw-r--r--source/aclocal.m426
-rw-r--r--source/auth/auth.c8
-rw-r--r--source/auth/auth_domain.c8
-rw-r--r--source/auth/auth_rhosts.c4
-rw-r--r--source/auth/auth_sam.c108
-rw-r--r--source/auth/auth_server.c13
-rw-r--r--source/auth/auth_unix.c2
-rw-r--r--source/auth/auth_util.c82
-rw-r--r--source/auth/auth_winbind.c2
-rw-r--r--source/change-log2
-rw-r--r--source/client/client.c4
-rwxr-xr-xsource/client/mount.cifs.c1
-rwxr-xr-xsource/config.sub236
-rw-r--r--source/configure.in477
-rw-r--r--source/include/.cvsignore1
-rw-r--r--source/include/idmap.h10
-rw-r--r--source/include/includes.h21
-rw-r--r--source/include/ntioctl.h44
-rw-r--r--source/include/ntlmssp.h4
-rw-r--r--source/include/rpc_lsa.h20
-rw-r--r--source/include/rpc_secdes.h19
-rw-r--r--source/include/safe_string.h18
-rw-r--r--source/include/smb.h23
-rw-r--r--source/include/smb_macros.h57
-rw-r--r--source/include/smbprofile.h8
-rw-r--r--source/include/trans2.h1
-rw-r--r--source/include/version.h2
-rw-r--r--source/include/vfs.h420
-rw-r--r--source/lib/charcnv.c15
-rw-r--r--source/lib/module.c23
-rw-r--r--source/lib/system.c125
-rw-r--r--source/lib/util.c13
-rw-r--r--source/lib/util_sid.c6
-rw-r--r--source/lib/util_sock.c13
-rw-r--r--source/lib/util_str.c22
-rw-r--r--source/libads/ads_utils.c46
-rw-r--r--source/libads/kerberos_verify.c8
-rw-r--r--source/libads/krb5_setpw.c35
-rw-r--r--source/libsmb/cliconnect.c16
-rw-r--r--source/libsmb/clikrb5.c28
-rw-r--r--source/libsmb/clispnego.c2
-rw-r--r--source/libsmb/namequery_dc.c155
-rw-r--r--source/libsmb/nmblib.c2
-rw-r--r--source/libsmb/ntlmssp.c8
-rw-r--r--source/libsmb/smb_signing.c28
-rw-r--r--source/libsmb/smbencrypt.c126
-rw-r--r--source/locking/posix.c11
-rw-r--r--source/modules/vfs_audit.c232
-rw-r--r--source/modules/vfs_extd_audit.c241
-rw-r--r--source/modules/vfs_fake_perms.c240
-rw-r--r--source/modules/vfs_netatalk.c78
-rw-r--r--source/modules/vfs_recycle.c516
-rw-r--r--source/msdfs/msdfs.c14
-rw-r--r--source/nmbd/nmbd.c67
-rw-r--r--source/nmbd/nmbd_become_lmb.c3
-rw-r--r--source/nmbd/nmbd_browserdb.c4
-rw-r--r--source/nmbd/nmbd_browsesync.c8
-rw-r--r--source/nmbd/nmbd_incomingdgrams.c14
-rw-r--r--source/nmbd/nmbd_processlogon.c67
-rw-r--r--source/nmbd/nmbd_sendannounce.c8
-rw-r--r--source/nmbd/nmbd_serverlistdb.c4
-rw-r--r--source/nmbd/nmbd_winsserver.c416
-rw-r--r--source/nmbd/nmbd_workgroupdb.c2
-rw-r--r--source/nsswitch/winbindd.h2
-rw-r--r--source/nsswitch/winbindd_cache.c4
-rw-r--r--source/nsswitch/winbindd_cm.c459
-rw-r--r--source/nsswitch/winbindd_misc.c2
-rw-r--r--source/nsswitch/winbindd_pam.c88
-rw-r--r--source/param/loadparm.c230
-rw-r--r--source/passdb/pdb_interface.c2
-rw-r--r--source/passdb/pdb_ldap.c449
-rw-r--r--source/passdb/pdb_smbpasswd.c34
-rw-r--r--source/printing/lpq_parse.c60
-rw-r--r--source/printing/nt_printing.c122
-rw-r--r--source/printing/pcap.c6
-rw-r--r--source/printing/printfsp.c2
-rw-r--r--source/python/py_winbind.c4
-rw-r--r--source/rpc_client/cli_lsarpc.c56
-rw-r--r--source/rpc_client/cli_netlogon.c20
-rw-r--r--source/rpc_client/cli_pipe.c107
-rw-r--r--source/rpc_client/cli_samr.c2
-rw-r--r--source/rpc_parse/parse_lsa.c135
-rw-r--r--source/rpc_parse/parse_misc.c142
-rw-r--r--source/rpc_parse/parse_net.c30
-rw-r--r--source/rpc_parse/parse_prs.c8
-rw-r--r--source/rpc_parse/parse_samr.c44
-rw-r--r--source/rpc_parse/parse_sec.c57
-rw-r--r--source/rpc_server/srv_lsa.c185
-rw-r--r--source/rpc_server/srv_lsa_nt.c162
-rw-r--r--source/rpc_server/srv_samr_nt.c9
-rw-r--r--source/rpc_server/srv_spoolss_nt.c30
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c13
-rw-r--r--source/rpc_server/srv_util.c2
-rw-r--r--source/rpcclient/cmd_lsarpc.c45
-rw-r--r--source/rpcclient/cmd_netlogon.c9
-rw-r--r--source/rpcclient/cmd_spoolss.c17
-rw-r--r--source/rpcclient/rpcclient.c20
-rw-r--r--source/sam/idmap.c97
-rw-r--r--source/sam/idmap_ldap.c576
-rw-r--r--source/sam/idmap_tdb.c10
-rw-r--r--source/script/.cvsignore1
-rwxr-xr-xsource/script/build_env.sh26
-rwxr-xr-xsource/script/installswat.sh2
-rw-r--r--source/smbd/.cvsignore1
-rw-r--r--source/smbd/close.c2
-rw-r--r--source/smbd/conn.c39
-rw-r--r--source/smbd/connection.c9
-rw-r--r--source/smbd/dfree.c12
-rw-r--r--source/smbd/dir.c20
-rw-r--r--source/smbd/dosmode.c14
-rw-r--r--source/smbd/fileio.c14
-rw-r--r--source/smbd/filename.c8
-rw-r--r--source/smbd/files.c4
-rw-r--r--source/smbd/mangle_hash.c4
-rw-r--r--source/smbd/negprot.c14
-rw-r--r--source/smbd/notify_hash.c4
-rw-r--r--source/smbd/nttrans.c707
-rw-r--r--source/smbd/open.c26
-rw-r--r--source/smbd/oplock.c2
-rw-r--r--source/smbd/posix_acls.c453
-rw-r--r--source/smbd/quotas.c114
-rw-r--r--source/smbd/reply.c84
-rw-r--r--source/smbd/server.c10
-rw-r--r--source/smbd/service.c23
-rw-r--r--source/smbd/session.c11
-rw-r--r--source/smbd/statcache.c2
-rw-r--r--source/smbd/trans2.c351
-rw-r--r--source/smbd/utmp.c54
-rw-r--r--source/smbd/vfs-wrap.c273
-rw-r--r--source/smbd/vfs.c583
-rw-r--r--source/smbwrapper/shared.c4
-rw-r--r--source/smbwrapper/smbw_dir.c5
-rw-r--r--source/torture/cmd_vfs.c201
-rw-r--r--source/torture/vfstest.c20
-rw-r--r--source/torture/vfstest.h2
-rw-r--r--source/utils/editreg.c42
-rw-r--r--source/utils/net_ads.c34
-rw-r--r--source/utils/net_ads_cldap.c242
-rw-r--r--source/utils/net_rpc.c110
-rw-r--r--source/utils/net_rpc_samsync.c29
-rw-r--r--source/utils/ntlm_auth.c569
-rw-r--r--source/web/swat.c46
143 files changed, 6307 insertions, 5529 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 5fa3018c696..1ebaa37d0b1 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -31,6 +31,7 @@ PRINTLIBS=@PRINTLIBS@
AUTHLIBS=@AUTHLIBS@
ACLLIBS=@ACLLIBS@
PASSDBLIBS=@PASSDBLIBS@
+IDMAP_LIBS=@IDMAP_LIBS@
ADSLIBS=@ADSLIBS@
KRB5LIBS=@KRB5_LIBS@
@@ -41,8 +42,8 @@ INSTALLCLIENTCMD_SH=@INSTALLCLIENTCMD_SH@
INSTALLCLIENTCMD_A=@INSTALLCLIENTCMD_A@
VPATH=@srcdir@
-srcdir=@srcdir@
-builddir=@builddir@
+srcdir=@abs_srcdir@
+builddir=@abs_builddir@
SHELL=/bin/sh
# XXX: Perhaps this should be @SHELL@ instead -- apparently autoconf
@@ -60,6 +61,7 @@ LIBDIR = @libdir@
VFSLIBDIR = $(LIBDIR)/vfs
PDBLIBDIR = $(LIBDIR)/pdb
RPCLIBDIR = $(LIBDIR)/rpc
+IDMAPLIBDIR = $(LIBDIR)/idmap
CHARSETLIBDIR = $(LIBDIR)/charset
AUTHLIBDIR = $(LIBDIR)/auth
CONFIGDIR = @configdir@
@@ -119,15 +121,15 @@ PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS)
# Note that all executable programs now provide for an optional executable suffix.
SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ \
- bin/wrepld@EXEEXT@ @EXTRA_SBIN_PROGS@
+ @EXTRA_SBIN_PROGS@
BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
bin/testparm@EXEEXT@ bin/testprns@EXEEXT@ bin/smbstatus@EXEEXT@
BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \
- bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@
+ bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/editreg@EXEEXT@
BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \
- bin/editreg@EXEEXT@ bin/smbcquotas@EXEEXT@
+ bin/smbcquotas@EXEEXT@
TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \
bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \
@@ -141,14 +143,13 @@ SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@
SCRIPTS = $(srcdir)/script/smbtar $(builddir)/script/findsmb
-QUOTAOBJS=@QUOTAOBJS@
-
VFS_MODULES = @VFS_MODULES@
PDB_MODULES = @PDB_MODULES@
RPC_MODULES = @RPC_MODULES@
+IDMAP_MODULES = @IDMAP_MODULES@
CHARSET_MODULES = @CHARSET_MODULES@
AUTH_MODULES = @AUTH_MODULES@
-MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES)
+MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES)
######################################################################
# object file lists
@@ -157,6 +158,8 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(CHARSET_MODULES) $(AUTH
TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o
TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o
+SMBLDAP_OBJ = @SMBLDAP@
+
LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/md4.o \
lib/interfaces.o lib/pidfile.o lib/replace.o \
@@ -175,10 +178,9 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
nsswitch/wb_client.o nsswitch/wb_common.o \
lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
- lib/module.o lib/genparser.o lib/genparser_samba.o \
- lib/ldap_escape.o @CHARSET_STATIC@
+ lib/module.o lib/ldap_escape.o @CHARSET_STATIC@
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
+LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
READLINE_OBJ = lib/readline.o
@@ -204,9 +206,7 @@ SECRETS_OBJ = passdb/secrets.o
LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \
libsmb/namequery.o
-LIBNTLMSSP_OBJ = libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o
-
-LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o
+LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \
@@ -219,7 +219,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
libsmb/passchange.o libsmb/doserr.o \
libsmb/trustdom_cache.o \
- $(RPC_PARSE_OBJ1) $(LIBNTLMSSP_OBJ) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
+ $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_netlogon.o rpc_client/cli_srvsvc.o \
@@ -279,26 +279,19 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \
- passdb/privileges.o @LDAP_OBJ@ @PDB_STATIC@
+ passdb/privileges.o @PDB_STATIC@
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
-DEVEL_HELP_OBJ = modules/developer.o
-
-SAM_STATIC_MODULES = sam/sam_plugin.o sam/sam_skel.o sam/sam_ads.o
+DEVEL_HELP_OBJ = modules/weird.o
-IDMAP_OBJ = sam/idmap.o sam/idmap_util.o sam/idmap_tdb.o
-
-SAM_OBJ = sam/account.o sam/get_set_account.o sam/get_set_group.o \
- sam/get_set_domain.o sam/interface.o $(SAM_STATIC_MODULES)
-
-SAMTEST_OBJ = torture/samtest.o torture/cmd_sam.o $(PARAM_OBJ) $(SAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(READLINE_OBJ) lib/util_seaccess.o $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(GROUPDB_OBJ)
+IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@
GROUPDB_OBJ = groupdb/mapping.o
PROFILE_OBJ = profile/profile.o
PROFILES_OBJ = utils/profiles.o
-EDITREG_OBJ = utils/editreg.o lib/snprintf.o
+EDITREG_OBJ = utils/editreg.o
OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
@@ -306,9 +299,9 @@ NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o
VFS_AUDIT_OBJ = modules/vfs_audit.o
VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
+VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o
VFS_RECYCLE_OBJ = modules/vfs_recycle.o
VFS_NETATALK_OBJ = modules/vfs_netatalk.o
-VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -330,6 +323,8 @@ MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash
SMBD_OBJ_MAIN = smbd/server.o
+BUILDOPT_OBJ = smbd/build_options.o
+
SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/utmp.o smbd/session.o \
smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
@@ -342,20 +337,19 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o \
- smbd/build_options.o \
- smbd/change_trust_pw.o \
+ lib/sysquotas.o smbd/change_trust_pw.o smbd/fake_file.o \
+ smbd/quotas.o smbd/ntquotas.o \
$(MANGLE_OBJ) @VFS_STATIC@
SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \
- $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) \
+ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
- $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \
+ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
- $(IDMAP_OBJ)
-
+ $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) $(IDMAP_OBJ) \
+ $(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
printing/print_cups.o printing/print_generic.o \
@@ -395,7 +389,7 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
- $(POPT_LIB_OBJ) $(IDMAP_OBJ)
+ $(POPT_LIB_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ)
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -420,14 +414,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
$(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \
- $(IDMAP_OBJ)
+ $(IDMAP_OBJ) $(SMBLDAP_OBJ)
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(IDMAP_OBJ)
-
-SMBGROUPEDIT_OBJ = utils/smbgroupedit.o $(GROUPDB_OBJ) $(PARAM_OBJ) \
- $(LIBSAMBA_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(IDMAP_OBJ)
+ $(POPT_LIB_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ)
RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
@@ -441,7 +432,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
- $(IDMAP_OBJ)
+ $(IDMAP_OBJ) $(SMBLDAP_OBJ)
PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
@@ -469,7 +460,7 @@ LIBBIGBALLOFMUD_MAJOR = 0
LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
- $(GROUPDB_OBJ) $(KRBCLIENT_OBJ)
+ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po)
@@ -489,7 +480,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
- $(IDMAP_OBJ)
+ $(IDMAP_OBJ) $(SMBLDAP_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ) $(KRBCLIENT_OBJ)
@@ -563,12 +554,12 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \
$(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
- $(QUOTAOBJS) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \
+ $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
- $(IDMAP_OBJ) $(RPC_ECHO_OBJ)
+ $(IDMAP_OBJ) $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ)
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \
$(LIB_OBJ) $(NSSWINS_OBJ)
@@ -607,10 +598,11 @@ WINBINDD_OBJ = \
$(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
- $(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) \
- $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
+ $(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) \
+ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
-WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o $(POPT_LIB_OBJ)
+WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
+ $(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
WINBIND_NSS_OBJ = nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@
@@ -621,7 +613,7 @@ POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
TDBBACKUP_OBJ = tdb/tdbbackup.o $(TDBBASE_OBJ)
-NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBNTLMSSP_OBJ) $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ)
+NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ)
######################################################################
# now the rules...
@@ -663,7 +655,7 @@ wins : SHOWFLAGS nsswitch/libnss_wins.@SHLIBEXT@
modules: SHOWFLAGS proto_exists $(MODULES)
-everything: all libsmbclient debug2html smbfilter talloctort torture
+everything: all libsmbclient debug2html smbfilter talloctort modules torture
.SUFFIXES:
.SUFFIXES: .c .o .po .po32 .lo
@@ -710,6 +702,14 @@ dynconfig.po: dynconfig.c Makefile
@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@
@POBAD_CC@ @mv $*.po.o $@
+smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h
+ @echo Compiling $*.c
+ @$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
+
+smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk
+ @echo Generating $@
+ @dir=smbd $(MAKEDIR) && $(AWK) -f $(srcdir)/script/mkbuildoptions.awk > $(builddir)/smbd/build_options.c < $(srcdir)/include/config.h.in
+
.c.po:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
@@ -736,7 +736,7 @@ bin/.dummy:
bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(ADSLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \
- $(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(LIBS) @POPTLIBS@
+ $(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(LIBS) @POPTLIBS@
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -749,11 +749,11 @@ bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \
- $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) @POPTLIBS@ $(KRB5LIBS)
+ $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) @POPTLIBS@ $(KRB5LIBS)
bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(IDMAP_LIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -761,7 +761,7 @@ bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS) $(PASSDBLIBS)
bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -809,19 +809,15 @@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(IDMAP_LIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS)
bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(ADSLIBS)
-
-bin/smbgroupedit@EXEEXT@: $(SMBGROUPEDIT_OBJ) bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBGROUPEDIT_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS)
bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -914,7 +910,7 @@ bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS)
bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
@echo Linking bigballofmud shared library $@
@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \
- @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(ADSLIBS)
+ @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS)
ln -snf libbigballofmud.so bin/libbigballofmud.so.0
# It would be nice to build a static bigballofmud too, but when I try
@@ -975,7 +971,7 @@ nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ)
@SONAMEFLAG@`basename $@`
bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
+ @echo "Linking $@"
@$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) @LDAP_LIBS@
nsswitch/@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
@@ -984,7 +980,7 @@ nsswitch/@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
@WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@`
nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy
- @echo Linking $@
+ @echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_OBJ) \
@SONAMEFLAG@`basename $@` -lpam
@@ -1051,6 +1047,11 @@ bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.po)
@$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.po) @XML_LIBS@ \
@SONAMEFLAG@`basename $@`
+bin/winbind_idmap.@SHLIBEXT@: sam/idmap_winbind.po
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_winbind.po \
+ @SONAMEFLAG@`basename $@`
+
bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ:.o=.po)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ:.o=.po) \
@@ -1076,11 +1077,9 @@ bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.po)
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.po) \
@SONAMEFLAG@`basename $@`
-bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
- $(UBIQX_OBJ) $(SECRETS_OBJ) @BUILD_POPT@ bin/.dummy
+bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(LINK) -o $@ $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
- $(UBIQX_OBJ) $(SECRETS_OBJ) $(LIBS) @POPTLIBS@
+ @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
@@ -1107,14 +1106,14 @@ bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringove
bin/t_doschar@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_doschar.o
$(CC) $(FLAGS) -o $@ $(LIBS) torture/t_doschar.o -L ./bin -lbigballofmud
-
bin/t_push_ucs2@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_push_ucs2.o
$(CC) $(FLAGS) -o $@ $(LIBS) torture/t_push_ucs2.o -L ./bin -lbigballofmud
bin/t_snprintf@EXEEXT@: lib/snprintf.c
$(CC) $(FLAGS) -o $@ -DTEST_SNPRINTF lib/snprintf.c -lm
+install: installbin installman installscripts installdat installswat
-install: installbin installman installscripts installdat installswat installmodules installclientlib
+install-everything: install installmodules
# DESTDIR is used here to prevent packagers wasting their time
# duplicating the Makefile. Remove it and you will have the privelege
@@ -1125,7 +1124,7 @@ install: installbin installman installscripts installdat installswat installmodu
# is not used
installdirs:
- @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(PRIVATEDIR) $(DESTDIR)$(VFSLIBDIR) $(DESTDIR)$(PDBLIBDIR) $(DESTDIR)$(PIDDIR) $(DESTDIR)$(LOCKDIR)
+ @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(PRIVATEDIR) $(DESTDIR)$(PIDDIR) $(DESTDIR)$(LOCKDIR)
installservers: all installdirs
@$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SBIN_PROGS)
@@ -1139,6 +1138,7 @@ installmodules: modules installdirs
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(VFS_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(PDB_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(RPCLIBDIR) $(RPC_MODULES)
+ @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES)
@@ -1172,7 +1172,7 @@ python_ext: $(PYTHON_PICOBJS)
fi
PYTHON_OBJS="$(PYTHON_PICOBJS)" \
PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \
- LIBS="$(LIBS) $(PASSDBLIBS) $(KRB5LIBS)" \
+ LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS)" \
$(PYTHON) python/setup.py build
python_install: $(PYTHON_PICOBJS)
@@ -1238,7 +1238,7 @@ clean: delheaders python_clean
# This is quite ugly actually.. But we need to make
# sure the changes to include/config.h are used.
modules_clean:
- @-rm -f @MODULES_CLEAN@ auth/auth.o passdb/pdb_interface.o rpc_server/srv_pipe_hnd.o lib/iconv.o smbd/vfs.o
+ @-rm -f @MODULES_CLEAN@ auth/auth.o passdb/pdb_interface.o smbd/server.o lib/iconv.o smbd/vfs.o sam/idmap.o
# Making this target will just make sure that the prototype files
# exist, not necessarily that they are up to date. Since they're
@@ -1246,81 +1246,67 @@ modules_clean:
# afterwards.
proto_exists: include/proto.h include/wrepld_proto.h include/build_env.h \
nsswitch/winbindd_proto.h web/swat_proto.h \
- client/client_proto.h utils/net_proto.h
-# include/tdbsam2_parse_info.h
+ client/client_proto.h utils/net_proto.h smbd/build_options.c
delheaders:
@echo Removing prototype headers
- @/bin/rm -f $(srcdir)/include/proto.h $(srcdir)/include/build_env.h
- @/bin/rm -f $(srcdir)/include/wrepld_proto.h $(srcdir)/nsswitch/winbindd_proto.h
- @/bin/rm -f $(srcdir)/web/swat_proto.h
- @/bin/rm -f $(srcdir)/client/client_proto.h $(srcdir)/utils/net_proto.h
- @/bin/rm -f $(srcdir)/include/tdbsam2_parse_info.h
-
- @/bin/rm -f include/proto.h include/build_env.h include/wrepld_proto.h \
- nsswitch/winbindd_proto.h web/swat_proto.h \
- client/client_proto.h utils/net_proto.h
-# include/tdbsam2_parse_info.h
-
-include/proto.h:
+ @rm -f include/proto.h include/build_env.h include/wrepld_proto.h \
+ nsswitch/winbindd_proto.h web/swat_proto.h \
+ client/client_proto.h utils/net_proto.h \
+ smbd/build_options.c
+
+MKPROTO_SH = $(srcdir)/script/mkproto.sh
+
+include/proto.h: smbd/build_options.c
@echo Building include/proto.h
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
-h _PROTO_H_ $(builddir)/include/proto.h \
$(PROTO_OBJ)
-include/build_env.h:
+include/build_env.h: script/build_env.sh
@echo Building include/build_env.h
- @cd $(srcdir) && $(SHELL) script/build_env.sh $(srcdir) $(builddir) $(CC) > $(builddir)/include/build_env.h
+ @$(SHELL) $(srcdir)/script/build_env.sh $(srcdir) $(builddir) $(CC) \
+ > $(builddir)/include/build_env.h
include/wrepld_proto.h:
@echo Building include/wrepld_proto.h
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
-h _WREPLD_PROTO_H_ $(builddir)/include/wrepld_proto.h \
$(WREPL_OBJ1)
nsswitch/winbindd_proto.h:
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
- -h _WINBINDD_PROTO_H_ nsswitch/winbindd_proto.h \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
+ -h _WINBINDD_PROTO_H_ $(builddir)/nsswitch/winbindd_proto.h \
$(WINBINDD_OBJ1)
web/swat_proto.h:
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
- -h _SWAT_PROTO_H_ web/swat_proto.h \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
+ -h _SWAT_PROTO_H_ $(builddir)/web/swat_proto.h \
$(SWAT_OBJ1)
client/client_proto.h:
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
- -h _CLIENT_PROTO_H_ client/client_proto.h \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
+ -h _CLIENT_PROTO_H_ $(builddir)/client/client_proto.h \
$(CLIENT_OBJ1)
utils/net_proto.h:
- @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
- -h _CLIENT_PROTO_H_ utils/net_proto.h \
+ @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
+ -h _CLIENT_PROTO_H_ $(builddir)/utils/net_proto.h \
$(NET_OBJ1)
-# not used yet an perl dependent
-#include/tdbsam2_parse_info.h:
-# @if test -n "$(PERL)"; then \
-# cd $(srcdir) && @PERL@ -w script/genstruct.pl \
-# -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \
-# include/tdbsam2.h; \
-# else \
-# echo Unable to build $@, continuing; \
-# fi
-
# "make headers" or "make proto" calls a subshell because we need to
# make sure these commands are executed in sequence even for a
# parallel make.
headers:
$(MAKE) delheaders; \
+ $(MAKE) smbd/build_options.c; \
$(MAKE) include/proto.h; \
$(MAKE) include/build_env.h; \
$(MAKE) include/wrepld_proto.h; \
$(MAKE) nsswitch/winbindd_proto.h; \
$(MAKE) web/swat_proto.h; \
$(MAKE) client/client_proto.h; \
- $(MAKE) utils/net_proto.h;
-# $(MAKE) include/tdbsam2_parse_info.h
+ $(MAKE) utils/net_proto.h
proto: headers
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index f470e2e8b0e..dd1ae8df72b 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -678,3 +678,29 @@ dnl AC_DISABLE_STATIC - set the default static flag to --disable-static
AC_DEFUN([AC_DISABLE_STATIC],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_STATIC(no)])
+
+dnl AC_TRY_RUN_STRICT(PROGRAM,CFLAGS,CPPFLAGS,LDFLAGS,
+dnl [ACTION-IF-TRUE],[ACTION-IF-FALSE],
+dnl [ACTION-IF-CROSS-COMPILING = RUNTIME-ERROR])
+AC_DEFUN( [AC_TRY_RUN_STRICT],
+[
+ old_CFLAGS="$CFLAGS";
+ CFLAGS="$2";
+ export CFLAGS;
+ old_CPPFLAGS="$CPPFLAGS";
+ CPPFLAGS="$3";
+ export CPPFLAGS;
+ old_LDFLAGS="$LDFLAGS";
+ LDFLAGS="$4";
+ export LDFLAGS;
+ AC_TRY_RUN([$1],[$5],[$6],[$7]);
+ CFLAGS="$old_CFLAGS";
+ old_CFLAGS="";
+ export CFLAGS;
+ CPPFLAGS="$old_CPPFLAGS";
+ old_CPPFLAGS="";
+ export CPPFLAGS;
+ LDFLAGS="$old_LDFLAGS";
+ old_LDFLAGS="";
+ export LDFLAGS;
+])
diff --git a/source/auth/auth.c b/source/auth/auth.c
index 0c4fe768307..02c7eb6d84a 100644
--- a/source/auth/auth.c
+++ b/source/auth/auth.c
@@ -63,7 +63,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
struct auth_init_function_entry *entry = backends;
while(entry) {
- if (strequal(entry->name, name)) return entry;
+ if (strcmp(entry->name, name)==0) return entry;
entry = entry->next;
}
@@ -262,12 +262,6 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
break;
}
- /* This is one of the few places the *relies* (rather than just sets defaults
- on the value of lp_security(). This needs to change. A new paramater
- perhaps? */
- if (lp_security() >= SEC_SERVER)
- smb_user_control(user_info, *server_info, nt_status);
-
if (NT_STATUS_IS_OK(nt_status)) {
pdb_username = pdb_get_username((*server_info)->sam_account);
if (!(*server_info)->guest) {
diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index bc03fecf749..29916842805 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -130,7 +130,6 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
struct in_addr dest_ip;
fstring remote_machine;
NTSTATUS result;
- uint32 neg_flags = 0x000001ff;
*retry = False;
@@ -214,7 +213,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
return NT_STATUS_NO_MEMORY;
}
- result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd, &neg_flags, 2);
+ result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
@@ -341,6 +340,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
*/
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
+ NULL,
user_info->smb_name.str, user_info->domain.str,
user_info->wksta_name.str, chal,
user_info->lm_resp, user_info->nt_resp,
@@ -458,7 +458,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -546,7 +546,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
}
/* module initialisation */
-NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/auth/auth_rhosts.c b/source/auth/auth_rhosts.c
index 34110831161..2f0de6b81e5 100644
--- a/source/auth/auth_rhosts.c
+++ b/source/auth/auth_rhosts.c
@@ -181,7 +181,7 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex
}
/* module initialisation */
-NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -235,7 +235,7 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index a7e49a270f0..161376616b1 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -28,9 +28,9 @@
/****************************************************************************
core of smb password checking routine.
****************************************************************************/
-static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
+static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
const uchar *part_passwd,
- DATA_BLOB sec_blob,
+ const DATA_BLOB *sec_blob,
uint8 user_sess_key[16])
{
/* Finish the encryption of part_passwd. */
@@ -42,17 +42,17 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
return False;
}
- if (sec_blob.length != 8) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob.length));
+ if (sec_blob->length != 8) {
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob->length));
return False;
}
- if (nt_response.length != 24) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length));
+ if (nt_response->length != 24) {
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response->length));
return False;
}
- SMBOWFencrypt(part_passwd, sec_blob.data, p24);
+ SMBOWFencrypt(part_passwd, sec_blob->data, p24);
if (user_sess_key != NULL)
{
SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
@@ -61,16 +61,16 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |"));
+ DEBUG(100,("Part password (P16) was |\n"));
dump_data(100, part_passwd, 16);
- DEBUG(100,("Password from client was |"));
- dump_data(100, nt_response.data, nt_response.length);
- DEBUG(100,("Given challenge was |"));
- dump_data(100, sec_blob.data, sec_blob.length);
- DEBUG(100,("Value from encryption was |"));
+ DEBUGADD(100,("Password from client was |\n"));
+ dump_data(100, nt_response->data, nt_response->length);
+ DEBUGADD(100,("Given challenge was |\n"));
+ dump_data(100, sec_blob->data, sec_blob->length);
+ DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, p24, 24);
#endif
- return (memcmp(p24, nt_response.data, 24) == 0);
+ return (memcmp(p24, nt_response->data, 24) == 0);
}
@@ -79,9 +79,9 @@ core of smb password checking routine. (NTLMv2, LMv2)
Note: The same code works with both NTLMv2 and LMv2.
****************************************************************************/
-static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
+static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
const uchar *part_passwd,
- const DATA_BLOB sec_blob,
+ const DATA_BLOB *sec_blob,
const char *user, const char *domain,
uint8 user_sess_key[16])
{
@@ -98,42 +98,43 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
return False;
}
- if (ntv2_response.length < 16) {
+ if (ntv2_response->length < 24) {
/* We MUST have more than 16 bytes, or the stuff below will go
- crazy... */
+ crazy. No known implementation sends less than the 24 bytes
+ for LMv2, let alone NTLMv2. */
DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n",
- ntv2_response.length));
+ ntv2_response->length));
return False;
}
- client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16);
+ client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16);
/*
todo: should we be checking this for anything? We can't for LMv2,
but for NTLMv2 it is meant to contain the current time etc.
*/
- memcpy(client_response, ntv2_response.data, sizeof(client_response));
+ memcpy(client_response, ntv2_response->data, sizeof(client_response));
if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
return False;
}
- SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption);
+ SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
if (user_sess_key != NULL)
{
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
}
#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |"));
+ DEBUG(100,("Part password (P16) was |\n"));
dump_data(100, part_passwd, 16);
- DEBUG(100,("Password from client was |"));
- dump_data(100, ntv2_response.data, ntv2_response.length);
- DEBUG(100,("Variable data from client was |"));
+ DEBUGADD(100,("Password from client was |\n"));
+ dump_data(100, ntv2_response->data, ntv2_response->length);
+ DEBUGADD(100,("Variable data from client was |\n"));
dump_data(100, client_key_data.data, client_key_data.length);
- DEBUG(100,("Given challenge was |"));
- dump_data(100, sec_blob.data, sec_blob.length);
- DEBUG(100,("Value from encryption was |"));
+ DEBUGADD(100,("Given challenge was |\n"));
+ dump_data(100, sec_blob->data, sec_blob->length);
+ DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, value_from_encryption, 16);
#endif
data_blob_clear_free(&client_key_data);
@@ -185,8 +186,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
use it (ie. does it exist in the smbpasswd file).
*/
DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", user_info->client_domain.str));
- if (smb_pwd_check_ntlmv2( user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
user_info->client_domain.str,
user_sess_key))
@@ -195,11 +196,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
"",
user_sess_key))
+
{
return NT_STATUS_OK;
} else {
@@ -213,8 +215,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
use it (ie. does it exist in the smbpasswd file).
*/
DEBUG(4,("sam_password_ok: Checking NT MD4 password\n"));
- if (smb_pwd_check_ntlmv1(user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -224,7 +226,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
} else {
DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));
- /* no return, because we might pick up LMv2 in the LM field */
+ /* no return, becouse we might pick up LMv2 in the LM field */
}
}
@@ -242,8 +244,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
lm_pw = pdb_get_lanman_passwd(sampass);
DEBUG(4,("sam_password_ok: Checking LM password\n"));
- if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- lm_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->lm_resp,
+ lm_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -261,8 +263,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
- related to Win9X, legacy NAS pass-though authentication
*/
DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", user_info->client_domain.str));
- if (smb_pwd_check_ntlmv2( user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
user_info->client_domain.str,
user_sess_key))
@@ -271,8 +273,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
"",
user_sess_key))
@@ -286,8 +288,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n"));
if (lp_ntlm_auth())
{
- if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -438,14 +440,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
return NT_STATUS_NO_SUCH_USER;
}
- nt_status = sam_account_ok(mem_ctx, sampass, user_info);
+ nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
return nt_status;
}
- nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
+ nt_status = sam_account_ok(mem_ctx, sampass, user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
@@ -468,7 +470,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -509,7 +511,7 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context
}
/* module initialisation */
-NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -535,11 +537,11 @@ static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_cont
return NT_STATUS_LOGON_FAILURE;
}
- /* If we are a domain member, we must not
- attempt to check the password locally,
+ /* If we are a PDC we must not check the password here
unless it is one of our aliases, empty
- or our domain if we are a logon server.*/
-
+ or equal to our domain name. Other names may be
+ Trusted domains.
+ */
if ((!is_myworkgroup(user_info->domain.str))&&
(!is_myname(user_info->domain.str))) {
@@ -552,7 +554,7 @@ static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_cont
}
/* module initialisation */
-NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index 73af290af2a..2a1e4a48d98 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -372,12 +372,19 @@ use this machine as the password server.\n"));
cli_ulogoff(cli);
- if NT_STATUS_IS_OK(nt_status) {
+ if (NT_STATUS_IS_OK(nt_status)) {
struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
if (pass) {
nt_status = make_server_info_pw(server_info, pass);
} else {
- nt_status = NT_STATUS_NO_SUCH_USER;
+ auth_add_user_script(user_info->domain.str, user_info->internal_username.str);
+ pass = Get_Pwnam(user_info->internal_username.str);
+
+ if (pass) {
+ nt_status = make_server_info_pw(server_info, pass);
+ } else {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ }
}
}
@@ -388,7 +395,7 @@ use this machine as the password server.\n"));
return(nt_status);
}
-NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/auth/auth_unix.c b/source/auth/auth_unix.c
index 392178f77c1..b9de6f7acbd 100644
--- a/source/auth/auth_unix.c
+++ b/source/auth/auth_unix.c
@@ -119,7 +119,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index e8f2af41f32..d57619942c4 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -36,7 +36,7 @@ extern DOM_SID global_sid_Authenticated_Users;
Create a UNIX user on demand.
****************************************************************************/
-static int smb_create_user(const char *unix_user, const char *homedir)
+static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
{
pstring add_script;
int ret;
@@ -44,7 +44,9 @@ static int smb_create_user(const char *unix_user, const char *homedir)
pstrcpy(add_script, lp_adduser_script());
if (! *add_script)
return -1;
- all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
+ all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
+ if (domain)
+ all_string_sub(add_script, "%D", domain, sizeof(pstring));
if (homedir)
all_string_sub(add_script, "%H", homedir, sizeof(pstring));
ret = smbrun(add_script,NULL);
@@ -56,24 +58,18 @@ static int smb_create_user(const char *unix_user, const char *homedir)
Add and Delete UNIX users on demand, based on NTSTATUS codes.
****************************************************************************/
-void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status)
+void auth_add_user_script(const char *domain, const char *username)
{
struct passwd *pwd=NULL;
- if (NT_STATUS_IS_OK(nt_status)) {
-
- if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
-
- /*
- * User validated ok against Domain controller.
- * If the admin wants us to try and create a UNIX
- * user on the fly, do so.
- */
-
- if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
- smb_create_user(user_info->internal_username.str, NULL);
- }
- }
+ /*
+ * User validated ok against Domain controller.
+ * If the admin wants us to try and create a UNIX
+ * user on the fly, do so.
+ */
+
+ if(lp_adduser_script() && !(pwd = Get_Pwnam(username))) {
+ smb_create_user(domain, username, NULL);
}
}
@@ -914,30 +910,38 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
nt_status = pdb_init_sam_pw(&sam_account, passwd);
passwd_free(&passwd);
} else {
- char *dom_user;
- dom_user = talloc_asprintf(mem_ctx, "%s%s%s",
- nt_domain,
- lp_winbind_separator(),
- internal_username);
-
- if (!dom_user) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
- } else {
-
- if (!(passwd = Get_Pwnam(dom_user))
- /* Only lookup local for the local
- domain, we don't want this for
- trusted domains */
- && strequal(nt_domain, lp_workgroup())) {
- passwd = Get_Pwnam(internal_username);
+ int try = 0;
+ while (try < 2) {
+ char *dom_user;
+ dom_user = talloc_asprintf(mem_ctx, "%s%s%s",
+ nt_domain,
+ lp_winbind_separator(),
+ internal_username);
+
+ if (!dom_user) {
+ DEBUG(0, ("talloc_asprintf failed!\n"));
+ nt_status = NT_STATUS_NO_MEMORY;
+ } else {
+
+ if (!(passwd = Get_Pwnam(dom_user))
+ /* Only lookup local for the local
+ domain, we don't want this for
+ trusted domains */
+ && strequal(nt_domain, lp_workgroup())) {
+ passwd = Get_Pwnam(internal_username);
+ }
+
+ if (!passwd) {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ } else {
+ nt_status = pdb_init_sam_pw(&sam_account, passwd);
+ break;
+ }
}
-
- if (!passwd) {
- return NT_STATUS_NO_SUCH_USER;
- } else {
- nt_status = pdb_init_sam_pw(&sam_account, passwd);
+ if (try == 0) {
+ auth_add_user_script(nt_domain, internal_username);
}
+ try++;
}
}
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
index b8276b08661..0b19746597d 100644
--- a/source/auth/auth_winbind.c
+++ b/source/auth/auth_winbind.c
@@ -136,7 +136,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/change-log b/source/change-log
index 71f5012484f..1f7798b541f 100644
--- a/source/change-log
+++ b/source/change-log
@@ -2,7 +2,7 @@ SUPERCEDED Change Log for Samba
^^^^^^^^^^
Unless otherwise attributed, all changes were made by
-Andrew.Tridgell@anu.edu.au.
+Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.org.
NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER
diff --git a/source/client/client.c b/source/client/client.c
index 918b435b2d1..69037ca1db8 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -2328,11 +2328,9 @@ static char **completion_fn(const char *text, int start, int end)
if (sp == NULL)
return NULL;
- for (i = 0; commands[i].description; i++) {
+ for (i = 0; commands[i].description; i++)
if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0))
break;
- }
-
if (commands[i].name == NULL)
return NULL;
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 8ba1eff02e3..6edb06aedfb 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -222,6 +222,7 @@ char * parse_server(char * unc_name)
printf(" %s does not begin with \\\\ or //\n",unc_name);
return 0;
} else {
+ unc_name[0] = '\\';
unc_name[0] = '/';
unc_name[1] = '/';
unc_name += 2;
diff --git a/source/config.sub b/source/config.sub
index 04baf3d80d1..2476310dff3 100755
--- a/source/config.sub
+++ b/source/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
-timestamp='2003-01-03'
+timestamp='2001-12-03'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -118,7 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -227,39 +227,26 @@ case $basic_machine in
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
- | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
+ | c4x | clipper \
+ | d10v | d30v | dsp16xx \
+ | fr30 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
- | ip2k \
| m32r | m68000 | m68k | m88k | mcore \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
+ | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+ | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+ | mipsisa32 \
| mn10200 | mn10300 \
- | msp430 \
| ns16k | ns32k \
- | openrisc | or32 \
+ | openrisc \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | sh | sh[34] | sh[34]eb | shbe | shle \
+ | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
@@ -291,52 +278,38 @@ case $basic_machine in
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | alphapca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armv*-* \
| avr-* \
| bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
- | clipper-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
+ | c[123]* | c30-* | [cjt]90-* | c54x-* \
+ | clipper-* | cray2-* | cydra-* \
+ | d10v-* | d30v-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | f30[01]-* | f700-* | fr30-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* \
| m32r-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | msp430-* \
- | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
+ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
+ | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
@@ -402,10 +375,6 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -426,8 +395,16 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
- cray | j90)
- basic_machine=j90-cray
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [cjt]90)
+ basic_machine=${basic_machine}-cray
os=-unicos
;;
crds | unos)
@@ -442,14 +419,6 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -630,6 +599,14 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -644,10 +621,6 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -720,10 +693,6 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
- nv1)
- basic_machine=nv1-cray
- os=-unicosmp
- ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -731,10 +700,6 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
- or32 | or32-*)
- basic_machine=or32-unknown
- os=-coff
- ;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -757,13 +722,13 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
- pc532 | pc532-*)
+ pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ pentiumpro | p6 | 6x86 | athlon)
basic_machine=i686-pc
;;
pentiumii | pentium2)
@@ -784,22 +749,22 @@ case $basic_machine in
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
- ;;
+ ;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
- ;;
+ ;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
- ;;
+ ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
- ;;
+ ;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
@@ -830,12 +795,6 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
sequent)
basic_machine=i386-sequent
;;
@@ -910,17 +869,9 @@ case $basic_machine in
os=-dynix
;;
t3e)
- basic_machine=alphaev5-cray
+ basic_machine=t3e-cray
os=-unicos
;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic4x | c4x*)
- basic_machine=tic4x-unknown
- os=-coff
- ;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
@@ -931,10 +882,6 @@ case $basic_machine in
tx39el)
basic_machine=mipstx39el-unknown
;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -959,8 +906,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -981,13 +928,17 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
- xps | xps100)
- basic_machine=xps100-honeywell
+ windows32)
+ basic_machine=i386-pc
+ os=-windows32-msvcrt
;;
- ymp)
- basic_machine=ymp-cray
+ xmp)
+ basic_machine=xmp-cray
os=-unicos
;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -1008,6 +959,13 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
romp)
basic_machine=romp-ibm
;;
@@ -1027,16 +985,13 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
+ sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
- sh64)
- basic_machine=sh64-unknown
- ;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
- cydra)
+ cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1051,6 +1006,10 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1113,12 +1072,10 @@ case $os in
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -microbsd*)
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1130,10 +1087,8 @@ case $os in
;;
esac
;;
- -nto-qnx*)
- ;;
-nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -1181,11 +1136,8 @@ case $os in
-ctix* | -uts*)
os=-sysv
;;
- -nova*)
- os=-rtmk-nova
- ;;
-ns2 )
- os=-nextstep2
+ os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1224,8 +1176,8 @@ case $os in
-xenix)
os=-xenix
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
;;
-none)
;;
@@ -1258,11 +1210,10 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- # This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
- pdp11-*)
+ pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1289,9 +1240,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
- or32-*)
- os=-coff
- ;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1355,19 +1303,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
- *-gould)
+ *-gould)
os=-sysv
;;
- *-highlevel)
+ *-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
- *-sgi)
+ *-sgi)
os=-irix
;;
- *-siemens)
+ *-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1439,7 +1387,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
- -vxsim* | -vxworks* | -windiss*)
+ -vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
diff --git a/source/configure.in b/source/configure.in
index 93cbb0a871b..64051381856 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -154,6 +154,7 @@ AC_SUBST(AUTHLIBS)
AC_SUBST(ACLLIBS)
AC_SUBST(ADSLIBS)
AC_SUBST(PASSDBLIBS)
+AC_SUBST(IDMAP_LIBS)
AC_SUBST(KRB5_LIBS)
AC_SUBST(LDAP_LIBS)
AC_SUBST(LDAP_OBJ)
@@ -171,11 +172,13 @@ AC_ARG_ENABLE(debug,
AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
[if eval "test x$enable_developer = xyes"; then
- CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ developer=yes
+ CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
fi])
AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
[if eval "test x$enable_krb5developer = xyes"; then
+ developer=yes
CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
fi])
@@ -221,6 +224,30 @@ else
fi
AC_SUBST(BROKEN_CC)
+dnl Check if the C compiler understands -Werror
+AC_CACHE_CHECK([that the C compiler understands -Werror],samba_cv_HAVE_Werror, [
+ AC_TRY_RUN_STRICT([
+ int main(void)
+ {
+ return 0;
+ }],[-Werror],[$CPPFLAGS],[$LDFLAGS],
+ samba_cv_HAVE_Werror=yes,samba_cv_HAVE_Werror=no,samba_cv_HAVE_Werror=cross)])
+if test x"$samba_cv_HAVE_Werror" = x"yes"; then
+ Werror_FLAGS="-Werror"
+else
+dnl Check if the C compiler understands -w2
+AC_CACHE_CHECK([that the C compiler understands -w2],samba_cv_HAVE_w2, [
+ AC_TRY_RUN_STRICT([
+ int main(void)
+ {
+ return 0;
+ }],[-w2],[$CPPFLAGS],[$LDFLAGS],
+ samba_cv_HAVE_w2=yes,samba_cv_HAVE_w2=no,samba_cv_HAVE_w2=cross)])
+if test x"$samba_cv_HAVE_w2" = x"yes"; then
+ Werror_FLAGS="-w2"
+fi
+fi
+
dnl Check if the C compiler understands volatile (it should, being ANSI).
AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [
AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0],
@@ -229,6 +256,21 @@ if test x"$samba_cv_volatile" = x"yes"; then
AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile])
fi
+UNAME_S=`uname -s`
+AC_MSG_CHECKING(uname -s)
+AC_MSG_RESULT(${UNAME_S})
+
+UNAME_R=`uname -r`
+AC_MSG_CHECKING(uname -r)
+AC_MSG_RESULT(${UNAME_R})
+
+UNAME_M=`uname -m`
+AC_MSG_CHECKING(uname -m)
+AC_MSG_RESULT(${UNAME_M})
+
+UNAME_P=`uname -p`
+AC_MSG_CHECKING(uname -p)
+AC_MSG_RESULT(${UNAME_P})
AC_CANONICAL_SYSTEM
@@ -247,9 +289,9 @@ dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin idmap_winbind"
dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms"
-if test "x$enable_developer" = xyes; then
+if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_echo"
default_shared_modules="$default_shared_modules charset_weird"
fi
@@ -509,18 +551,11 @@ AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/
AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
+AC_CHECK_HEADERS(sys/acl.h attr/xattr.h sys/cdefs.h glob.h)
# For experimental utmp support (lastlog on some BSD-like systems)
AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h)
-# For quotas on Veritas VxFS filesystems
-AC_CHECK_HEADERS(sys/fs/vx_quota.h)
-
-# For quotas on Linux XFS filesystems
-AC_CHECK_HEADERS(linux/xqm.h)
-AC_CHECK_HEADERS(xfs/xqm.h)
-
AC_CHECK_SIZEOF(int,cross)
AC_CHECK_SIZEOF(long,cross)
AC_CHECK_SIZEOF(short,cross)
@@ -903,6 +938,13 @@ AC_LIBTESTFUNC(sec, bigcrypt)
AC_LIBTESTFUNC(security, getprpwnam)
AC_LIBTESTFUNC(sec, getprpwnam)
+############################################
+# Check if we have libattr
+AC_SEARCH_LIBS(getxattr, [attr])
+AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
+AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
+AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
+
# Assume non-shared by default and override below
BLDSHARED="false"
@@ -2173,6 +2215,7 @@ fi
AC_CHECK_LIB(crypto, des_set_key, [LIBS="$LIBS -lcrypto"])
AC_CHECK_LIB(asn1, copy_Authenticator, [LIBS="$LIBS -lasn1"])
AC_CHECK_LIB(roken, roken_getaddrinfo_hostspec, [LIBS="$LIBS -lroken"])
+ AC_CHECK_LIB(resolv, dn_expand, [LIBS="$LIBS -lresolv"])
# Heimdal checks. On static Heimdal gssapi must be linked before krb5.
AC_CHECK_LIB(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi -lkrb5";
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
@@ -2266,8 +2309,8 @@ AC_ARG_WITH(ldap,
AC_MSG_RESULT($with_ldap_support)
if test x"$with_ldap_support" = x"yes"; then
-ac_save_LIBS="$LIBS"
-LIBS=""
+ ac_save_LIBS="$LIBS"
+ LIBS=""
##################################################################
# we might need the lber lib on some systems. To avoid link errors
@@ -2277,10 +2320,17 @@ LIBS=""
########################################################
# now see if we can find the ldap libs in standard paths
if test x$have_ldap != xyes; then
- AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap";
- LDAP_OBJ=lib/ldap.o;
- AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])])
- AC_CHECK_HEADERS([ldap.h lber.h], [default_static_modules="$default_static_modules pdb_ldap"])
+ AC_CHECK_LIB(ldap, ldap_init, [
+ LIBS="$LIBS -lldap";
+ AC_CHECK_LIB(ldap, ldap_domain2hostlist, [
+ AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
+ AC_CHECK_HEADERS([ldap.h lber.h],
+ [default_static_modules="$default_static_modules pdb_ldap idmap_ldap"])
+ ])
+ ])
+
+ ## we have ldap so build the list of files for the generic samba ldap library
+ SMBLDAP="lib/smbldap.o"
########################################################
# If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
@@ -2291,10 +2341,12 @@ LIBS=""
#include <lber.h>
#include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [pam_ldap_cv_ldap_set_rebind_proc=3], [pam_ldap_cv_ldap_set_rebind_proc=2]) ])
AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $pam_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
+ AC_CHECK_FUNCS(ldap_initialize)
fi
-LDAP_LIBS="$LIBS";
-LIBS="$ac_save_LIBS";
+ AC_SUBST(SMBLDAP)
+ LDAP_LIBS="$LIBS";
+ LIBS="$ac_save_LIBS";
else
# Can't have ADS support without LDAP
if test x"$with_ads_support" = x"yes"; then
@@ -2485,27 +2537,6 @@ AC_ARG_WITH(ldapsam,
AC_MSG_RESULT(no)
)
-#################################################
-# check for IDMAP
-
-AC_DEFINE(WITH_IDMAP,1, [Include IDMAP support])
-
-AC_MSG_CHECKING(whether to use IDMAP only for [ug]id mapping)
-AC_ARG_WITH(idmap,
-[ --with-idmap Include experimental IDMAP support (default=yes)],
-[ case "$withval" in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_IDMAP,1,[Whether to include experimental IDMAP support])
- ;;
- no)
- AC_MSG_RESULT(no)
- AC_DEFINE(WITH_IDMAP,0,[Whether to include experimental IDMAP support])
- ;;
- esac ],
- AC_MSG_RESULT(yes)
-)
-
########################################################################################
##
## END OF TESTS FOR SAM BACKENDS.
@@ -2566,44 +2597,283 @@ AC_ARG_WITH(profiling-data,
#################################################
# check for experimental disk-quotas support
-QUOTAOBJS=smbd/noquotas.o
-AC_MSG_CHECKING(whether to support disk-quotas)
+samba_cv_WITH_QUOTAS=auto
+samba_cv_TRY_QUOTAS=no
+samba_cv_RUN_QUOTA_TESTS=auto
+samba_cv_WITH_SYS_QUOTAS=auto
+samba_cv_TRY_SYS_QUOTAS=no
+
+AC_MSG_CHECKING(whether to try disk-quotas support)
AC_ARG_WITH(quotas,
-[ --with-quotas Include experimental disk-quota support (default=no)],
+[ --with-quotas Include disk-quota support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- case "$host_os" in
- *linux*)
- # Check for kernel 2.4.x quota braindamage...
- AC_CACHE_CHECK([for linux 2.4.x quota braindamage..],samba_cv_linux_2_4_quota_braindamage, [
- AC_TRY_COMPILE([#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <linux/quota.h>
-#include <mntent.h>
-#include <linux/unistd.h>],[struct mem_dqblk D;],
- samba_cv_linux_2_4_quota_braindamage=yes,samba_cv_linux_2_4_quota_braindamage=no)])
-if test x"$samba_cv_linux_2_4_quota_braindamage" = x"yes"; then
- AC_DEFINE(LINUX_QUOTAS_2,1,[linux 2.4.x quota braindamage])
-else
- AC_DEFINE(LINUX_QUOTAS_1,1,[linux quotas])
-fi
- ;;
- *)
- ;;
- esac
- QUOTAOBJS=smbd/quotas.o
- AC_DEFINE(WITH_QUOTAS,1,[Whether to include experimental quota support])
+ samba_cv_WITH_QUOTAS=yes
+ samba_cv_TRY_QUOTAS=yes
+ samba_cv_RUN_QUOTA_TESTS=yes
+ #set sys quotas to auto in this case
+ samba_cv_TRY_SYS_QUOTAS=auto
+ ;;
+ auto)
+ AC_MSG_RESULT(auto)
+ samba_cv_WITH_QUOTAS=auto
+ samba_cv_TRY_QUOTAS=auto
+ samba_cv_RUN_QUOTA_TESTS=auto
+ #set sys quotas to auto in this case
+ samba_cv_TRY_SYS_QUOTAS=auto
+ ;;
+ no)
+ AC_MSG_RESULT(no)
+ samba_cv_WITH_QUOTAS=no
+ samba_cv_TRY_QUOTAS=no
+ samba_cv_RUN_QUOTA_TESTS=no
;;
*)
+ AC_MSG_RESULT(${samba_cv_TRY_QUOTAS})
+ ;;
+ esac ],
+ AC_MSG_RESULT(${samba_cv_TRY_QUOTAS})
+)
+
+AC_MSG_CHECKING(whether to try the new lib/sysquotas.c interface)
+AC_ARG_WITH(sys-quotas,
+[ --with-sys-quotas Include lib/sysquotas.c support (default=auto)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ samba_cv_WITH_SYS_QUOTAS=yes
+ samba_cv_TRY_SYS_QUOTAS=yes
+ samba_cv_RUN_QUOTA_TESTS=yes
+ ;;
+ auto)
+ AC_MSG_RESULT(auto)
+ samba_cv_WITH_SYS_QUOTAS=auto
+ samba_cv_TRY_SYS_QUOTAS=auto
+ samba_cv_RUN_QUOTA_TESTS=auto
+ ;;
+ no)
AC_MSG_RESULT(no)
+ samba_cv_WITH_SYS_QUOTAS=no
+ samba_cv_TRY_SYS_QUOTAS=no
+ ;;
+ *)
+ AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS})
;;
esac ],
- AC_MSG_RESULT(no)
+ AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS})
)
-AC_SUBST(QUOTAOBJS)
+
+if test x"$samba_cv_TRY_SYS_QUOTAS" = x"auto"; then
+AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os})
+ case "$host_os" in
+ *linux*)
+ AC_MSG_RESULT(yes)
+ samba_cv_TRY_SYS_QUOTAS=yes
+ samba_cv_RUN_QUOTA_TESTS=yes
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ samba_cv_TRY_SYS_QUOTAS=no
+ ;;
+ esac
+fi
+
+#############################################
+# only check for quota stuff if --with-quotas
+if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then
+
+# For quotas on Veritas VxFS filesystems
+AC_CHECK_HEADERS(sys/fs/vx_quota.h)
+
+# For sys/quota.h and linux/quota.h
+AC_CHECK_HEADERS(sys/quota.h)
+AC_CHECK_HEADERS(asm/types.h linux/quota.h)
+
+# For quotas on Linux XFS filesystems
+AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h)
+AC_CHECK_HEADERS(xfs/libxfs.h xfs/xqm.h xfs/xfs_fs.h)
+# For linux > 2.5.56
+AC_CHECK_HEADERS(linux/dqblk_xfs.h)
+
+# if we have struct if_dqblk in <linux/quota.h> we should use it
+AC_CACHE_CHECK([for struct if_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_IF_DQBLK, [
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#include <linux/quota.h>
+],[struct if_dqblk D;],
+samba_cv_HAVE_STRUCT_IF_DQBLK=yes,samba_cv_HAVE_STRUCT_IF_DQBLK=no)])
+if test "$samba_cv_HAVE_STRUCT_IF_DQBLK"x = "yes"x; then
+ AC_DEFINE(HAVE_STRUCT_IF_DQBLK,1,[struct if_dqblk])
+fi
+
+# if we have struct mem_dqblk in <linux/quota.h> we should use it
+AC_CACHE_CHECK([for struct mem_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_MEM_DQBLK, [
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#include <linux/quota.h>
+],[struct mem_dqblk D;],
+samba_cv_HAVE_STRUCT_MEM_DQBLK=yes,samba_cv_HAVE_STRUCT_MEM_DQBLK=no)])
+if test "$samba_cv_HAVE_STRUCT_MEM_DQBLK"x = "yes"x; then
+ AC_DEFINE(HAVE_STRUCT_MEM_DQBLK,1,[struct mem_dqblk])
+fi
+
+# if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX
+AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#ifdef HAVE_SYS_QUOTA_H
+#include <sys/quota.h>
+#endif
+],[
+struct dqblk D;
+D.dqb_fsoftlimit = 0;],
+samba_cv_HAVE_DQB_FSOFTLIMIT=yes,samba_cv_HAVE_DQB_FSOFTLIMIT=no)])
+if test "$samba_cv_HAVE_DQB_FSOFTLIMIT"x = "yes"x; then
+ AC_DEFINE(HAVE_DQB_FSOFTLIMIT,1,[struct dqblk .dqb_fsoftlimit])
+fi
+
+##################
+# look for a working quota system
+samba_cv_SYSQUOTA_FOUND=no;
+
+if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
+AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[
+AC_TRY_RUN_STRICT([
+#define HAVE_QUOTACTL_4A 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
+ samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)])
+if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then
+ samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available])
+fi
+fi
+
+if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
+AC_CACHE_CHECK([for int quotactl(const char *path, int cmd, int id, char *addr)],samba_cv_HAVE_QUOTACTL_4B,[
+AC_TRY_RUN_STRICT([
+#define HAVE_QUOTACTL_4B 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
+ samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)])
+if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then
+ echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api"
+# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available])
+fi
+fi
+
+if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
+AC_CACHE_CHECK([for CRAY int quotactl (char *spec, int request, char *arg)],samba_cv_HAVE_QUOTACTL_3,[
+AC_TRY_RUN_STRICT([
+#define HAVE_QUOTACTL_3 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
+ samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)])
+if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then
+ echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api"
+# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available])
+fi
+fi
+
+#################################################
+# check for mntent.h and struct mntent
+AC_CHECK_HEADERS(mntent.h)
+#################################################
+# check for setmntent,getmntent,endmntent
+AC_CHECK_FUNCS(setmntent getmntent endmntent)
+
+#################################################
+# check for devnm.h and struct mntent
+AC_CHECK_HEADERS(devnm.h)
+#################################################
+# check for devnm
+AC_CHECK_FUNCS(devnm)
+
+if test x"$samba_cv_WITH_SYS_QUOTAS" = x"yes"; then
+ if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
+ # if --with-sys-quotas=yes then build it
+ # you have can use the get/set quota command smb.conf
+ # options then
+ samba_cv_SYSQUOTA_FOUND=auto
+ fi
+ if test x"$samba_cv_TRY_SYS_QUOTAS" != x"yes"; then
+ # if --with-sys-quotas=yes then build it
+ # you have can use the get/set quota command smb.conf
+ # options then
+ samba_cv_TRY_SYS_QUOTAS=auto
+ fi
+fi
+
+if test x"$samba_cv_SYSQUOTA_FOUND" != x"no"; then
+AC_CACHE_CHECK([whether the sys_quota interface works],samba_cv_SYSQUOTA_WORKS,[
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#define NO_PROTO_H 1
+#define NO_CONFIG_H 1
+#define HAVE_SYS_QUOTAS 1
+#include "${srcdir-.}/lib/sysquotas.c"
+],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no)
+CPPFLAGS="$SAVE_CPPFLAGS"
+])
+if test x"$samba_cv_SYSQUOTA_WORKS" = x"yes"; then
+AC_MSG_CHECKING(whether to use the new lib/sysquotas.c interface)
+ if test x"$samba_cv_TRY_SYS_QUOTAS" != x"no"; then
+ AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support])
+ AC_DEFINE(HAVE_SYS_QUOTAS,1,[Whether the new lib/sysquotas.c interface can be used])
+ samba_cv_WE_USE_SYS_QUOTAS=yes
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+fi
+
+AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#define NO_PROTO_H 1
+#define NO_CONFIG_H 1
+#include "${srcdir-.}/smbd/quotas.c"
+],[],samba_cv_QUOTA_WORKS=yes,samba_cv_QUOTA_WORKS=no)
+CPPFLAGS="$SAVE_CPPFLAGS"
+])
+if test x"$samba_cv_QUOTA_WORKS" = x"yes"; then
+AC_MSG_CHECKING(whether to use the old quota support)
+ if test x"$samba_cv_WE_USE_SYS_QUOTAS" != x"yes"; then
+ if test x"$samba_cv_TRY_QUOTAS" != x"no"; then
+ AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support])
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+####################
+# End of quota check samba_cv_RUN_QUOTA_TESTS
+fi
#################################################
# check for experimental utmp accounting
@@ -2966,7 +3236,34 @@ AC_ARG_WITH(acl-support,
AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether FreeBSD POSIX ACLs are available])
AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
;;
- *)
+ *linux*)
+ AC_CHECK_LIB(attr,getxattr,[ACLLIBS="$ACLLIBS -lattr"])
+ AC_CHECK_LIB(acl,acl_get_file,[ACLLIBS="$ACLLIBS -lacl"])
+ AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
+ acl_LIBS=$LIBS
+ LIBS="$LIBS -lacl"
+ AC_TRY_LINK([#include <sys/types.h>
+#include <sys/acl.h>],
+[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);],
+samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)
+ LIBS=$acl_LIBS])
+ if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
+ AC_MSG_RESULT(Using posix ACLs)
+ AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
+ AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[
+ acl_LIBS=$LIBS
+ LIBS="$LIBS -lacl"
+ AC_TRY_LINK([#include <sys/types.h>
+#include <sys/acl.h>],
+[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);],
+samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)
+ LIBS=$acl_LIBS])
+ if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
+ AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
+ fi
+ fi
+ ;;
+ *)
AC_CHECK_LIB(acl,acl_get_file,[ACLLIBS="$ACLLIBS -lacl"])
AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
acl_LIBS=$LIBS
@@ -3316,7 +3613,7 @@ if test x"$HAVE_WINBIND" = x"yes"; then
EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)"
EXTRA_SBIN_PROGS="$EXTRA_SBIN_PROGS bin/winbindd\$(EXEEXT)"
if test x"$BLDSHARED" = x"true"; then
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/$WINBIND_NSS"
+ SHLIB_PROGS="$SHLIB_PROGS nsswitch/$WINBIND_NSS"
if test x"$with_pam" = x"yes"; then
SHLIB_PROGS="$SHLIB_PROGS nsswitch/pam_winbind.$SHLIBEXT"
@@ -3327,31 +3624,15 @@ else
fi
# Solaris has some extra fields in struct passwd that need to be
-# initialised otherwise nscd crashes. Unfortunately autoconf < 2.50
-# doesn't have the AC_CHECK_MEMBER macro which would be handy for checking
-# this.
-
-#AC_CHECK_MEMBER(struct passwd.pw_comment,
-# AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),
-# [#include <pwd.h>])
-
-AC_CACHE_CHECK([whether struct passwd has pw_comment],samba_cv_passwd_pw_comment, [
- AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_comment;],
- samba_cv_passwd_pw_comment=yes,samba_cv_passwd_pw_comment=no)])
-if test x"$samba_cv_passwd_pw_comment" = x"yes"; then
- AC_DEFINE(HAVE_PASSWD_PW_COMMENT,1,[Whether struct passwd has pw_comment])
-fi
-
-#AC_CHECK_MEMBER(struct passwd.pw_age,
-# AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),
-# [#include <pwd.h>])
+# initialised otherwise nscd crashes.
+
+AC_CHECK_MEMBER(struct passwd.pw_comment,
+ AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),,
+ [#include <pwd.h>])
-AC_CACHE_CHECK([whether struct passwd has pw_age],samba_cv_passwd_pw_age, [
- AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_age;],
- samba_cv_passwd_pw_age=yes,samba_cv_passwd_pw_age=no)])
-if test x"$samba_cv_passwd_pw_age" = x"yes"; then
- AC_DEFINE(HAVE_PASSWD_PW_AGE,1,[Whether struct passwd has pw_age])
-fi
+AC_CHECK_MEMBER(struct passwd.pw_age,
+ AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),,
+ [#include <pwd.h>])
#################################################
# Check to see if we should use the included popt
@@ -3435,6 +3716,7 @@ dnl Always built these modules static
MODULE_pdb_guest=STATIC
MODULE_rpc_spoolss=STATIC
MODULE_rpc_srv=STATIC
+MODULE_idmap_tdb=STATIC
AC_ARG_WITH(static-modules,
[ --with-static-modules=MODULES Comma-seperated list of names of modules to statically link in],
@@ -3484,7 +3766,12 @@ SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC)
-SMB_MODULE(charset_weird, modules/developer.o, "bin/weird.$SHLIBEXT", CHARSET)
+SMB_MODULE(idmap_winbind, sam/idmap_winbind.o, "bin/idmap_winbind.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP)
+SMB_SUBSYSTEM(IDMAP)
+
+SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
SMB_SUBSYSTEM(CHARSET)
SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH)
@@ -3499,8 +3786,8 @@ SMB_SUBSYSTEM(AUTH)
SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), "bin/recycle.$SHLIBEXT", VFS)
SMB_MODULE(vfs_audit, \$(VFS_AUDIT_OBJ), "bin/audit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_extd_audit, \$(VFS_EXTD_AUDIT_OBJ), "bin/extd_audit.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", VFS)
SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK_OBJ), "bin/netatalk.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
diff --git a/source/include/.cvsignore b/source/include/.cvsignore
index 4bff170b3bf..bff248727f2 100644
--- a/source/include/.cvsignore
+++ b/source/include/.cvsignore
@@ -3,5 +3,4 @@ config.h
stamp-h
proto.h
wrepld_proto.h
-tdbsam2_parse_info.h
config.h.in
diff --git a/source/include/idmap.h b/source/include/idmap.h
index 1e56519453a..4b38128c2f2 100644
--- a/source/include/idmap.h
+++ b/source/include/idmap.h
@@ -22,6 +22,9 @@
Boston, MA 02111-1307, USA.
*/
+#define SMB_IDMAP_INTERFACE_VERSION 1
+
+
#define ID_EMPTY 0x00
#define ID_USERID 0x01
#define ID_GROUPID 0x02
@@ -32,16 +35,11 @@
#define ID_NOMAP 0x10
#define ID_CACHE 0x20
-typedef union unid_t {
- uid_t uid;
- gid_t gid;
-} unid_t;
-
/* Filled out by IDMAP backends */
struct idmap_methods {
/* Called when backend is first loaded */
- NTSTATUS (*init)(void);
+ NTSTATUS (*init)( char *params );
NTSTATUS (*get_sid_from_id)(DOM_SID *sid, unid_t id, int id_type);
NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, const DOM_SID *sid);
diff --git a/source/include/includes.h b/source/include/includes.h
index 534bbfbf26c..7b4c8dbdff5 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -437,6 +437,10 @@
#include <com_err.h>
#endif
+#if HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
/* Special macros that are no-ops except when run under Valgrind on
* x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
#if HAVE_VALGRIND_MEMCHECK_H
@@ -769,9 +773,6 @@ extern int errno;
#include "version.h"
#include "smb.h"
-/*
-#include "smbw.h"
-*/
#include "nameserv.h"
@@ -808,14 +809,12 @@ extern int errno;
#include "auth.h"
-#include "sam.h"
-
-#include "gums.h"
-
#include "idmap.h"
#include "client.h"
+
#include "smbw.h"
+
#include "session.h"
#include "asn_1.h"
@@ -828,8 +827,6 @@ extern int errno;
#include "nsswitch/winbind_client.h"
-#include "genparser.h"
-
/*
* Type for wide character dirent structure.
* Only d_name is defined by POSIX.
@@ -876,6 +873,10 @@ struct printjob;
struct smb_ldap_privates;
+/* forward declarations from smbldap.c */
+
+#include "smbldap.h"
+
/***** automatically generated prototypes *****/
#ifndef NO_PROTO_H
#include "proto.h"
@@ -1283,7 +1284,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
-BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]);
+BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]);
#endif /* HAVE_KRB5 */
/* TRUE and FALSE are part of the C99 standard and gcc, but
diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h
index 4749842ddc5..17791fde18f 100644
--- a/source/include/ntioctl.h
+++ b/source/include/ntioctl.h
@@ -23,4 +23,46 @@
we only need the sparse flag
*/
-#define NTIOCTL_SET_SPARSE 0x900c4
+
+/* IOCTL information */
+/* List of ioctl function codes that look to be of interest to remote clients like this. */
+/* Need to do some experimentation to make sure they all work remotely. */
+/* Some of the following such as the encryption/compression ones would be */
+/* invoked from tools via a specialized hook into the VFS rather than via the */
+/* standard vfs entry points */
+#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000
+#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004
+#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008
+#define FSCTL_LOCK_VOLUME 0x00090018
+#define FSCTL_UNLOCK_VOLUME 0x0009001C
+#define FSCTL_GET_COMPRESSION 0x0009003C
+#define FSCTL_SET_COMPRESSION 0x0009C040
+#define FSCTL_REQUEST_FILTER_OPLOCK 0x0009008C
+#define FSCTL_FIND_FILES_BY_SID 0x0009008F
+#define FSCTL_FILESYS_GET_STATISTICS 0x00090090
+#define FSCTL_SET_REPARSE_POINT 0x000900A4
+#define FSCTL_GET_REPARSE_POINT 0x000900A8
+#define FSCTL_DELETE_REPARSE_POINT 0x000900AC
+#define FSCTL_0x000900C0 0x000900C0
+#define FSCTL_SET_SPARSE 0x000900C4
+#define FSCTL_SET_ZERO_DATA 0x000900C8
+#define FSCTL_SET_ENCRYPTION 0x000900D7
+#define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB
+#define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF
+#define FSCTL_READ_RAW_ENCRYPTED 0x000900E3
+#define FSCTL_SIS_COPYFILE 0x00090100
+#define FSCTL_SIS_LINK_FILES 0x0009C104
+
+#if 0
+#define FSCTL_SECURITY_ID_CHECK
+#define FSCTL_DISMOUNT_VOLUME
+#define FSCTL_GET_NTFS_FILE_RECORD
+#define FSCTL_ALLOW_EXTENDED_DASD_IO
+#define FSCTL_RECALL_FILE
+#define FSCTL_QUERY_ALLOCATED_RANGES
+
+#endif
+
+#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
+#define IO_REPARSE_TAG_HSM 0xC0000004
+#define IO_REPARSE_TAG_SIS 0x80000007
diff --git a/source/include/ntlmssp.h b/source/include/ntlmssp.h
index cfbbb00381a..067b2a58800 100644
--- a/source/include/ntlmssp.h
+++ b/source/include/ntlmssp.h
@@ -64,8 +64,8 @@ enum NTLM_MESSAGE_TYPE
#define NTLMSSP_NAME_TYPE_SERVER 0x01
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
-#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x03
-#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x04
+#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03
+#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04
typedef struct ntlmssp_state
{
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index d4136a9fde1..135fd76d6c9 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -237,7 +237,7 @@ typedef struct r_lsa_query_sec_obj_info
typedef struct lsa_query_info
{
POLICY_HND pol; /* policy handle */
- uint16 info_class; /* info class */
+ uint16 info_class; /* info class */
} LSA_Q_QUERY_INFO;
@@ -537,6 +537,7 @@ typedef struct
POLICY_HND pol; /* policy handle */
DOM_SID2 sid;
UNISTR2_ARRAY rights;
+ uint32 count;
} LSA_Q_ADD_ACCT_RIGHTS;
/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */
@@ -553,6 +554,7 @@ typedef struct
DOM_SID2 sid;
uint32 removeall;
UNISTR2_ARRAY rights;
+ uint32 count;
} LSA_Q_REMOVE_ACCT_RIGHTS;
/* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */
@@ -561,22 +563,6 @@ typedef struct
NTSTATUS status;
} LSA_R_REMOVE_ACCT_RIGHTS;
-/* LSA_Q_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */
-typedef struct
-{
- POLICY_HND pol;
- STRHDR right_hdr;
- UNISTR2 right;
-} LSA_Q_ENUM_ACCT_WITH_RIGHT;
-
-/* LSA_R_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */
-typedef struct
-{
- uint32 count;
- SID_ARRAY sids;
- NTSTATUS status;
-} LSA_R_ENUM_ACCT_WITH_RIGHT;
-
/* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */
typedef struct lsa_q_priv_get_dispname
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index 1bb25e86511..fb7060cde3b 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -78,7 +78,8 @@
#define SEC_DESC_DACL_DEFAULTED 0x0008
#define SEC_DESC_SACL_PRESENT 0x0010
#define SEC_DESC_SACL_DEFAULTED 0x0020
-#define SEC_DESC_SELF_RELATIVE 0x8000
+#define SEC_DESC_DACL_TRUSTED 0x0040
+#define SEC_DESC_SERVER_SECURITY 0x0080
/*
* New Windows 2000 bits.
*/
@@ -89,14 +90,28 @@
#define SE_DESC_DACL_PROTECTED 0x1000
#define SE_DESC_SACL_PROTECTED 0x2000
+/* Don't know what this means. */
+#define SEC_DESC_RM_CONTROL_VALID 0x4000
+
+#define SEC_DESC_SELF_RELATIVE 0x8000
+
/* security information */
#define OWNER_SECURITY_INFORMATION 0x00000001
#define GROUP_SECURITY_INFORMATION 0x00000002
#define DACL_SECURITY_INFORMATION 0x00000004
#define SACL_SECURITY_INFORMATION 0x00000008
+/* Extra W2K flags. */
+#define UNPROTECTED_SACL_SECURITY_INFORMATION 0x10000000
+#define UNPROTECTED_DACL_SECURITY_INFORMATION 0x20000000
+#define PROTECTED_SACL_SECURITY_INFORMATION 0x40000000
+#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000
#define ALL_SECURITY_INFORMATION (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|\
- DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION)
+ DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION|\
+ UNPROTECTED_SACL_SECURITY_INFORMATION|\
+ UNPROTECTED_DACL_SECURITY_INFORMATION|\
+ PROTECTED_SACL_SECURITY_INFORMATION|\
+ PROTECTED_DACL_SECURITY_INFORMATION)
/* Globally Unique ID */
#define GUID_SIZE 16
diff --git a/source/include/safe_string.h b/source/include/safe_string.h
index a6b352b02e8..df3633d91d9 100644
--- a/source/include/safe_string.h
+++ b/source/include/safe_string.h
@@ -113,24 +113,24 @@ size_t __unsafe_string_function_usage_here_char__(void);
#endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
-/* the addition of the DEVELOPER checks in safe_strcpy means we must
- * update a lot of code. To make this a little easier here are some
- * functions that provide the lengths with less pain */
-#define pstrcpy_base(dest, src, pstring_base) \
- safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
-
#define safe_strcpy_base(dest, src, base, size) \
safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
-/* String copy functions - macro hell below adds 'type checking'
- (limited, but the best we can do in C) and may tag with function
- name/number to record the last 'clobber region' on that string */
+/* String copy functions - macro hell below adds 'type checking' (limited,
+ but the best we can do in C) and may tag with function name/number to
+ record the last 'clobber region' on that string */
#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1)
#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
+/* the addition of the DEVELOPER checks in safe_strcpy means we must
+ * update a lot of code. To make this a little easier here are some
+ * functions that provide the lengths with less pain */
+#define pstrcpy_base(dest, src, pstring_base) \
+ safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
+
/* Inside the _fn variants of these is a call to clobber_region(), -
* which might destroy the stack on a buggy function. We help the
diff --git a/source/include/smb.h b/source/include/smb.h
index 0889abf0385..27c966914fb 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -66,6 +66,7 @@ typedef int BOOL;
#define STR_ASCII 4
#define STR_UNICODE 8
#define STR_NOALIGN 16
+#define STR_TERMINATE_ASCII 128
/* how long to wait for secondary SMB packets (milli-seconds) */
#define SMB_SECONDARY_WAIT (60*1000)
@@ -155,6 +156,11 @@ typedef int BOOL;
#include "doserr.h"
+typedef union unid_t {
+ uid_t uid;
+ gid_t gid;
+} unid_t;
+
/*
* SMB UCS2 (16-bit unicode) internal type.
*/
@@ -404,9 +410,11 @@ typedef struct files_struct
BOOL is_stat;
BOOL directory_delete_on_close;
char *fsp_name;
+ FAKE_FILE_HANDLE *fake_file_handle;
} files_struct;
#include "ntquotas.h"
+#include "sysquotas.h"
/* used to hold an arbitrary blob of data */
typedef struct data_blob {
@@ -442,18 +450,10 @@ typedef struct
#include "smb_acls.h"
#include "vfs.h"
-typedef struct smb_vfs_handle_struct
-{
- void *data;
- /* Handle on dlopen() call */
- void *handle;
- struct smb_vfs_handle_struct *next, *prev;
-
-} smb_vfs_handle_struct;
-
typedef struct connection_struct
{
struct connection_struct *next, *prev;
+ TALLOC_CTX *mem_ctx;
unsigned cnum; /* an index passed over the wire */
int service;
BOOL force_user;
@@ -468,8 +468,9 @@ typedef struct connection_struct
char *connectpath;
char *origpath;
- struct vfs_ops vfs_ops; /* Filesystem operations */
- struct smb_vfs_handle_struct *vfs_private;
+ struct vfs_ops vfs; /* Filesystem operations */
+ struct vfs_ops vfs_opaque; /* OPAQUE Filesystem operations */
+ struct vfs_handle_struct *vfs_handles; /* for the new plugins */
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 8e2cb1c8185..aae3b46f7a4 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -77,12 +77,15 @@
#define OPEN_CONN(conn) ((conn) && (conn)->open)
#define IS_IPC(conn) ((conn) && (conn)->ipc)
#define IS_PRINT(conn) ((conn) && (conn)->printer)
-#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn)
+#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
-#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \
+#define CHECK_FSP(fsp,conn) do {\
+ extern struct current_user current_user;\
+ if (!FNUM_OK(fsp,conn)) \
return(ERROR_DOS(ERRDOS,ERRbadfid)); \
else if((fsp)->fd == -1) \
- return(ERROR_DOS(ERRDOS,ERRbadaccess))
+ return(ERROR_DOS(ERRDOS,ERRbadaccess));\
+ } while(0)
#define CHECK_READ(fsp) if (!(fsp)->can_read) \
return(ERROR_DOS(ERRDOS,ERRbadaccess))
@@ -244,52 +247,4 @@ copy an IP address from one buffer to another
#define dos_format(fname) string_replace(fname,'/','\\')
-/*******************************************************************
- vfs stat wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_stat(conn, fname, st) ((conn)->vfs_ops.stat((conn), fname,(st)))
-
-/*******************************************************************
- vfs lstat wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_lstat(conn, fname, st) ((conn)->vfs_ops.lstat((conn), fname,(st)))
-
-/*******************************************************************
- vfs fstat wrapper
-********************************************************************/
-
-#define vfs_fstat(fsp, fd, st) ((fsp)->conn->vfs_ops.fstat((fsp),(fd),(st)))
-
-/*******************************************************************
- vfs rmdir wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_rmdir(conn,fname) ((conn)->vfs_ops.rmdir((conn),fname))
-
-/*******************************************************************
- vfs Unlink wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_unlink(conn, fname) ((conn)->vfs_ops.unlink((conn),fname))
-
-/*******************************************************************
- vfs chmod wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_chmod(conn,fname,mode) ((conn)->vfs_ops.chmod((conn),fname,(mode)))
-
-/*******************************************************************
- vfs chown wrapper that calls internal2unix.
-********************************************************************/
-
-#define vfs_chown(conn,fname,uid,gid) ((conn)->vfs_ops.chown((conn),fname,(uid),(gid)))
-
-/*******************************************************************
- A wrapper for vfs_chdir().
-********************************************************************/
-
-#define vfs_chdir(conn,fname) ((conn)->vfs_ops.chdir((conn),fname))
-
#endif /* _SMB_MACROS_H */
diff --git a/source/include/smbprofile.h b/source/include/smbprofile.h
index e501de8c0e2..a64c2ce69ec 100644
--- a/source/include/smbprofile.h
+++ b/source/include/smbprofile.h
@@ -108,6 +108,10 @@ struct profile_stats {
unsigned syscall_mknod_time;
unsigned syscall_realpath_count;
unsigned syscall_realpath_time;
+ unsigned syscall_get_quota_count;
+ unsigned syscall_get_quota_time;
+ unsigned syscall_set_quota_count;
+ unsigned syscall_set_quota_time;
/* stat cache counters */
unsigned statcache_lookups;
unsigned statcache_misses;
@@ -326,6 +330,10 @@ struct profile_stats {
unsigned NT_transact_rename_time;
unsigned NT_transact_query_security_desc_count;
unsigned NT_transact_query_security_desc_time;
+ unsigned NT_transact_get_user_quota_count;
+ unsigned NT_transact_get_user_quota_time;
+ unsigned NT_transact_set_user_quota_count;
+ unsigned NT_transact_set_user_quota_time;
/* These are ACL manipulation calls */
unsigned get_nt_acl_count;
unsigned get_nt_acl_time;
diff --git a/source/include/trans2.h b/source/include/trans2.h
index 2ccf83478be..eb5b1bc79f9 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -224,6 +224,7 @@ Byte offset Type name description
#define SMB_QUERY_FILE_ALL_INFO 0x107
#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108
#define SMB_QUERY_FILE_STREAM_INFO 0x109
+#define SMB_QUERY_COMPRESSION_INFO 0x10b
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
diff --git a/source/include/version.h b/source/include/version.h
index c0a1c702f29..b5b00c7859d 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -1 +1 @@
-#define VERSION "post3.0-HEAD"
+#define VERSION "3.0beta1"
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 756e417814d..924d7063217 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -1,8 +1,10 @@
/*
Unix SMB/CIFS implementation.
VFS structures and parameters
+ Copyright (C) Jeremy Allison 1999-2003
Copyright (C) Tim Potter 1999
Copyright (C) Alexander Bokovoy 2002
+ Copyright (C) Stefan (metze) Metzmacher 2003
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
@@ -45,150 +47,41 @@
/* Changed to version 3 for POSIX acl extensions. JRA. */
/* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */
/* Changed to version 5 for sendfile addition. JRA. */
-#define SMB_VFS_INTERFACE_VERSION 5
+/* Changed to version 6 for the new module system, fixed cascading and quota functions. --metze */
+/* Changed to version 7 to include the get_nt_acl info parameter. JRA. */
+/* Changed to version 8 includes EA calls. JRA. */
+#define SMB_VFS_INTERFACE_VERSION 8
-/* Version of supported cascaded interface backward compatibility.
- (version 5 corresponds to SMB_VFS_INTERFACE_VERSION 5)
- It is used in vfs_init_custom() to detect VFS modules which conform to cascaded
- VFS interface but implement elder version than current version of Samba uses.
- This allows to use old modules with new VFS interface as far as combined VFS operation
- set is coherent (will be in most cases).
-*/
-#define SMB_VFS_INTERFACE_CASCADED 5
+
+/* to bug old modules witch are trying to compile with the old functions */
+#define vfs_init __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore(void) { __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore };
+#define lp_parm_string __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string { \
+ __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string };
+#define lp_vfs_options __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead { \
+ __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead };
/*
- Each VFS module must provide following global functions:
- vfs_init -- initialization function
- vfs_done -- finalization function
-
- vfs_init must return proper initialized vfs_op_tuple[] array
- which describes all operations this module claims to intercept. This function
- is called whenever module is loaded into smbd process using sys_dlopen().
-
- vfs_init must store somewhere vfs_handle reference if module wants to store per-instance
- private information for further usage. vfs_handle->data should be used to
- store such information. Do not try to change other fields in this structure
- or results likely to be unpredictable.
-
- vfs_done must perform finalization of the module. In particular,
- this function must free vfs_ops structure returned to module from smb_vfs_get_opaque_ops()
- function if it is used (see below). This function is called whenever module
- is unloaded from smbd process using sys_dlclose().
-
- Prototypes:
- vfs_op_tuple *vfs_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle);
- void vfs_done(connection_struct *conn);
-
All intercepted VFS operations must be declared as static functions inside module source
- in order to keep smbd namespace unpolluted. See source of skel, audit, and recycle bin
+ in order to keep smbd namespace unpolluted. See source of audit, extd_audit, fake_perms and recycle
example VFS modules for more details.
-
*/
/* VFS operations structure */
+struct vfs_handle_struct;
struct connection_struct;
struct files_struct;
struct security_descriptor_info;
-struct vfs_ops {
-
- /* Disk operations */
-
- int (*connect)(struct connection_struct *conn, const char *service, const char *user);
- void (*disconnect)(struct connection_struct *conn);
- SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
-
- /* Directory operations */
-
- DIR *(*opendir)(struct connection_struct *conn, const char *fname);
- struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp);
- int (*mkdir)(struct connection_struct *conn, const char *path, mode_t mode);
- int (*rmdir)(struct connection_struct *conn, const char *path);
- int (*closedir)(struct connection_struct *conn, DIR *dir);
-
- /* File operations */
-
- int (*open)(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
- int (*close)(struct files_struct *fsp, int fd);
- ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n);
- ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n);
- SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
- ssize_t (*sendfile)(int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
- int (*rename)(struct connection_struct *conn, const char *old, const char *new);
- int (*fsync)(struct files_struct *fsp, int fd);
- int (*stat)(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
- int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
- int (*lstat)(struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
- int (*unlink)(struct connection_struct *conn, const char *path);
- int (*chmod)(struct connection_struct *conn, const char *path, mode_t mode);
- int (*fchmod)(struct files_struct *fsp, int fd, mode_t mode);
- int (*chown)(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid);
- int (*fchown)(struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
- int (*chdir)(struct connection_struct *conn, const char *path);
- char *(*getwd)(struct connection_struct *conn, char *buf);
- int (*utime)(struct connection_struct *conn, const char *path, struct utimbuf *times);
- int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset);
- BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
- int (*symlink)(struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*readlink)(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
- int (*link)(struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*mknod)(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
- char *(*realpath)(struct connection_struct *conn, const char *path, char *resolved_path);
-
- /* NT ACL operations. */
-
- size_t (*fget_nt_acl)(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc);
- size_t (*get_nt_acl)(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc);
- BOOL (*fset_nt_acl)(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
- BOOL (*set_nt_acl)(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
-
- /* POSIX ACL operations. */
-
- int (*chmod_acl)(struct connection_struct *conn, const char *name, mode_t mode);
- int (*fchmod_acl)(struct files_struct *fsp, int fd, mode_t mode);
-
- int (*sys_acl_get_entry)(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
- int (*sys_acl_get_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
- int (*sys_acl_get_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
- void * (*sys_acl_get_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
- SMB_ACL_T (*sys_acl_get_file)(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
- SMB_ACL_T (*sys_acl_get_fd)(struct files_struct *fsp, int fd);
- int (*sys_acl_clear_perms)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_add_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- char * (*sys_acl_to_text)(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
- SMB_ACL_T (*sys_acl_init)(struct connection_struct *conn, int count);
- int (*sys_acl_create_entry)(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
- int (*sys_acl_set_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
- int (*sys_acl_set_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
- int (*sys_acl_set_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_valid)(struct connection_struct *conn, SMB_ACL_T theacl );
- int (*sys_acl_set_file)(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
- int (*sys_acl_set_fd)(struct files_struct *fsp, int fd, SMB_ACL_T theacl);
- int (*sys_acl_delete_def_file)(struct connection_struct *conn, const char *path);
- int (*sys_acl_get_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- int (*sys_acl_free_text)(struct connection_struct *conn, char *text);
- int (*sys_acl_free_acl)(struct connection_struct *conn, SMB_ACL_T posix_acl);
- int (*sys_acl_free_qualifier)(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
-};
-
-struct vfs_options {
- struct vfs_options *prev, *next;
- char *name;
- char *value;
-};
-
/*
- Available VFS operations. These values must be in sync with vfs_ops struct.
+ Available VFS operations. These values must be in sync with vfs_ops struct
+ (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops).
In particular, if new operations are added to vfs_ops, appropriate constants
should be added to vfs_op_type so that order of them kept same as in vfs_ops.
*/
typedef enum _vfs_op_type {
-
SMB_VFS_OP_NOOP = -1,
/* Disk operations */
@@ -196,6 +89,8 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_CONNECT = 0,
SMB_VFS_OP_DISCONNECT,
SMB_VFS_OP_DISK_FREE,
+ SMB_VFS_OP_GET_QUOTA,
+ SMB_VFS_OP_SET_QUOTA,
/* Directory operations */
@@ -269,12 +164,225 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_SYS_ACL_FREE_ACL,
SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
+ /* EA operations. */
+ SMB_VFS_OP_GETXATTR,
+ SMB_VFS_OP_LGETXATTR,
+ SMB_VFS_OP_FGETXATTR,
+ SMB_VFS_OP_LISTXATTR,
+ SMB_VFS_OP_LLISTXATTR,
+ SMB_VFS_OP_FLISTXATTR,
+ SMB_VFS_OP_REMOVEXATTR,
+ SMB_VFS_OP_LREMOVEXATTR,
+ SMB_VFS_OP_FREMOVEXATTR,
+ SMB_VFS_OP_SETXATTR,
+ SMB_VFS_OP_LSETXATTR,
+ SMB_VFS_OP_FSETXATTR,
+
/* This should always be last enum value */
SMB_VFS_OP_LAST
} vfs_op_type;
/*
+ Please keep vfs_op_type, struct vfs_fn_pointers and struct vfs_handles_pointers in sync.
+*/
+struct vfs_ops {
+ struct vfs_fn_pointers {
+ /* Disk operations */
+
+ int (*connect)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user);
+ void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn);
+ SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
+ int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
+ int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
+
+ /* Directory operations */
+
+ DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname);
+ struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
+ int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
+ int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir);
+
+ /* File operations */
+
+ int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode);
+ int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
+ ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n);
+ ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n);
+ SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence);
+ ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new);
+ int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
+ int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
+ int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+ int (*lstat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
+ int (*unlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
+ int (*chmod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
+ int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
+ int (*chown)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid);
+ int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
+ int (*chdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
+ char *(*getwd)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *buf);
+ int (*utime)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct utimbuf *times);
+ int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
+ BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+ int (*symlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
+ int (*readlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
+ int (*link)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
+ int (*mknod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
+ char *(*realpath)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *resolved_path);
+
+ /* NT ACL operations. */
+
+ size_t (*fget_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info, struct security_descriptor_info **ppdesc);
+ size_t (*get_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor_info **ppdesc);
+ BOOL (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
+ BOOL (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
+
+ /* POSIX ACL operations. */
+
+ int (*chmod_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, mode_t mode);
+ int (*fchmod_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
+
+ int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+ int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+ int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+ void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
+ SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
+ SMB_ACL_T (*sys_acl_get_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
+ int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
+ SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, struct connection_struct *conn, int count);
+ int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+ int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+ int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
+ int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_valid)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl );
+ int (*sys_acl_set_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+ int (*sys_acl_set_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_ACL_T theacl);
+ int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
+ int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ int (*sys_acl_free_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *text);
+ int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T posix_acl);
+ int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
+
+ /* EA operations. */
+ ssize_t (*getxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
+ ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
+ ssize_t (*fgetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size);
+ ssize_t (*listxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
+ ssize_t (*llistxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
+ ssize_t (*flistxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size);
+ int (*removexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
+ int (*lremovexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
+ int (*fremovexattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name);
+ int (*setxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
+ int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
+ int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags);
+
+ } ops;
+
+ struct vfs_handles_pointers {
+ /* Disk operations */
+
+ struct vfs_handle_struct *connect;
+ struct vfs_handle_struct *disconnect;
+ struct vfs_handle_struct *disk_free;
+ struct vfs_handle_struct *get_quota;
+ struct vfs_handle_struct *set_quota;
+
+ /* Directory operations */
+
+ struct vfs_handle_struct *opendir;
+ struct vfs_handle_struct *readdir;
+ struct vfs_handle_struct *mkdir;
+ struct vfs_handle_struct *rmdir;
+ struct vfs_handle_struct *closedir;
+
+ /* File operations */
+
+ struct vfs_handle_struct *open;
+ struct vfs_handle_struct *close;
+ struct vfs_handle_struct *read;
+ struct vfs_handle_struct *write;
+ struct vfs_handle_struct *lseek;
+ struct vfs_handle_struct *sendfile;
+ struct vfs_handle_struct *rename;
+ struct vfs_handle_struct *fsync;
+ struct vfs_handle_struct *stat;
+ struct vfs_handle_struct *fstat;
+ struct vfs_handle_struct *lstat;
+ struct vfs_handle_struct *unlink;
+ struct vfs_handle_struct *chmod;
+ struct vfs_handle_struct *fchmod;
+ struct vfs_handle_struct *chown;
+ struct vfs_handle_struct *fchown;
+ struct vfs_handle_struct *chdir;
+ struct vfs_handle_struct *getwd;
+ struct vfs_handle_struct *utime;
+ struct vfs_handle_struct *ftruncate;
+ struct vfs_handle_struct *lock;
+ struct vfs_handle_struct *symlink;
+ struct vfs_handle_struct *readlink;
+ struct vfs_handle_struct *link;
+ struct vfs_handle_struct *mknod;
+ struct vfs_handle_struct *realpath;
+
+ /* NT ACL operations. */
+
+ struct vfs_handle_struct *fget_nt_acl;
+ struct vfs_handle_struct *get_nt_acl;
+ struct vfs_handle_struct *fset_nt_acl;
+ struct vfs_handle_struct *set_nt_acl;
+
+ /* POSIX ACL operations. */
+
+ struct vfs_handle_struct *chmod_acl;
+ struct vfs_handle_struct *fchmod_acl;
+
+ struct vfs_handle_struct *sys_acl_get_entry;
+ struct vfs_handle_struct *sys_acl_get_tag_type;
+ struct vfs_handle_struct *sys_acl_get_permset;
+ struct vfs_handle_struct *sys_acl_get_qualifier;
+ struct vfs_handle_struct *sys_acl_get_file;
+ struct vfs_handle_struct *sys_acl_get_fd;
+ struct vfs_handle_struct *sys_acl_clear_perms;
+ struct vfs_handle_struct *sys_acl_add_perm;
+ struct vfs_handle_struct *sys_acl_to_text;
+ struct vfs_handle_struct *sys_acl_init;
+ struct vfs_handle_struct *sys_acl_create_entry;
+ struct vfs_handle_struct *sys_acl_set_tag_type;
+ struct vfs_handle_struct *sys_acl_set_qualifier;
+ struct vfs_handle_struct *sys_acl_set_permset;
+ struct vfs_handle_struct *sys_acl_valid;
+ struct vfs_handle_struct *sys_acl_set_file;
+ struct vfs_handle_struct *sys_acl_set_fd;
+ struct vfs_handle_struct *sys_acl_delete_def_file;
+ struct vfs_handle_struct *sys_acl_get_perm;
+ struct vfs_handle_struct *sys_acl_free_text;
+ struct vfs_handle_struct *sys_acl_free_acl;
+ struct vfs_handle_struct *sys_acl_free_qualifier;
+
+ /* EA operations. */
+ struct vfs_handle_struct *getxattr;
+ struct vfs_handle_struct *lgetxattr;
+ struct vfs_handle_struct *fgetxattr;
+ struct vfs_handle_struct *listxattr;
+ struct vfs_handle_struct *llistxattr;
+ struct vfs_handle_struct *flistxattr;
+ struct vfs_handle_struct *removexattr;
+ struct vfs_handle_struct *lremovexattr;
+ struct vfs_handle_struct *fremovexattr;
+ struct vfs_handle_struct *setxattr;
+ struct vfs_handle_struct *lsetxattr;
+ struct vfs_handle_struct *fsetxattr;
+ } handles;
+};
+
+/*
Possible VFS operation layers (per-operation)
These values are used by VFS subsystem when building vfs_ops for connection
@@ -300,7 +408,7 @@ typedef enum _vfs_op_layer {
SMB_VFS_LAYER_OPAQUE = 0, /* - Final level, does not call anything beyond itself */
SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */
/* possibly changing passed data */
- SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging does not */
+ SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging may not */
/* use Samba VFS */
SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */
/* then combines result */
@@ -309,10 +417,10 @@ typedef enum _vfs_op_layer {
} vfs_op_layer;
/*
- VFS operation description. Each VFS module initialization function returns to VFS subsystem
- an array of vfs_op_tuple which describes all operations this module is willing to intercept.
- VFS subsystem initializes then vfs_ops using this information and passes it
- to next VFS module as underlying vfs_ops and to connection after all VFS modules are initialized.
+ VFS operation description. Each VFS module registers an array of vfs_op_tuple to VFS subsystem,
+ which describes all operations this module is willing to intercept.
+ VFS subsystem initializes then the conn->vfs_ops and conn->vfs_opaque_ops structs
+ using this information.
*/
typedef struct _vfs_op_tuple {
@@ -321,18 +429,46 @@ typedef struct _vfs_op_tuple {
vfs_op_layer layer;
} vfs_op_tuple;
-/*
- Return vfs_ops filled with current opaque VFS operations. This function is designed to
- be called from VFS module initialization function for those modules which needs 'direct' VFS
- access (loggers or initiators of file operations other than connection asks for).
-
- Returned vfs_ops must be cleaned up in VFS module's finalizer function (vfs_done_<module_name>)
- using safe_free().
-
- Prototype:
- struct vfs_ops *smb_vfs_get_opaque_ops();
-
- This prototype will be available via include/proto.h
-*/
+
+typedef struct vfs_handle_struct {
+ struct vfs_handle_struct *next, *prev;
+ const char *param;
+ struct vfs_ops vfs_next;
+ struct connection_struct *conn;
+ void *data;
+ void (*free_data)(void **data);
+} vfs_handle_struct;
+
+
+#define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \
+ if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \
+ DEBUG(0,("%s() failed to get vfs_handle->data!\n",FUNCTION_MACRO)); \
+ ret; \
+ } \
+}
+
+#define SMB_VFS_HANDLE_SET_DATA(handle, datap, free_fn, type, ret) { \
+ if (!(handle)) { \
+ DEBUG(0,("%s() failed to set handle->data!\n",FUNCTION_MACRO)); \
+ ret; \
+ } else { \
+ if ((handle)->free_data) { \
+ (handle)->free_data(&(handle)->data); \
+ } \
+ (handle)->data = (void *)datap; \
+ (handle)->free_data = free_fn; \
+ } \
+}
+
+#define SMB_VFS_HANDLE_FREE_DATA(handle) { \
+ if ((handle) && (handle)->free_data) { \
+ (handle)->free_data(&(handle)->data); \
+ } \
+}
+
+#define SMB_VFS_OP(x) ((void *) x)
+
+
+#include "vfs_macros.h"
#endif /* _VFS_H */
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index eb427cc0fce..708ef343e1a 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -367,7 +367,7 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
src = tmpbuf;
}
- if (flags & STR_TERMINATE)
+ if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
src_len++;
return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
@@ -723,8 +723,21 @@ size_t pull_utf8_allocate(void **dest, const char *src)
size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
{
+#ifdef DEVELOPER
+ /* We really need to zero fill here, not clobber
+ * region, as we want to ensure that valgrind thinks
+ * all of the outgoing buffer has been written to
+ * so a send() or write() won't trap an error.
+ * JRA.
+ */
+#if 0
if (dest_len != (size_t)-1)
clobber_region(function, line, dest, dest_len);
+#else
+ if (dest_len != (size_t)-1)
+ memset(dest, '\0', dest_len);
+#endif
+#endif
if (!(flags & STR_ASCII) && \
((flags & STR_UNICODE || \
diff --git a/source/lib/module.c b/source/lib/module.c
index 4437d085f9c..ac4fe57a2c8 100644
--- a/source/lib/module.c
+++ b/source/lib/module.c
@@ -130,29 +130,6 @@ void init_modules(void)
}
-/*************************************************************************
- * This functions /path/to/foobar.so -> foobar
- ************************************************************************/
-void module_path_get_name(const char *path, pstring name)
-{
- char *s;
-
- /* First, make the path relative */
- s = strrchr(path, '/');
- if(s) pstrcpy(name, s+1);
- else pstrcpy(name, path);
-
- if (dyn_SHLIBEXT && *dyn_SHLIBEXT && strlen(dyn_SHLIBEXT) < strlen(name)) {
- int n = strlen(name) - strlen(dyn_SHLIBEXT);
-
- /* Remove extension if necessary */
- if (name[n-1] == '.' && !strcmp(name+n, dyn_SHLIBEXT)) {
- name[n-1] = '\0';
- }
- }
-}
-
-
/***************************************************************************
* This Function registers a idle event
*
diff --git a/source/lib/system.c b/source/lib/system.c
index 6ff97b88da3..a7024c852df 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -1253,3 +1253,128 @@ int sys_dup2(int oldfd, int newfd)
#endif
SAFE_FREE(msgbuf);
}
+
+/**************************************************************************
+ Wrappers for extented attribute calls. Based on the Linux package with
+ support for IRIX also. Expand as other systems have them.
+****************************************************************************/
+
+ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_GETXATTR)
+ return getxattr(path, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_LGETXATTR)
+ return lgetxattr(path, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_FGETXATTR)
+ return fgetxattr(filedes, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_listxattr (const char *path, char *list, size_t size)
+{
+#if defined(HAVE_LISTXATTR)
+ return listxattr(path, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_llistxattr (const char *path, char *list, size_t size)
+{
+#if defined(HAVE_GETXATTR)
+ return llistxattr(path, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_flistxattr (int filedes, char *list, size_t size)
+{
+#if defined(HAVE_FLISTXATTR)
+ return flistxattr(filedes, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_removexattr (const char *path, const char *name)
+{
+#if defined(HAVE_REMOVEXATTR)
+ return removexattr(path, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_lremovexattr (const char *path, const char *name)
+{
+#if defined(HAVE_LREMOVEXATTR)
+ return lremovexattr(path, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_fremovexattr (int filedes, const char *name)
+{
+#if defined(HAVE_FREMOVEXATTR)
+ return fremovexattr(filedes, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
+{
+#if defined(HAVE_SETXATTR)
+ return setxattr(path, name, value, size, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
+{
+#if defined(HAVE_LSETXATTR)
+ return lsetxattr(path, name, value, size, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
+{
+#if defined(HAVE_FSETXATTR)
+ return fsetxattr(filedes, name, value, size, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index e1ddd578839..95d3403a7cd 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -937,6 +937,19 @@ void *Realloc(void *p,size_t size)
return(ret);
}
+void *Realloc_zero(void *ptr, size_t size)
+{
+ void *tptr = NULL;
+
+ tptr = Realloc(ptr, size);
+ if(tptr == NULL)
+ return NULL;
+
+ memset((char *)tptr,'\0',size);
+
+ return tptr;
+}
+
/****************************************************************************
Free memory, checks for NULL.
Use directly SAFE_FREE()
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 9dc0c8ca18d..00f14d7d26b 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -391,6 +391,9 @@ BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *
if (!exp_dom_sid || !sid || !rid)
return False;
+ if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
+ return False;
+ }
if (sid_compare_domain(exp_dom_sid, sid)!=0){
*rid=(-1);
@@ -642,8 +645,9 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
if(!src)
return NULL;
- if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL)
+ if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
sid_copy( dst, src);
+ }
return dst;
}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index c974050b43e..8c171852abb 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -764,6 +764,19 @@ char *client_addr(void)
return get_socket_addr(client_fd);
}
+struct in_addr *client_inaddr(struct sockaddr *sa)
+{
+ struct sockaddr_in *sockin = (struct sockaddr_in *) (sa);
+ int length = sizeof(*sa);
+
+ if (getpeername(client_fd, sa, &length) < 0) {
+ DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
+ return NULL;
+ }
+
+ return &sockin->sin_addr;
+}
+
/*******************************************************************
matchname - determine if host name matches IP address. Used to
confirm a hostname lookup to prevent spoof attacks
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index e561d15f61b..87a8ea2eb19 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1713,3 +1713,25 @@ char * base64_encode_data_blob(DATA_BLOB data)
return result;
}
+/* read a SMB_BIG_UINT from a string */
+SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
+{
+
+ SMB_BIG_UINT val = -1;
+ const char *p = nptr;
+
+ while (p && *p && isspace(*p))
+ p++;
+#ifdef LARGE_SMB_OFF_T
+ sscanf(p,"%llu",&val);
+#else /* LARGE_SMB_OFF_T */
+ sscanf(p,"%lu",&val);
+#endif /* LARGE_SMB_OFF_T */
+ if (entptr) {
+ while (p && *p && isdigit(*p))
+ p++;
+ *entptr = p;
+ }
+
+ return val;
+}
diff --git a/source/libads/ads_utils.c b/source/libads/ads_utils.c
index c56e7385a41..1aad0bed547 100644
--- a/source/libads/ads_utils.c
+++ b/source/libads/ads_utils.c
@@ -89,52 +89,6 @@ uint32 ads_uf2atype(uint32 uf)
}
/*
-translated the GROUP_CTRL Flags to GroupType (groupType)
-*/
-uint32 ads_gcb2gtype(uint16 gcb)
-{
- uint32 gtype = 0x00000000;
-
- if (gcb & GCB_ALIAS_GROUP) gtype |= GTYPE_SECURITY_BUILTIN_LOCAL_GROUP;
- else if(gcb & GCB_LOCAL_GROUP) gtype |= GTYPE_SECURITY_DOMAIN_LOCAL_GROUP;
- if (gcb & GCB_GLOBAL_GROUP) gtype |= GTYPE_SECURITY_GLOBAL_GROUP;
-
- return gtype;
-}
-
-/*
-translated the GroupType (groupType) to GROUP_CTRL Flags
-*/
-uint16 ads_gtype2gcb(uint32 gtype)
-{
- uint16 gcb = 0x0000;
-
- switch(gtype) {
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- gcb = GCB_ALIAS_GROUP;
- break;
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- gcb = GCB_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_GLOBAL_GROUP:
- gcb = GCB_GLOBAL_GROUP;
- break;
-
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- gcb = GCB_GLOBAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- gcb = GCB_LOCAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- gcb = GCB_GLOBAL_GROUP;
- break;
- }
-
- return gcb;
-}
-
-/*
get the accountType from the groupType
*/
uint32 ads_gtype2atype(uint32 gtype)
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
index 35d429ca2ab..65b557af574 100644
--- a/source/libads/kerberos_verify.c
+++ b/source/libads/kerberos_verify.c
@@ -138,9 +138,11 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
*ap_rep = data_blob(packet.data, packet.length);
free(packet.data);
- krb5_get_smb_session_key(context, auth_context, session_key);
- DEBUG(0,("SMB session key (from ticket) follows:\n"));
- dump_data(0, session_key, 16);
+ get_krb5_smb_session_key(context, auth_context, session_key);
+#ifdef DEBUG_PASSWORD
+ DEBUG(10,("SMB session key (from ticket) follows:\n"));
+ dump_data(10, session_key, 16);
+#endif
#if 0
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c
index 214871b3fb5..df749d04d36 100644
--- a/source/libads/krb5_setpw.c
+++ b/source/libads/krb5_setpw.c
@@ -195,9 +195,9 @@ static const struct kpasswd_errors {
{0, NULL}
};
-static krb5_error_code krb5_setpw_result_code_string(krb5_context context,
- int result_code,
- const char **code_string)
+static krb5_error_code setpw_result_code_string(krb5_context context,
+ int result_code,
+ const char **code_string)
{
unsigned int idx = 0;
@@ -311,7 +311,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context,
return 0;
else {
const char *errstr;
- krb5_setpw_result_code_string(context, res_code, &errstr);
+ setpw_result_code_string(context, res_code, &errstr);
DEBUG(1, ("Error changing password: %s\n", errstr));
switch(res_code) {
@@ -457,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
return ADS_SUCCESS;
}
-ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw,
- int time_offset)
+ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
+ const char *newpw, int time_offset)
{
ADS_STATUS aret;
@@ -570,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data,
return 0;
}
-static ADS_STATUS krb5_chg_password(const char *kdc_host,
- const char *principal,
- const char *oldpw,
- const char *newpw,
- int time_offset)
+static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
+ const char *principal,
+ const char *oldpw,
+ const char *newpw,
+ int time_offset)
{
ADS_STATUS aret;
krb5_error_code ret;
@@ -648,11 +648,11 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
}
if (!strcmp(auth_principal, target_principal))
- return krb5_chg_password(kpasswd_server, target_principal,
- auth_password, new_password, time_offset);
+ return ads_krb5_chg_password(kpasswd_server, target_principal,
+ auth_password, new_password, time_offset);
else
- return krb5_set_password(kpasswd_server, target_principal,
- new_password, time_offset);
+ return ads_krb5_set_password(kpasswd_server, target_principal,
+ new_password, time_offset);
}
@@ -677,9 +677,10 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
we need to use the '$' form of the name here, as otherwise the
server might end up setting the password for a user instead
*/
- asprintf(&principal, "%s$@%s", host, ads->auth.realm);
+ asprintf(&principal, "%s$@%s", host, ads->config.realm);
- status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset);
+ status = ads_krb5_set_password(ads->auth.kdc_server, principal,
+ password, ads->auth.time_offset);
free(host);
free(principal);
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 32397173da1..8ebac7bae7b 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -270,14 +270,23 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
if (passlen != 24) {
if (lp_client_ntlmv2_auth()) {
DATA_BLOB server_chal;
-
+ DATA_BLOB names_blob;
server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
- if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal,
+ /* note that the 'workgroup' here is a best guess - we don't know
+ the server's domain at this point. The 'server name' is also
+ dodgy...
+ */
+ names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
+
+ if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
+ &names_blob,
&lm_response, &nt_response, &session_key)) {
+ data_blob_free(&names_blob);
data_blob_free(&server_chal);
return False;
}
+ data_blob_free(&names_blob);
data_blob_free(&server_chal);
} else {
@@ -823,9 +832,6 @@ BOOL cli_send_tconX(struct cli_state *cli,
clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
- if (strcasecmp(share,"IPC$")==0)
- fstrcpy(cli->dev, "IPC");
-
if (cli->protocol >= PROTOCOL_NT1 &&
smb_buflen(cli->inbuf) == 3) {
/* almost certainly win95 - enable bug fixes */
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index 5edc56daa9b..df6043a618b 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -235,12 +235,12 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
/*
we can't use krb5_mk_req because w2k wants the service to be in a particular format
*/
-static krb5_error_code krb5_mk_req2(krb5_context context,
- krb5_auth_context *auth_context,
- const krb5_flags ap_req_options,
- const char *principal,
- krb5_ccache ccache,
- krb5_data *outbuf)
+static krb5_error_code ads_krb5_mk_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ const char *principal,
+ krb5_ccache ccache,
+ krb5_data *outbuf)
{
krb5_error_code retval;
krb5_principal server;
@@ -305,7 +305,7 @@ cleanup_princ:
/*
get a kerberos5 ticket for the given service
*/
-DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
{
krb5_error_code retval;
krb5_data packet;
@@ -344,11 +344,11 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
goto failed;
}
- if ((retval = krb5_mk_req2(context,
- &auth_context,
- 0,
- principal,
- ccdef, &packet))) {
+ if ((retval = ads_krb5_mk_req(context,
+ &auth_context,
+ 0,
+ principal,
+ ccdef, &packet))) {
goto failed;
}
@@ -365,7 +365,7 @@ failed:
return data_blob(NULL, 0);
}
- BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
+ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
{
#ifdef ENCTYPE_ARCFOUR_HMAC
krb5_keyblock *skey;
@@ -390,7 +390,7 @@ failed:
}
#else /* HAVE_KRB5 */
/* this saves a few linking headaches */
-DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
{
DEBUG(0,("NO KERBEROS SUPPORT\n"));
return data_blob(NULL, 0);
diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c
index 53f7eb6e7d9..bb48f579151 100644
--- a/source/libsmb/clispnego.c
+++ b/source/libsmb/clispnego.c
@@ -329,7 +329,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset)
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
/* get a kerberos ticket for the service */
- tkt = krb5_get_ticket(principal, time_offset);
+ tkt = cli_krb5_get_ticket(principal, time_offset);
/* wrap that up in a nice GSS-API wrapping */
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c
index ffc64139e9b..e98b728963e 100644
--- a/source/libsmb/namequery_dc.c
+++ b/source/libsmb/namequery_dc.c
@@ -25,15 +25,149 @@
#include "includes.h"
-/*
- find the DC for a domain using methods appropriate for a RPC domain
-*/
+#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
+
+struct failed_connection_cache {
+ fstring domain_name;
+ fstring controller;
+ time_t lookup_time;
+ NTSTATUS nt_status;
+ struct failed_connection_cache *prev, *next;
+};
+
+static struct failed_connection_cache *failed_connection_cache;
+
+/**********************************************************************
+ Check for a previously failed connection
+**********************************************************************/
+
+static NTSTATUS check_negative_conn_cache( const char *domain, const char *server )
+{
+ struct failed_connection_cache *fcc;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ /* can't check if we don't have strings */
+
+ if ( !domain || !server )
+ return NT_STATUS_OK;
+
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+
+ /*
+ * we have a match IFF the domain and server name matches
+ * (a) the domain matches,
+ * (b) the IP address matches (if we have one)
+ * (c) the server name (if specified) matches
+ */
+
+ if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) )
+ continue; /* no match; check the next entry */
+
+ /* we have a match so see if it is still current */
+
+ if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT)
+ {
+ /* Cache entry has expired, delete it */
+
+ DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
+ domain, server ));
+
+ DLIST_REMOVE(failed_connection_cache, fcc);
+ SAFE_FREE(fcc);
+
+ return NT_STATUS_OK;
+ }
+
+ /* The timeout hasn't expired yet so return false */
+
+ DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
+ domain, server ));
+
+ result = fcc->nt_status;
+ return result;
+ }
+
+ /* end of function means no cache entry */
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
+ Add an entry to the failed conneciton cache
+**********************************************************************/
+
+void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
+{
+ struct failed_connection_cache *fcc;
+
+ SMB_ASSERT(!NT_STATUS_IS_OK(result));
+
+ /* Check we already aren't in the cache. We always have to have
+ a domain, but maybe not a specific DC name. */
+
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+ if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) )
+ {
+ DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
+ domain, server ));
+ return;
+ }
+ }
+
+ /* Create negative lookup cache entry for this domain and controller */
+
+ if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) )
+ {
+ DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
+ return;
+ }
+
+ ZERO_STRUCTP(fcc);
+
+ fstrcpy( fcc->domain_name, domain );
+ fstrcpy( fcc->controller, server );
+ fcc->lookup_time = time(NULL);
+ fcc->nt_status = result;
+
+ DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
+ domain, server ));
+
+ DLIST_ADD(failed_connection_cache, fcc);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+void flush_negative_conn_cache( void )
+{
+ struct failed_connection_cache *fcc;
+
+ fcc = failed_connection_cache;
+
+ while (fcc) {
+ struct failed_connection_cache *fcc_next;
+
+ fcc_next = fcc->next;
+ DLIST_REMOVE(failed_connection_cache, fcc);
+ free(fcc);
+
+ fcc = fcc_next;
+ }
+
+}
+
+/****************************************************************************
+ Utility function to return the name of a DC using RPC. The name is
+ guaranteed to be valid since we have already done a name_status_find on it
+ and we have checked our negative connection cache
+ ***************************************************************************/
+
BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
{
struct in_addr *ip_list = NULL, dc_ip, exclude_ip;
int count, i;
BOOL list_ordered;
BOOL use_pdc_only;
+ NTSTATUS result;
zero_ip(&exclude_ip);
@@ -41,11 +175,15 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
/* Lookup domain controller name */
- if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) {
+ if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) )
+ {
DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n"));
if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) {
- goto done;
+ /* makre we we haven't tried this on previously and failed */
+ result = check_negative_conn_cache( domain, srv_name );
+ if ( NT_STATUS_IS_OK(result) )
+ goto done;
}
/* Didn't get name, remember not to talk to this DC. */
exclude_ip = dc_ip;
@@ -77,8 +215,11 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
continue;
if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
- dc_ip = ip_list[i];
- goto done;
+ result = check_negative_conn_cache( domain, srv_name );
+ if ( NT_STATUS_IS_OK(result) ) {
+ dc_ip = ip_list[i];
+ goto done;
+ }
}
}
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 30ce5b6b10c..b96111240f1 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -295,7 +295,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
if (name->scope[0]) {
/* XXXX this scope handling needs testing */
ret += strlen(name->scope) + 1;
- pstrcpy(&buf[offset+1],name->scope);
+ safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
p = &buf[offset+1];
while ((p = strchr_m(p,'.'))) {
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
index d54655d17f7..636e384e657 100644
--- a/source/libsmb/ntlmssp.c
+++ b/source/libsmb/ntlmssp.c
@@ -487,9 +487,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
}
SAFE_FREE(server_domain);
- data_blob_free(&struct_blob);
-
if (challenge_blob.length != 8) {
+ data_blob_free(&struct_blob);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -500,9 +499,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
if (!SMBNTLMv2encrypt(ntlmssp_state->user,
ntlmssp_state->domain,
- ntlmssp_state->password, challenge_blob,
+ ntlmssp_state->password, &challenge_blob,
+ &struct_blob,
&lm_response, &nt_response, &session_key)) {
data_blob_free(&challenge_blob);
+ data_blob_free(&struct_blob);
return NT_STATUS_NO_MEMORY;
}
} else {
@@ -522,6 +523,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
session_key = data_blob(NULL, 16);
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
}
+ data_blob_free(&struct_blob);
/* this generates the actual auth packet */
if (!msrpc_gen(next_request, auth_gen_string,
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index 4e9b895a1b3..eedf7f401f9 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -111,6 +111,9 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli)
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
+ *
+ * We put the sequence into the packet, because we are going
+ * to copy over it anyway.
*/
SIVAL(cli->outbuf, smb_ss_field,
data->send_seq_num);
@@ -132,7 +135,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli)
memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8);
/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote server actually verifies signitures...*/
+ Uncomment this to test if the remote server actually verifies signatures...*/
data->send_seq_num++;
data->reply_seq_num = data->send_seq_num;
data->send_seq_num++;
@@ -155,6 +158,8 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
+ *
+ * We do this here, to avoid modifying the packet.
*/
SIVAL(sequence_buf, 0, data->reply_seq_num);
@@ -163,15 +168,28 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
/* get a copy of the server-sent mac */
memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac));
- /* Calculate the 16 byte MAC and place first 8 bytes into the field. */
+ /* Calculate the 16 byte MAC - but don't alter the data in the
+ incoming packet.
+
+ This makes for a bit for fussing about, but it's not too bad.
+ */
MD5Init(&md5_ctx);
+
+ /* intialise with the key */
MD5Update(&md5_ctx, data->mac_key.data,
data->mac_key.length);
+
+ /* copy in the first bit of the SMB header */
MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4);
+
+ /* copy in the sequence number, instead of the signature */
MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
-
+
+ /* copy in the rest of the packet in, skipping the signature */
MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig,
smb_len(cli->inbuf) - (offset_end_of_sig - 4));
+
+ /* caclulate the MD5 sig */
MD5Final(calc_md5_mac, &md5_ctx);
good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
@@ -219,10 +237,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
data = smb_xmalloc(sizeof(*data));
cli->sign_info.signing_context = data;
- data->mac_key = data_blob(NULL, MIN(response.length + 16, 40));
+ data->mac_key = data_blob(NULL, response.length + 16);
memcpy(&data->mac_key.data[0], user_session_key, 16);
- memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16));
+ memcpy(&data->mac_key.data[16],response.data, response.length);
/* Initialise the sequence number */
data->send_seq_num = 0;
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 28160d96094..c1b38802996 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -76,10 +76,9 @@ void E_deshash(const char *passwd, uchar p16[16])
{
fstring dospwd;
ZERO_STRUCT(dospwd);
- ZERO_STRUCTP(p16);
/* Password must be converted to DOS charset - null terminated, uppercase. */
- push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
+ push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
/* Only the fisrt 14 chars are considered, password need not be null terminated. */
E_P16(dospwd, p16);
@@ -250,21 +249,21 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
/* Does the md5 encryption from the NT hash for NTLMv2. */
void SMBOWFencrypt_ntv2(const uchar kr[16],
- const DATA_BLOB srv_chal,
- const DATA_BLOB cli_chal,
+ const DATA_BLOB *srv_chal,
+ const DATA_BLOB *cli_chal,
uchar resp_buf[16])
{
HMACMD5Context ctx;
hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(srv_chal.data, srv_chal.length, &ctx);
- hmac_md5_update(cli_chal.data, cli_chal.length, &ctx);
+ hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
+ hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
hmac_md5_final(resp_buf, &ctx);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
- dump_data(100, srv_chal.data, srv_chal.length);
- dump_data(100, cli_chal.data, cli_chal.length);
+ dump_data(100, srv_chal->data, srv_chal->length);
+ dump_data(100, cli_chal->data, cli_chal->length);
dump_data(100, resp_buf, 16);
#endif
}
@@ -295,36 +294,99 @@ void SMBsesskeygen_ntv1(const uchar kr[16],
#endif
}
-static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16],
- DATA_BLOB server_chal, size_t client_chal_length)
+DATA_BLOB NTLMv2_generate_names_blob(const char *hostname,
+ const char *domain)
+{
+ DATA_BLOB names_blob = data_blob(NULL, 0);
+
+ msrpc_gen(&names_blob, "aaa",
+ True, NTLMSSP_NAME_TYPE_DOMAIN, domain,
+ True, NTLMSSP_NAME_TYPE_SERVER, hostname,
+ True, 0, "");
+ return names_blob;
+}
+
+static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob)
+{
+ uchar client_chal[8];
+ DATA_BLOB response = data_blob(NULL, 0);
+ char long_date[8];
+
+ generate_random_buffer(client_chal, sizeof(client_chal), False);
+
+ put_long_date(long_date, time(NULL));
+
+ /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */
+
+ msrpc_gen(&response, "ddbbdb",
+ 0x00000101, /* Header */
+ 0, /* 'Reserved' */
+ long_date, 8, /* Timestamp */
+ client_chal, 8, /* client challenge */
+ 0, /* Unknown */
+ names_blob->data, names_blob->length); /* End of name list */
+
+ return response;
+}
+
+static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16],
+ const DATA_BLOB *server_chal,
+ const DATA_BLOB *names_blob)
{
uchar ntlmv2_response[16];
DATA_BLOB ntlmv2_client_data;
DATA_BLOB final_response;
/* NTLMv2 */
+ /* generate some data to pass into the response function - including
+ the hostname and domain name of the server */
+ ntlmv2_client_data = NTLMv2_generate_client_data(names_blob);
- /* We also get to specify some random data */
- ntlmv2_client_data = data_blob(NULL, client_chal_length);
- generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False);
-
/* Given that data, and the challenge from the server, generate a response */
- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response);
+ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);
- /* put it into nt_response, for the code below to put into the packet */
- final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response));
+ final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);
+
memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));
- /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */
- memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length);
+
+ memcpy(final_response.data+sizeof(ntlmv2_response),
+ ntlmv2_client_data.data, ntlmv2_client_data.length);
+
data_blob_free(&ntlmv2_client_data);
return final_response;
}
+static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16],
+ const DATA_BLOB *server_chal)
+{
+ uchar lmv2_response[16];
+ DATA_BLOB lmv2_client_data = data_blob(NULL, 8);
+ DATA_BLOB final_response = data_blob(NULL, 24);
+
+ /* LMv2 */
+ /* client-supplied random data */
+ generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False);
+
+ /* Given that data, and the challenge from the server, generate a response */
+ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
+ memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));
+
+ /* after the first 16 bytes is the random data we generated above,
+ so the server can verify us with it */
+ memcpy(final_response.data+sizeof(lmv2_response),
+ lmv2_client_data.data, lmv2_client_data.length);
+
+ data_blob_free(&lmv2_client_data);
+
+ return final_response;
+}
+
BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password,
- const DATA_BLOB server_chal,
+ const DATA_BLOB *server_chal,
+ const DATA_BLOB *names_blob,
DATA_BLOB *lm_response, DATA_BLOB *nt_response,
- DATA_BLOB *session_key)
+ DATA_BLOB *nt_session_key)
{
uchar nt_hash[16];
uchar ntlm_v2_hash[16];
@@ -338,18 +400,24 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
return False;
}
- *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */);
+ if (nt_response) {
+ *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal,
+ names_blob);
+ if (nt_session_key) {
+ *nt_session_key = data_blob(NULL, 16);
+
+ /* The NTLMv2 calculations also provide a session key, for signing etc later */
+ /* use only the first 16 bytes of nt_response for session key */
+ SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data);
+ }
+ }
/* LMv2 */
- *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8);
-
- *session_key = data_blob(NULL, 16);
+ if (lm_response) {
+ *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal);
+ }
- /* The NTLMv2 calculations also provide a session key, for signing etc later */
- /* use only the first 16 bytes of nt_response for session key */
- SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data);
-
return True;
}
diff --git a/source/locking/posix.c b/source/locking/posix.c
index 2b64631d39a..6173c80b2fd 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -205,7 +205,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
/*
* No POSIX to worry about, just close.
*/
- ret = conn->vfs_ops.close(fsp,fsp->fd);
+ ret = SMB_VFS_CLOSE(fsp,fsp->fd);
fsp->fd = -1;
return ret;
}
@@ -259,7 +259,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
for(i = 0; i < count; i++) {
- if (conn->vfs_ops.close(fsp,fd_array[i]) == -1) {
+ if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) {
saved_errno = errno;
}
}
@@ -278,7 +278,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
* Finally close the fd associated with this fsp.
*/
- ret = conn->vfs_ops.close(fsp,fsp->fd);
+ ret = SMB_VFS_CLOSE(fsp,fsp->fd);
if (saved_errno != 0) {
errno = saved_errno;
@@ -646,11 +646,10 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
int ret;
- struct connection_struct *conn = fsp->conn;
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
- ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
@@ -674,7 +673,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
errno = 0;
count &= 0x7fffffff;
- ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
}
}
diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c
index 4f9dc1b1e40..550d918b43c 100644
--- a/source/modules/vfs_audit.c
+++ b/source/modules/vfs_audit.c
@@ -2,8 +2,9 @@
* Auditing VFS module for samba. Log selected file operations to syslog
* facility.
*
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
+ * Copyright (C) Tim Potter 1999-2000
+ * Copyright (C) Alexander Bokovoy 2002
+ * Copyright (C) Stefan (metze) Metzmacher 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
@@ -20,118 +21,111 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#include <syslog.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
-
-#ifndef SYSLOG_FACILITY
-#define SYSLOG_FACILITY LOG_USER
-#endif
-
-#ifndef SYSLOG_PRIORITY
-#define SYSLOG_PRIORITY LOG_NOTICE
-#endif
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
/* Function prototypes */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(struct connection_struct *conn);
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname);
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(struct connection_struct *conn, const char *path);
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(struct files_struct *fsp, int fd);
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new);
-static int audit_unlink(struct connection_struct *conn, const char *path);
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
+static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
+static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
+static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname);
+static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
+static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
+static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
+static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
+static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new);
+static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
+static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
+static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
+static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
+static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *audit_handle;
-
-static vfs_op_tuple audit_ops[] = {
+static vfs_op_tuple audit_op_tuples[] = {
/* Disk operations */
- {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
/* Directory operations */
- {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
/* File operations */
- {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
/* Finish VFS operations definition */
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+static int audit_syslog_facility(vfs_handle_struct *handle)
{
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- audit_handle = vfs_handle;
+ /* fix me: let this be configurable by:
+ * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog facility",
+ * audit_enum_facility,LOG_USER);
+ */
+ return LOG_USER;
+}
- openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
- syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
- return audit_ops;
+
+static int audit_syslog_priority(vfs_handle_struct *handle)
+{
+ /* fix me: let this be configurable by:
+ * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog priority",
+ * audit_enum_priority,LOG_NOTICE);
+ */
+ return LOG_NOTICE;
}
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
+static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
{
- syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n",
+ int result;
+
+ openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
+
+ syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
svc, user);
- return default_vfs_ops.connect(conn, svc, user);
+ result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
+
+ return result;
}
-static void audit_disconnect(struct connection_struct *conn)
+static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
{
- syslog(SYSLOG_PRIORITY, "disconnected\n");
- default_vfs_ops.disconnect(conn);
+ syslog(audit_syslog_priority(handle), "disconnected\n");
+ SMB_VFS_NEXT_DISCONNECT(handle, conn);
+
+ return;
}
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
+static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
{
- DIR *result = default_vfs_ops.opendir(conn, fname);
+ DIR *result;
+
+ result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
- syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
fname,
(result == NULL) ? "failed: " : "",
(result == NULL) ? strerror(errno) : "");
@@ -139,11 +133,13 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
return result;
}
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
- int result = default_vfs_ops.mkdir(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n",
+ int result;
+
+ result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
+
+ syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -151,11 +147,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_rmdir(struct connection_struct *conn, const char *path)
+static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
- int result = default_vfs_ops.rmdir(conn, path);
+ int result;
+
+ result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
- syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -163,11 +161,13 @@ static int audit_rmdir(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
{
- int result = default_vfs_ops.open(conn, fname, flags, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
- syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n",
+ syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
fname, result,
((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
(result < 0) ? "failed: " : "",
@@ -176,11 +176,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla
return result;
}
-static int audit_close(struct files_struct *fsp, int fd)
+static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
{
- int result = default_vfs_ops.close(fsp, fd);
+ int result;
+
+ result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
- syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
+ syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
fd,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -188,11 +190,13 @@ static int audit_close(struct files_struct *fsp, int fd)
return result;
}
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new)
+static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
{
- int result = default_vfs_ops.rename(conn, old, new);
+ int result;
+
+ result = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
- syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
old, new,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -200,11 +204,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c
return result;
}
-static int audit_unlink(struct connection_struct *conn, const char *path)
+static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
- int result = default_vfs_ops.unlink(conn, path);
+ int result;
+
+ result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
- syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -212,11 +218,13 @@ static int audit_unlink(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
- int result = default_vfs_ops.chmod(conn, path, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
- syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
path, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -224,16 +232,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
int result;
- if ( !default_vfs_ops.chmod_acl )
- return 0;
+ result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
- result = default_vfs_ops.chmod_acl(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
path, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -241,11 +246,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod
return result;
}
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
- int result = default_vfs_ops.fchmod(fsp, fd, mode);
+ int result;
- syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
+ result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
+
+ syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
fsp->fsp_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -253,16 +260,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
return result;
}
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
int result;
- if ( !default_vfs_ops.fchmod_acl )
- return 0;
-
- result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
+ result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
- syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
fsp->fsp_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -272,5 +276,5 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
NTSTATUS vfs_audit_init(void)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_init);
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_op_tuples);
}
diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c
index ef30ca70272..e677552eeae 100644
--- a/source/modules/vfs_extd_audit.c
+++ b/source/modules/vfs_extd_audit.c
@@ -5,6 +5,7 @@
* Copyright (C) Tim Potter, 1999-2000
* Copyright (C) Alexander Bokovoy, 2002
* Copyright (C) John H Terpstra, 2003
+ * Copyright (C) Stefan (metze) Metzmacher, 2003
*
* 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
@@ -21,127 +22,120 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#include <syslog.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
-
-#ifndef SYSLOG_FACILITY
-#define SYSLOG_FACILITY LOG_USER
-#endif
-
-#ifndef SYSLOG_PRIORITY
-#define SYSLOG_PRIORITY LOG_NOTICE
-#endif
+
+#include "includes.h"
+
+static int vfs_extd_audit_debug_level = DBGC_VFS;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS vfs_extd_audit_debug_level
/* Function prototypes */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(struct connection_struct *conn);
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname);
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(struct connection_struct *conn, const char *path);
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(struct files_struct *fsp, int fd);
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new);
-static int audit_unlink(struct connection_struct *conn, const char *path);
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
+static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
+static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
+static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname);
+static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
+static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
+static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
+static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
+static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new);
+static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
+static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
+static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
+static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
+static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *audit_handle;
-
-static vfs_op_tuple audit_ops[] = {
+static vfs_op_tuple audit_op_tuples[] = {
/* Disk operations */
- {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
/* Directory operations */
- {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
/* File operations */
- {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
/* Finish VFS operations definition */
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+static int audit_syslog_facility(vfs_handle_struct *handle)
{
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- audit_handle = vfs_handle;
+ /* fix me: let this be configurable by:
+ * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog facility",
+ * audit_enum_facility,LOG_USER);
+ */
+ return LOG_USER;
+}
- openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
- syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
- return audit_ops;
+static int audit_syslog_priority(vfs_handle_struct *handle)
+{
+ /* fix me: let this be configurable by:
+ * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog priority",
+ * audit_enum_priority,LOG_NOTICE);
+ */
+ return LOG_NOTICE;
}
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
+static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
{
- syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n",
+ int result;
+
+ openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
+
+ syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
svc, user);
DEBUG(10, ("Connected to service %s as user %s\n",
svc, user));
- return default_vfs_ops.connect(conn, svc, user);
+ result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
+
+ return result;
}
-static void audit_disconnect(struct connection_struct *conn)
+static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
{
- syslog(SYSLOG_PRIORITY, "disconnected\n");
+ syslog(audit_syslog_priority(handle), "disconnected\n");
DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
+ SMB_VFS_NEXT_DISCONNECT(handle, conn);
- default_vfs_ops.disconnect(conn);
+ return;
}
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
+static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
{
- DIR *result = default_vfs_ops.opendir(conn, fname);
+ DIR *result;
+
+ result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
- syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
fname,
(result == NULL) ? "failed: " : "",
(result == NULL) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: opendir %s %s %s",
+ DEBUG(1, ("vfs_extd_audit: opendir %s %s %s\n",
fname,
(result == NULL) ? "failed: " : "",
(result == NULL) ? strerror(errno) : ""));
@@ -149,11 +143,13 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
return result;
}
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
- int result = default_vfs_ops.mkdir(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n",
+ int result;
+
+ result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
+
+ syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -165,11 +161,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_rmdir(struct connection_struct *conn, const char *path)
+static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
- int result = default_vfs_ops.rmdir(conn, path);
+ int result;
+
+ result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
- syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -181,11 +179,13 @@ static int audit_rmdir(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
{
- int result = default_vfs_ops.open(conn, fname, flags, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
- syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n",
+ syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
fname, result,
((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
(result < 0) ? "failed: " : "",
@@ -198,11 +198,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla
return result;
}
-static int audit_close(struct files_struct *fsp, int fd)
+static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
{
- int result = default_vfs_ops.close(fsp, fd);
+ int result;
+
+ result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
- syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
+ syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
fd,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -214,11 +216,13 @@ static int audit_close(struct files_struct *fsp, int fd)
return result;
}
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new)
+static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
{
- int result = default_vfs_ops.rename(conn, old, new);
+ int result;
+
+ result = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
- syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
old, new,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -230,11 +234,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c
return result;
}
-static int audit_unlink(struct connection_struct *conn, const char *path)
+static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
- int result = default_vfs_ops.unlink(conn, path);
+ int result;
+
+ result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
- syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
+ syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -246,11 +252,13 @@ static int audit_unlink(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
- int result = default_vfs_ops.chmod(conn, path, mode);
+ int result;
- syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
+ result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
+
+ syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
path, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -262,11 +270,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
- int result = default_vfs_ops.chmod_acl(conn, path, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
- syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
path, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -278,11 +288,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod
return result;
}
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
- int result = default_vfs_ops.fchmod(fsp, fd, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
- syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
fsp->fsp_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -294,11 +306,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
return result;
}
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
- int result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
+ int result;
+
+ result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
- syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
+ syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
fsp->fsp_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -312,5 +326,18 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
NTSTATUS vfs_extd_audit_init(void)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_init);
+ NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples);
+
+ if (NT_STATUS_IS_ERR(ret))
+ return ret;
+
+ vfs_extd_audit_debug_level = debug_add_class("extd_audit");
+ if (vfs_extd_audit_debug_level == -1) {
+ vfs_extd_audit_debug_level = DBGC_VFS;
+ DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n"));
+ } else {
+ DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level));
+ }
+
+ return ret;
}
diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c
index 3a18fbb730c..740218dcd41 100644
--- a/source/modules/vfs_fake_perms.c
+++ b/source/modules/vfs_fake_perms.c
@@ -22,31 +22,16 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include "includes.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
-#include <includes.h>
-#include <vfs.h>
-
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *fake_perms_handle; /* use fake_perms_handle->data for storing per-instance private data */
-
-static int fake_perms_stat(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
{
- int ret = default_vfs_ops.stat(conn, fname, sbuf);
+ int ret = -1;
+
+ ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
if (ret == 0) {
extern struct current_user current_user;
@@ -58,12 +43,15 @@ static int fake_perms_stat(struct connection_struct *conn, const char *fname, SM
sbuf->st_uid = current_user.uid;
sbuf->st_gid = current_user.gid;
}
+
return ret;
}
-static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
{
- int ret = default_vfs_ops.fstat(fsp, fd, sbuf);
+ int ret = -1;
+
+ ret = SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf);
if (ret == 0) {
extern struct current_user current_user;
@@ -78,210 +66,16 @@ static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *s
return ret;
}
-#if 0
-static size_t fake_perms_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc)
-{
- return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc);
-}
-
-static size_t fake_perms_get_nt_acl(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc)
-{
- return default_vfs_ops.get_nt_acl(fsp, name, ppdesc);
-}
-
-static BOOL fake_perms_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return default_vfs_ops.fset_nt_acl(fsp, fd, security_info_sent, psd);
-}
-
-static BOOL fake_perms_set_nt_acl(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return default_vfs_ops.set_nt_acl(fsp, name, security_info_sent, psd);
-}
-
-static BOOL fake_perms_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode)
-{
- return default_vfs_ops.chmod_acl(conn, name, mode);
-}
-
-static BOOL fake_perms_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
-{
- return default_vfs_ops.fchmod_acl(fsp, fd, mode);
-}
-
-static int fake_perms_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
-{
- return default_vfs_ops.sys_acl_get_entry(conn, theacl, entry_id, entry_p);
-}
-
-static int fake_perms_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
-{
- return default_vfs_ops.sys_acl_get_tag_type(conn, entry_d, tag_type_p);
-}
-
-static int fake_perms_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
-{
- return default_vfs_ops.sys_acl_get_permset(conn, entry_d, permset_p);
-}
-
-static void *fake_perms_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
-{
- return default_vfs_ops.sys_acl_get_qualifier(conn, entry_d);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- return default_vfs_ops.sys_acl_get_file(conn, path_p, type);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_get_fd(struct files_struct *fsp, int fd)
-{
- return default_vfs_ops.sys_acl_get_fd(fsp, fd);
-}
-
-static int fake_perms_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset)
-{
- return default_vfs_ops.sys_acl_clear_perms(conn, permset);
-}
-
-static int fake_perms_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return default_vfs_ops.sys_acl_add_perm(conn, permset, perm);
-}
-
-static char *fake_perms_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
-{
- return default_vfs_ops.sys_acl_to_text(conn, theacl, plen);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_init(struct connection_struct *conn, int count)
-{
- return default_vfs_ops.sys_acl_init(conn, count);
-}
-
-static int fake_perms_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
-{
- return default_vfs_ops.sys_acl_create_entry(conn, pacl, pentry);
-}
-
-static int fake_perms_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
-{
- return default_vfs_ops.sys_acl_set_tag_type(conn, entry, tagtype);
-}
-
-static int fake_perms_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
-{
- return default_vfs_ops.sys_acl_set_qualifier(conn, entry, qual);
-}
-
-static int fake_perms_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
-{
- return default_vfs_ops.sys_acl_set_permset(conn, entry, permset);
-}
-
-static int fake_perms_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl )
-{
- return default_vfs_ops.sys_acl_valid(conn, theacl );
-}
-
-static int fake_perms_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- return default_vfs_ops.sys_acl_set_file(conn, name, acltype, theacl);
-}
-
-static int fake_perms_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
-{
- return default_vfs_ops.sys_acl_set_fd(fsp, fd, theacl);
-}
-
-static int fake_perms_sys_acl_delete_def_file(struct connection_struct *conn, const char *path)
-{
- return default_vfs_ops.sys_acl_delete_def_file(conn, path);
-}
-
-static int fake_perms_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return default_vfs_ops.sys_acl_get_perm(conn, permset, perm);
-}
-
-static int fake_perms_sys_acl_free_text(struct connection_struct *conn, char *text)
-{
- return default_vfs_ops.sys_acl_free_text(conn, text);
-}
-
-static int fake_perms_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl)
-{
- return default_vfs_ops.sys_acl_free_acl(conn, posix_acl);
-}
-
-static int fake_perms_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
-{
- return default_vfs_ops.sys_acl_free_qualifier(conn, qualifier, tagtype);
-}
-#endif
-
/* VFS operations structure */
-static vfs_op_tuple fake_perms_ops[] = {
-
- /* NT File ACL operations */
-#if 0
- {fake_perms_fget_nt_acl, SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_get_nt_acl, SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fset_nt_acl, SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_set_nt_acl, SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
+static vfs_op_tuple fake_perms_ops[] = {
+ {SMB_VFS_OP(fake_perms_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(fake_perms_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {fake_perms_sys_acl_get_entry, SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_tag_type, SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_permset, SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_qualifier, SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_file, SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_fd, SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_clear_perms, SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_add_perm, SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_to_text, SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_init, SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_create_entry, SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_tag_type, SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_qualifier, SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_permset, SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_valid, SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_file, SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_fd, SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_delete_def_file, SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_perm, SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_text, SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_acl, SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_qualifier, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
-#endif
-
- {fake_perms_stat, SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fstat, SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */
-
-static vfs_op_tuple *fake_perms_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- DEBUG(3, ("Initialising default vfs hooks\n"));
-
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- /* Remember vfs_handle for further allocation and referencing of private
- information in vfs_handle->data
- */
- fake_perms_handle = vfs_handle;
- return fake_perms_ops;
-}
-
NTSTATUS vfs_fake_perms_init(void)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_init);
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_ops);
}
diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c
index 718bc2a35ca..ae6286e292d 100644
--- a/source/modules/vfs_netatalk.c
+++ b/source/modules/vfs_netatalk.c
@@ -2,6 +2,7 @@
* AppleTalk VFS module for Samba-3.x
*
* Copyright (C) Alexei Kotovich, 2002
+ * Copyright (C) Stefan (metze) Metzmacher, 2003
*
* 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
@@ -18,22 +19,10 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
#define APPLEDOUBLE ".AppleDouble"
#define ADOUBLEMODE 0777
@@ -46,9 +35,6 @@ static int atalk_build_paths(TALLOC_CTX *ctx, const char *path,
static int atalk_unlink_file(const char *path);
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *atalk_handle;
-
static int atalk_get_path_ptr(char *path)
{
int i = 0;
@@ -187,11 +173,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
/* Directory operations */
-DIR *atalk_opendir(struct connection_struct *conn, const char *fname)
+DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname)
{
DIR *ret = 0;
-
- ret = default_vfs_ops.opendir(conn, fname);
+
+ ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
/*
* when we try to perform delete operation upon file which has fork
@@ -208,7 +194,7 @@ DIR *atalk_opendir(struct connection_struct *conn, const char *fname)
return ret;
}
-static int atalk_rmdir(struct connection_struct *conn, const char *path)
+static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
{
BOOL add = False;
TALLOC_CTX *ctx = 0;
@@ -233,12 +219,12 @@ static int atalk_rmdir(struct connection_struct *conn, const char *path)
exit_rmdir:
talloc_destroy(ctx);
- return default_vfs_ops.rmdir(conn, path);
+ return SMB_VFS_NEXT_RMDIR(handle, conn, path);
}
/* File operations */
-static int atalk_rename(struct connection_struct *conn, const char *old, const char *new)
+static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new)
{
int ret = 0;
char *adbl_path = 0;
@@ -247,7 +233,7 @@ static int atalk_rename(struct connection_struct *conn, const char *old, const c
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.rename(conn, old, new);
+ ret = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
if (!conn || !old) return ret;
@@ -270,7 +256,7 @@ exit_rename:
return ret;
}
-static int atalk_unlink(struct connection_struct *conn, const char *path)
+static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
{
int ret = 0, i;
char *adbl_path = 0;
@@ -279,7 +265,7 @@ static int atalk_unlink(struct connection_struct *conn, const char *path)
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.unlink(conn, path);
+ ret = SMB_VFS_NEXT_UNLINK(handle, conn, path);
if (!conn || !path) return ret;
@@ -326,7 +312,7 @@ exit_unlink:
return ret;
}
-static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode)
{
int ret = 0;
char *adbl_path = 0;
@@ -335,7 +321,7 @@ static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.chmod(conn, path, mode);
+ ret = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
if (!conn || !path) return ret;
@@ -358,7 +344,7 @@ exit_chmod:
return ret;
}
-static int atalk_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
{
int ret = 0;
char *adbl_path = 0;
@@ -367,7 +353,7 @@ static int atalk_chown(struct connection_struct *conn, const char *path, uid_t u
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.chown(conn, path, uid, gid);
+ ret = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid);
if (!conn || !path) return ret;
@@ -394,34 +380,22 @@ static vfs_op_tuple atalk_ops[] = {
/* Directory operations */
- {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
/* File operations */
- {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
/* Finish VFS operations definition */
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-static vfs_op_tuple *netatalk_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- atalk_handle = vfs_handle;
-
- DEBUG(3, ("ATALK: vfs module loaded\n"));
- return atalk_ops;
-}
-
NTSTATUS vfs_netatalk_init(void)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", netatalk_init);
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", atalk_ops);
}
diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c
index 87dea944ac0..45c661edb7a 100644
--- a/source/modules/vfs_recycle.c
+++ b/source/modules/vfs_recycle.c
@@ -6,6 +6,7 @@
* Copyright (C) 2002, Alexander Bokovoy - cascaded VFS adoption,
* Copyright (C) 2002, Juergen Hasch - added some options.
* Copyright (C) 2002, Simo Sorce
+ * Copyright (C) 2002, Stefan (metze) Metzmacher
*
* 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
@@ -30,231 +31,133 @@ static int vfs_recycle_debug_level = DBGC_VFS;
#undef DBGC_CLASS
#define DBGC_CLASS vfs_recycle_debug_level
-
-static const char *delimiter = "|"; /* delimiter for options */
-
-/* One per connection */
-
-typedef struct recycle_bin_struct
-{
- TALLOC_CTX *mem_ctx;
- char *repository; /* name of the recycle bin directory */
- BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */
- BOOL versions; /* create versions of deleted files with identical name */
- BOOL touch; /* touch access date of deleted file */
- char *exclude; /* which files to exclude */
- char *exclude_dir; /* which directories to exclude */
- char *noversions; /* which files to exclude from versioning */
- SMB_OFF_T maxsize; /* maximum file size to be saved */
-} recycle_bin_struct;
-
-typedef struct recycle_bin_connections {
- int conn;
- recycle_bin_struct *data;
- struct recycle_bin_connections *next;
-} recycle_bin_connections;
-
-typedef struct recycle_bin_private_data {
- TALLOC_CTX *mem_ctx;
- recycle_bin_connections *conns;
-} recycle_bin_private_data;
-
-struct smb_vfs_handle_struct *recycle_bin_private_handle;
-
-/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-
-static int recycle_connect(struct connection_struct *conn, const char *service, const char *user);
-static void recycle_disconnect(struct connection_struct *conn);
-static int recycle_unlink(connection_struct *, const char *);
-
-#define VFS_OP(x) ((void *) x)
+
+static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user);
+static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn);
+static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name);
static vfs_op_tuple recycle_ops[] = {
/* Disk operations */
- {VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
/* File operations */
- {VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/**
- * VFS initialisation function.
- *
- * @retval initialised vfs_op_tuple array
- **/
-static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
{
- TALLOC_CTX *mem_ctx = NULL;
+ DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n",
+ service,user));
- DEBUG(10, ("Initializing VFS module recycle\n"));
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
- vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin");
- if (vfs_recycle_debug_level == -1) {
- vfs_recycle_debug_level = DBGC_VFS;
- DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n"));
- } else {
- DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level));
- }
-
- recycle_bin_private_handle = vfs_handle;
- if (!(mem_ctx = talloc_init("recycle bin data"))) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return NULL;
- }
+ return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+}
- recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data));
- if (recycle_bin_private_handle->data == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return NULL;
- }
- ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx;
- ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL;
+static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn)
+{
+ DEBUG(10,("recycle_disconnect() connect to service[%s].\n",
+ lp_servicename(SNUM(conn))));
- return recycle_ops;
+ SMB_VFS_NEXT_DISCONNECT(handle, conn);
}
-static int recycle_connect(struct connection_struct *conn, const char *service, const char *user)
+static const char *recycle_repository(vfs_handle_struct *handle)
{
- TALLOC_CTX *ctx = NULL;
- recycle_bin_struct *recbin;
- recycle_bin_connections *recconn;
- recycle_bin_connections *recconnbase;
- recycle_bin_private_data *recdata;
- const char *tmp_str;
+ const char *tmp_str = NULL;
+
- DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user));
+ tmp_str = lp_parm_const_string(SNUM(handle->conn), "recycle", "repository",".recycle");
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return -1;
- }
+ DEBUG(10, ("recycle: repository = %s\n", tmp_str));
+
+ return tmp_str;
+}
- if (!(ctx = talloc_init("recycle bin connection"))) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return -1;
- }
+static BOOL recycle_keep_dir_tree(vfs_handle_struct *handle)
+{
+ BOOL ret;
+
+ ret = lp_parm_bool(SNUM(handle->conn), "recycle", "keeptree", False);
- recbin = talloc_zero(ctx, sizeof(recycle_bin_struct));
- if (recbin == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return -1;
- }
- recbin->mem_ctx = ctx;
-
- /* parse configuration options */
- if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "repository", ".recycle")) != NULL) {
- recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str);
- ALLOC_CHECK(recbin->repository, error);
- trim_string(recbin->repository, "/", "/");
- DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository));
- } else {
- DEBUG(0,("recycle.bin: no repository found (fail) !\n"));
- goto error;
- }
+ DEBUG(10, ("recycle_bin: keeptree = %s\n", ret?"True":"False"));
- recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False);
- DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree));
+ return ret;
+}
+
+static BOOL recycle_versions(vfs_handle_struct *handle)
+{
+ BOOL ret;
+
+ ret = lp_parm_bool(SNUM(handle->conn), "recycle", "versions", False);
+
+ DEBUG(10, ("recycle: versions = %s\n", ret?"True":"False"));
- recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False);
- DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions));
+ return ret;
+}
+
+static BOOL recycle_touch(vfs_handle_struct *handle)
+{
+ BOOL ret;
+
+ ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch", False);
+
+ DEBUG(10, ("recycle: touch = %s\n", ret?"True":"False"));
- recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False);
- DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch));
+ return ret;
+}
- recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize" , 0);
- if (recbin->maxsize == 0) {
- recbin->maxsize = -1;
- DEBUG(5, ("recycle.bin: maxsize = -infinite-\n"));
- } else {
- DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize));
- }
+static const char **recycle_exclude(vfs_handle_struct *handle)
+{
+ const char **tmp_lp;
+
+ tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude", NULL);
- if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude", "")) != NULL) {
- recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->exclude, error);
- DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude));
- }
- if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir", "")) != NULL) {
- recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->exclude_dir, error);
- DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir));
- }
- if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "noversions", "")) != NULL) {
- recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->noversions, error);
- DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions));
- }
+ DEBUG(10, ("recycle: exclude = %s ...\n", tmp_lp?*tmp_lp:""));
+
+ return tmp_lp;
+}
- recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections));
- if (recconn == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- goto error;
- }
- recconn->conn = SNUM(conn);
- recconn->data = recbin;
- recconn->next = NULL;
- if (recdata->conns) {
- recconnbase = recdata->conns;
- while (recconnbase->next != NULL) recconnbase = recconnbase->next;
- recconnbase->next = recconn;
- } else {
- recdata->conns = recconn;
- }
- return default_vfs_ops.connect(conn, service, user);
+static const char **recycle_exclude_dir(vfs_handle_struct *handle)
+{
+ const char **tmp_lp;
+
+ tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude_dir", NULL);
-error:
- talloc_destroy(ctx);
- return -1;
+ DEBUG(10, ("recycle: exclude_dir = %s ...\n", tmp_lp?*tmp_lp:""));
+
+ return tmp_lp;
}
-static void recycle_disconnect(struct connection_struct *conn)
+static const char **recycle_noversions(vfs_handle_struct *handle)
{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
+ const char **tmp_lp;
+
+ tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "noversions", NULL);
- DEBUG(10, ("Disconnecting VFS module recycle bin\n"));
+ DEBUG(10, ("recycle: noversions = %s\n", tmp_lp?*tmp_lp:""));
+
+ return tmp_lp;
+}
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return;
- }
+static int recycle_maxsize(vfs_handle_struct *handle)
+{
+ int maxsize;
+
+ maxsize = lp_parm_int(SNUM(handle->conn), "recycle", "maxsize", -1);
- if (recdata) {
- if (recdata->conns) {
- if (recdata->conns->conn == SNUM(conn)) {
- talloc_destroy(recdata->conns->data->mem_ctx);
- recdata->conns = recdata->conns->next;
- } else {
- recconn = recdata->conns;
- while (recconn->next) {
- if (recconn->next->conn == SNUM(conn)) {
- talloc_destroy(recconn->next->data->mem_ctx);
- recconn->next = recconn->next->next;
- break;
- }
- recconn = recconn->next;
- }
- }
- }
- }
- default_vfs_ops.disconnect(conn);
+ DEBUG(10, ("recycle: maxsize = %d\n", maxsize));
+
+ return maxsize;
}
-static BOOL recycle_directory_exist(connection_struct *conn, const char *dname)
+static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname)
{
SMB_STRUCT_STAT st;
- if (default_vfs_ops.stat(conn, dname, &st) == 0) {
+ if (SMB_VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
return True;
}
@@ -263,11 +166,11 @@ static BOOL recycle_directory_exist(connection_struct *conn, const char *dname)
return False;
}
-static BOOL recycle_file_exist(connection_struct *conn, const char *fname)
+static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname)
{
SMB_STRUCT_STAT st;
- if (default_vfs_ops.stat(conn, fname, &st) == 0) {
+ if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) {
if (S_ISREG(st.st_mode)) {
return True;
}
@@ -282,13 +185,15 @@ static BOOL recycle_file_exist(connection_struct *conn, const char *fname)
* @param fname file name
* @return size in bytes
**/
-static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname)
+static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fname)
{
SMB_STRUCT_STAT st;
- if (default_vfs_ops.stat(conn, fname, &st) != 0) {
- DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno)));
+
+ if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
+ DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
return (SMB_OFF_T)0;
}
+
return(st.st_size);
}
@@ -298,7 +203,7 @@ static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fnam
* @param dname Directory tree to be created
* @return Returns True for success
**/
-static BOOL recycle_create_dir(connection_struct *conn, const char *dname)
+static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname)
{
int len;
mode_t mode;
@@ -322,18 +227,18 @@ static BOOL recycle_create_dir(connection_struct *conn, const char *dname)
/* Create directory tree if neccessary */
for(token = strtok(tok_str, "/"); token; token = strtok(NULL, "/")) {
safe_strcat(new_dir, token, len);
- if (recycle_directory_exist(conn, new_dir))
- DEBUG(10, ("recycle.bin: dir %s already exists\n", new_dir));
+ if (recycle_directory_exist(handle, new_dir))
+ DEBUG(10, ("recycle: dir %s already exists\n", new_dir));
else {
- DEBUG(5, ("recycle.bin: creating new dir %s\n", new_dir));
- if (default_vfs_ops.mkdir(conn, new_dir, mode) != 0) {
- DEBUG(1,("recycle.bin: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
+ DEBUG(5, ("recycle: creating new dir %s\n", new_dir));
+ if (SMB_VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) {
+ DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
ret = False;
goto done;
}
}
safe_strcat(new_dir, "/", len);
- }
+ }
ret = True;
done:
@@ -348,30 +253,22 @@ done:
* @param needle string to be matched exactly to haystack
* @return True if found
**/
-static BOOL checkparam(const char *haystack, const char *needle)
+static BOOL checkparam(const char **haystack_list, const char *needle)
{
- char *token;
- char *tok_str;
- char *tmp_str;
- BOOL ret = False;
+ int i;
- if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) {
+ if (haystack_list == NULL || haystack_list[0] == NULL ||
+ *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') {
return False;
}
- tmp_str = strdup(haystack);
- ALLOC_CHECK(tmp_str, done);
- token = tok_str = tmp_str;
-
- for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) {
- if(strcmp(token, needle) == 0) {
- ret = True;
- goto done;
+ for(i=0; haystack_list[i] ; i++) {
+ if(strequal(haystack_list[i], needle)) {
+ return True;
}
}
-done:
- SAFE_FREE(tmp_str);
- return ret;
+
+ return False;
}
/**
@@ -380,110 +277,87 @@ done:
* @param needle string to be matched exectly to haystack including pattern matching
* @return True if found
**/
-static BOOL matchparam(const char *haystack, const char *needle)
+static BOOL matchparam(const char **haystack_list, const char *needle)
{
- char *token;
- char *tok_str;
- char *tmp_str;
- BOOL ret = False;
+ int i;
- if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) {
+ if (haystack_list == NULL || haystack_list[0] == NULL ||
+ *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') {
return False;
}
- tmp_str = strdup(haystack);
- ALLOC_CHECK(tmp_str, done);
- token = tok_str = tmp_str;
-
- for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) {
- if (!unix_wild_match(token, needle)) {
- ret = True;
- goto done;
+ for(i=0; haystack_list[i] ; i++) {
+ if(!unix_wild_match((char *)haystack_list[i], (char *)needle)) {
+ return True;
}
}
-done:
- SAFE_FREE(tmp_str);
- return ret;
+
+ return False;
}
/**
* Touch access date
**/
-static void recycle_touch(connection_struct *conn, const char *fname)
+static void recycle_do_touch(vfs_handle_struct *handle, const char *fname)
{
SMB_STRUCT_STAT st;
struct utimbuf tb;
time_t currtime;
-
- if (default_vfs_ops.stat(conn, fname, &st) != 0) {
- DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno)));
+
+ if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
+ DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
return;
}
currtime = time(&currtime);
tb.actime = currtime;
tb.modtime = st.st_mtime;
- if (default_vfs_ops.utime(conn, fname, &tb) == -1 )
- DEBUG(0, ("recycle.bin: touching %s failed, reason = %s\n", fname, strerror(errno)));
+ if (SMB_VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) {
+ DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno)));
}
+}
/**
* Check if file should be recycled
**/
-static int recycle_unlink(connection_struct *conn, const char *file_name)
+static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name)
{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
- recycle_bin_struct *recbin;
char *path_name = NULL;
char *temp_name = NULL;
char *final_name = NULL;
const char *base;
- int i;
-/* SMB_BIG_UINT dfree, dsize, bsize; */
+ char *repository = NULL;
+ int i = 1;
+ int maxsize;
SMB_OFF_T file_size; /* space_avail; */
BOOL exist;
int rc = -1;
- recbin = NULL;
- if (recycle_bin_private_handle) {
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- if (recdata) {
- if (recdata->conns) {
- recconn = recdata->conns;
- while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next;
- if (recconn != NULL) {
- recbin = recconn->data;
- }
- }
- }
- }
- if (recbin == NULL) {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- if(!recbin->repository || *(recbin->repository) == '\0') {
- DEBUG(3, ("Recycle path not set, purging %s...\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ repository = alloc_sub_conn(conn, (char *)recycle_repository(handle));
+ ALLOC_CHECK(repository, done);
+ /* shouldn't we allow absolute path names here? --metze */
+ trim_string(repository, "/", "/");
+
+ if(!repository || *(repository) == '\0') {
+ DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
/* we don't recycle the recycle bin... */
- if (strncmp(file_name, recbin->repository, strlen(recbin->repository)) == 0) {
- DEBUG(3, ("File is within recycling bin, unlinking ...\n"));
- rc = default_vfs_ops.unlink(conn, file_name);
+ if (strncmp(file_name, repository, strlen(repository)) == 0) {
+ DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n"));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
- file_size = recycle_get_file_size(conn, file_name);
+ file_size = recycle_get_file_size(handle, file_name);
/* it is wrong to purge filenames only because they are empty imho
* --- simo
*
if(fsize == 0) {
- DEBUG(3, ("File %s is empty, purging...\n", file_name));
- rc = default_vfs_ops.unlink(conn,file_name);
+ DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name);
goto done;
}
*/
@@ -492,20 +366,21 @@ static int recycle_unlink(connection_struct *conn, const char *file_name)
* not greater then maxsize, not the size of the single file, also it is better
* to remove older files
*/
- if(recbin->maxsize > 0 && file_size > recbin->maxsize) {
- DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ maxsize = recycle_maxsize(handle);
+ if(maxsize > 0 && file_size > maxsize) {
+ DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
/* FIXME: this is wrong: moving files with rename does not change the disk space
* allocation
*
- space_avail = default_vfs_ops.disk_free(conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
+ space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
if(space_avail < file_size) {
- DEBUG(3, ("Not enough diskspace, purging file %s\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
*/
@@ -524,13 +399,13 @@ static int recycle_unlink(connection_struct *conn, const char *file_name)
base++;
}
- DEBUG(10, ("recycle.bin: fname = %s\n", file_name)); /* original filename with path */
- DEBUG(10, ("recycle.bin: fpath = %s\n", path_name)); /* original path */
- DEBUG(10, ("recycle.bin: base = %s\n", base)); /* filename without path */
+ DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */
+ DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */
+ DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */
- if (matchparam(recbin->exclude, base)) {
- DEBUG(3, ("recycle.bin: file %s is excluded \n", base));
- rc = default_vfs_ops.unlink(conn, file_name);
+ if (matchparam(recycle_exclude(handle), base)) {
+ DEBUG(3, ("recycle: file %s is excluded \n", base));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
@@ -538,72 +413,85 @@ static int recycle_unlink(connection_struct *conn, const char *file_name)
* we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 ....
* ---simo
*/
- if (checkparam(recbin->exclude_dir, path_name)) {
- DEBUG(3, ("recycle.bin: directory %s is excluded \n", path_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ if (checkparam(recycle_exclude_dir(handle), path_name)) {
+ DEBUG(3, ("recycle: directory %s is excluded \n", path_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
- /* see if we need to recreate the original directory structure in the recycle bin */
- if (recbin->keep_dir_tree == True) {
- asprintf(&temp_name, "%s/%s", recbin->repository, path_name);
+ if (recycle_keep_dir_tree(handle) == True) {
+ asprintf(&temp_name, "%s/%s", repository, path_name);
} else {
- temp_name = strdup(recbin->repository);
+ temp_name = strdup(repository);
}
ALLOC_CHECK(temp_name, done);
- exist = recycle_directory_exist(conn, temp_name);
+ exist = recycle_directory_exist(handle, temp_name);
if (exist) {
- DEBUG(10, ("recycle.bin: Directory already exists\n"));
+ DEBUG(10, ("recycle: Directory already exists\n"));
} else {
- DEBUG(10, ("recycle.bin: Creating directory %s\n", temp_name));
- if (recycle_create_dir(conn, temp_name) == False) {
- DEBUG(3, ("Could not create directory, purging %s...\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ DEBUG(10, ("recycle: Creating directory %s\n", temp_name));
+ if (recycle_create_dir(handle, temp_name) == False) {
+ DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
}
asprintf(&final_name, "%s/%s", temp_name, base);
ALLOC_CHECK(final_name, done);
- DEBUG(10, ("recycle.bin: recycled file name: %s\n", temp_name)); /* new filename with path */
+ DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */
/* check if we should delete file from recycle bin */
- if (recycle_file_exist(conn, final_name)) {
- if (recbin->versions == False || matchparam(recbin->noversions, base) == True) {
- DEBUG(3, ("recycle.bin: Removing old file %s from recycle bin\n", final_name));
- if (default_vfs_ops.unlink(conn, final_name) != 0) {
- DEBUG(1, ("recycle.bin: Error deleting old file: %s\n", strerror(errno)));
+ if (recycle_file_exist(handle, final_name)) {
+ if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) {
+ DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name));
+ if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) {
+ DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno)));
}
}
}
/* rename file we move to recycle bin */
i = 1;
- while (recycle_file_exist(conn, final_name)) {
- snprintf(final_name, PATH_MAX, "%s/Copy #%d of %s", temp_name, i++, base);
+ while (recycle_file_exist(handle, final_name)) {
+ snprintf(final_name, PATH_MAX -1, "%s/Copy #%d of %s", temp_name, i++, base);
}
- DEBUG(10, ("recycle.bin: Moving %s to %s\n", file_name, final_name));
- rc = default_vfs_ops.rename(conn, file_name, final_name);
+ DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name));
+ rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name);
if (rc != 0) {
- DEBUG(3, ("recycle.bin: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
- rc = default_vfs_ops.unlink(conn, file_name);
+ DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
+ rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
goto done;
}
/* touch access date of moved file */
- if (recbin->touch == True )
- recycle_touch(conn, final_name);
+ if (recycle_touch(handle) == True )
+ recycle_do_touch(handle, final_name);
done:
SAFE_FREE(path_name);
SAFE_FREE(temp_name);
SAFE_FREE(final_name);
+ SAFE_FREE(repository);
return rc;
}
NTSTATUS vfs_recycle_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_init);
+{
+ NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops);
+
+ if (NT_STATUS_IS_ERR(ret))
+ return ret;
+
+ vfs_recycle_debug_level = debug_add_class("recycle");
+ if (vfs_recycle_debug_level == -1) {
+ vfs_recycle_debug_level = DBGC_VFS;
+ DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n"));
+ } else {
+ DEBUG(10, ("vfs_recycle: Debug class number of 'recycle': %d\n", vfs_recycle_debug_level));
+ }
+
+ return ret;
}
diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c
index 69a315d4e40..d4ec0b830fd 100644
--- a/source/msdfs/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -169,14 +169,14 @@ BOOL is_msdfs_link(connection_struct* conn, char* path,
if (sbufp == NULL)
sbufp = &st;
- if (conn->vfs_ops.lstat(conn, path, sbufp) != 0) {
+ if (SMB_VFS_LSTAT(conn, path, sbufp) != 0) {
DEBUG(5,("is_msdfs_link: %s does not exist.\n",path));
return False;
}
if (S_ISLNK(sbufp->st_mode)) {
/* open the link and read it */
- referral_len = conn->vfs_ops.readlink(conn, path, referral,
+ referral_len = SMB_VFS_READLINK(conn, path, referral,
sizeof(pstring));
if (referral_len == -1) {
DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", path, strerror(errno)));
@@ -785,10 +785,10 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link));
if(exists)
- if(conn->vfs_ops.unlink(conn,path)!=0)
+ if(SMB_VFS_UNLINK(conn,path)!=0)
return False;
- if(conn->vfs_ops.symlink(conn, msdfs_link, path) < 0) {
+ if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n",
path, msdfs_link, strerror(errno)));
return False;
@@ -805,7 +805,7 @@ BOOL remove_msdfs_link(struct junction_map* jn)
if(!junction_to_local_path(jn, path, sizeof(path), conn))
return False;
- if(conn->vfs_ops.unlink(conn, path)!=0)
+ if(SMB_VFS_UNLINK(conn, path)!=0)
return False;
return True;
@@ -862,7 +862,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
cnt++;
/* Now enumerate all dfs links */
- dirp = conn->vfs_ops.opendir(conn, connect_path);
+ dirp = SMB_VFS_OPENDIR(conn, connect_path);
if(!dirp)
return False;
@@ -881,7 +881,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
}
}
- conn->vfs_ops.closedir(conn,dirp);
+ SMB_VFS_CLOSEDIR(conn,dirp);
*jn_count = cnt;
return True;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index ad5ab4d734d..d9300f4668f 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -573,8 +573,10 @@ static BOOL open_sockets(BOOL isdaemon, int port)
**************************************************************************** */
int main(int argc, const char *argv[])
{
- static BOOL opt_interactive = False;
+ pstring logfile;
+ static BOOL opt_interactive;
poptContext pc;
+ int opt;
struct poptOption long_options[] = {
POPT_AUTOHELP
{"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
@@ -586,46 +588,47 @@ static BOOL open_sockets(BOOL isdaemon, int port)
POPT_COMMON_SAMBA
{ NULL }
};
- pstring logfile;
-
- global_nmb_port = NMB_PORT;
- global_in_nmbd = True;
-
- StartupTime = time(NULL);
-
- sys_srandom(time(NULL) ^ sys_getpid());
- slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
+ global_nmb_port = NMB_PORT;
- fault_setup((void (*)(void *))fault_continue );
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't receive them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
- BlockSignals(False, SIGTERM);
-
- CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
- CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
+ pc = poptGetContext("nmbd", argc, argv, long_options, 0);
+ while ((opt = poptGetNextOpt(pc)) != -1) ;
+ poptFreeContext(pc);
+ global_in_nmbd = True;
+
+ StartupTime = time(NULL);
+
+ sys_srandom(time(NULL) ^ sys_getpid());
+
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
+ lp_set_logfile(logfile);
+
+ fault_setup((void (*)(void *))fault_continue );
+
+ /* POSIX demands that signals are inherited. If the invoking process has
+ * these signals masked, we will have problems, as we won't receive them. */
+ BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGUSR1);
+ BlockSignals(False, SIGTERM);
+
+ CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
+ CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
+
#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
+ /* we are never interested in SIGFPE */
+ BlockSignals(True,SIGFPE);
#endif
- /* We no longer use USR2... */
+ /* We no longer use USR2... */
#if defined(SIGUSR2)
- BlockSignals(True, SIGUSR2);
+ BlockSignals(True, SIGUSR2);
#endif
- pc = poptGetContext("nmbd", argc, argv, long_options, 0);
-
- poptFreeContext(pc);
- if ( opt_interactive ) {
- Fork = False;
- log_stdout = True;
- }
+ if ( opt_interactive ) {
+ Fork = False;
+ log_stdout = True;
+ }
if ( log_stdout && Fork ) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
diff --git a/source/nmbd/nmbd_become_lmb.c b/source/nmbd/nmbd_become_lmb.c
index 6f8e7efb1ae..d390bf72e95 100644
--- a/source/nmbd/nmbd_become_lmb.c
+++ b/source/nmbd/nmbd_become_lmb.c
@@ -600,6 +600,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n",
}
#endif
- StrnCpy(work->local_master_browser_name, newname,
- sizeof(work->local_master_browser_name)-1);
+ fstrcpy(work->local_master_browser_name, newname);
}
diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c
index a4ef98e265e..d7c852605e2 100644
--- a/source/nmbd/nmbd_browserdb.c
+++ b/source/nmbd/nmbd_browserdb.c
@@ -107,8 +107,8 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
/* Allow the new lmb to miss an announce period before we remove it. */
browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
- StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 );
- StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 );
+ pstrcpy( browc->lmb_name, browser_name);
+ pstrcpy( browc->work_group, work_name);
strupper( browc->lmb_name );
strupper( browc->work_group );
diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c
index adfefc9f27a..381f65e0c85 100644
--- a/source/nmbd/nmbd_browsesync.c
+++ b/source/nmbd/nmbd_browsesync.c
@@ -106,6 +106,7 @@ As a local master browser, send an announce packet to the domain master browser.
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
{
pstring outbuf;
+ fstring myname;
char *p;
if(ismyip(work->dmb_addr))
@@ -125,8 +126,11 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
SCVAL(p,0,ANN_MasterAnnouncement);
p++;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
if( DEBUGLVL( 4 ) )
diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c
index cd6954fc62a..16fecbccd95 100644
--- a/source/nmbd/nmbd_incomingdgrams.c
+++ b/source/nmbd/nmbd_incomingdgrams.c
@@ -172,7 +172,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
}
else
@@ -343,7 +343,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl(servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
set_workgroup_local_master_browser_name( work, server_name );
@@ -520,7 +520,7 @@ originate from OS/2 Warp client. Ignoring packet.\n"));
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
}
else
@@ -559,6 +559,7 @@ static void send_backup_list_response(struct subnet_record *subrec,
#if 0
struct server_record *servrec;
#endif
+ fstring myname;
memset(outbuf,'\0',sizeof(outbuf));
@@ -578,8 +579,11 @@ static void send_backup_list_response(struct subnet_record *subrec,
/* We always return at least one name - our own. */
count = 1;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
/* Look for backup browsers in this workgroup. */
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index a702fc30156..42edcc871fa 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -304,19 +304,19 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
pstring hostname;
char *component, *dc, *q1;
uint8 size;
+ char *q_orig = q;
+ int str_offset;
get_mydomname(domain);
get_myname(hostname);
if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
+ SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
} else {
- SSVAL(q, 0, SAMLOGON_AD_R);
+ SIVAL(q, 0, SAMLOGON_AD_R);
}
- q += 2;
+ q += 4;
- SSVAL(q, 0, 0);
- q += 2;
SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
q += 4;
@@ -329,7 +329,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
memcpy(q, &domain_guid, sizeof(domain_guid));
q += sizeof(domain_guid);
- /* Push domain components */
+ /* Forest */
+ str_offset = q - q_orig;
dc = domain;
q1 = q;
while ((component = strtok(dc, "."))) {
@@ -338,44 +339,60 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
SCVAL(q, 0, size);
q += (size + 1);
}
+
+ /* Unk0 */
SCVAL(q, 0, 0); q++;
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
- /* Push dns host name */
+ /* Domain */
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
+
+ /* Hostname */
size = push_ascii(&q[1], hostname, -1, 0);
SCVAL(q, 0, size);
q += (size + 1);
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
- /* Push NETBIOS of domain */
+ /* NETBIOS of domain */
size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
SCVAL(q, 0, size);
q += (size + 1);
- SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
- /* null terminator would not be needed because size is included */
- /* Push NETBIOS of hostname */
+ /* Unk1 */
+ SCVAL(q, 0, 0); q++;
+
+ /* NETBIOS of hostname */
size = push_ascii(&q[1], my_name, -1, 0);
SCVAL(q, 0, size);
q += (size + 1);
- SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
- /* Push user account */
- size = push_ascii(&q[1], ascuser, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
+ /* Unk2 */
+ SCVAL(q, 0, 0); q++;
+
+ /* User name */
+ if (SVAL(uniuser, 0) != 0) {
+ size = push_ascii(&q[1], ascuser, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ }
- /* Push 'Default-First-Site-Name' */
+ q_orig = q;
+ /* Site name */
size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
SCVAL(q, 0, size);
q += (size + 1);
- SSVAL(q, 0, 0xc000); /* unknown */
- SCVAL(q, 2, PTR_DIFF(q,q1));
- SCVAL(q, 3, 0x10); /* unknown */
- q += 4;
+ /* Site name (2) */
+ str_offset = q - q_orig;
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
+
+ SCVAL(q, 0, PTR_DIFF(q,q1));
+ SCVAL(q, 1, 0x10); /* unknown */
SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
diff --git a/source/nmbd/nmbd_sendannounce.c b/source/nmbd/nmbd_sendannounce.c
index 40d07aae168..8501acf9ba5 100644
--- a/source/nmbd/nmbd_sendannounce.c
+++ b/source/nmbd/nmbd_sendannounce.c
@@ -555,6 +555,7 @@ void browse_sync_remote(time_t t)
struct work_record *work;
pstring outbuf;
char *p;
+ fstring myname;
if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
return;
@@ -589,8 +590,11 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
SCVAL(p,0,ANN_MasterAnnouncement);
p++;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
diff --git a/source/nmbd/nmbd_serverlistdb.c b/source/nmbd/nmbd_serverlistdb.c
index ee0c021d5dc..e99599e16fa 100644
--- a/source/nmbd/nmbd_serverlistdb.c
+++ b/source/nmbd/nmbd_serverlistdb.c
@@ -153,8 +153,8 @@ workgroup %s. This is a bug.\n", name, work->work_group));
servrec->subnet = work->subnet;
- StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.name,name);
+ fstrcpy(servrec->serv.comment,comment);
strupper(servrec->serv.name);
servrec->serv.type = servertype;
diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c
index 47ce8119f33..eafff03b767 100644
--- a/source/nmbd/nmbd_winsserver.c
+++ b/source/nmbd/nmbd_winsserver.c
@@ -22,7 +22,7 @@
#include "includes.h"
-#define WINS_LIST "wins.tdb"
+#define WINS_LIST "wins.dat"
#define WINS_VERSION 1
/****************************************************************************
@@ -221,123 +221,177 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
- time_t time_now = time(NULL);
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
- struct name_record *namerec = NULL;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+ time_t time_now = time(NULL);
+ XFILE *fp;
+ pstring line;
- DEBUG(2,("initialise_wins: started\n"));
+ if(!lp_we_are_a_wins_server())
+ return True;
- if(!lp_we_are_a_wins_server())
- return True;
+ add_samba_names_to_subnet(wins_server_subnet);
- add_samba_names_to_subnet(wins_server_subnet);
+ if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL)
+ {
+ DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
+ WINS_LIST, strerror(errno) ));
+ return True;
+ }
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return True;
- }
+ while (!x_feof(fp))
+ {
+ pstring name_str, ip_str, ttl_str, nb_flags_str;
+ unsigned int num_ips;
+ pstring name;
+ struct in_addr *ip_list;
+ int type = 0;
+ int nb_flags;
+ int ttl;
+ const char *ptr;
+ char *p;
+ BOOL got_token;
+ BOOL was_ip;
+ int i;
+ unsigned hash;
+ int version;
+
+ /* Read a line from the wins.dat file. Strips whitespace
+ from the beginning and end of the line.
+ */
+ if (!fgets_slash(line,sizeof(pstring),fp))
+ continue;
+
+ if (*line == '#')
+ continue;
+
+ if (strncmp(line,"VERSION ", 8) == 0) {
+ if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
+ version != WINS_VERSION) {
+ DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
+ x_fclose(fp);
+ return True;
+ }
+ continue;
+ }
- if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.tdb file\n"));
- tdb_close(tdb);
- return True;
- }
+ ptr = line;
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- fstring name_type;
- pstring name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int high, low;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len,i;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
+ /*
+ * Now we handle multiple IP addresses per name we need
+ * to iterate over the line twice. The first time to
+ * determine how many IP addresses there are, the second
+ * time to actually parse them into the ip_list array.
+ */
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
+ if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
+ {
+ DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
+ continue;
+ }
- pstrcpy(name, name_type);
+ if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
+ {
+ DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
+ continue;
+ }
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
+ /*
+ * Determine the number of IP addresses per line.
+ */
+ num_ips = 0;
+ do
+ {
+ got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
+ was_ip = False;
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags, &high, &low,
- ip_str, &ttl, &num_ips, &wins_flags);
+ if(got_token && strchr(ip_str, '.'))
+ {
+ num_ips++;
+ was_ip = True;
+ }
+ } while( got_token && was_ip);
- wins_ip=*interpret_addr2(ip_str);
+ if(num_ips == 0)
+ {
+ DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
+ continue;
+ }
- /* Don't reload replica records */
- if (!ip_equal(wins_ip, our_fake_ip)) {
- SAFE_FREE(dbuf.dptr);
- continue;
- }
+ if(!got_token)
+ {
+ DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
+ continue;
+ }
- /* Don't reload released or tombstoned records */
- if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE) {
- SAFE_FREE(dbuf.dptr);
- continue;
- }
+ /* Allocate the space for the ip_list. */
+ if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
+ {
+ DEBUG(0,("initialise_wins: Malloc fail !\n"));
+ return False;
+ }
+
+ /* Reset and re-parse the line. */
+ ptr = line;
+ next_token(&ptr,name_str,NULL,sizeof(name_str));
+ next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
+ for(i = 0; i < num_ips; i++)
+ {
+ next_token(&ptr, ip_str, NULL, sizeof(ip_str));
+ ip_list[i] = *interpret_addr2(ip_str);
+ }
+ next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
- }
+ /*
+ * Deal with SELF or REGISTER name encoding. Default is REGISTER
+ * for compatibility with old nmbds.
+ */
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
+ {
+ DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
+ SAFE_FREE(ip_list);
+ continue;
+ }
+
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
+ nb_flags_str[strlen(nb_flags_str)-1] = '\0';
+
+ /* Netbios name. # divides the name from the type (hex): netbios#xx */
+ pstrcpy(name,name_str);
+
+ if((p = strchr(name,'#')) != NULL)
+ {
+ *p = 0;
+ sscanf(p+1,"%x",&type);
+ }
+
+ /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
+ sscanf(nb_flags_str,"%x",&nb_flags);
+ sscanf(ttl_str,"%d",&ttl);
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
+ /* add all entries that have 60 seconds or more to live */
+ if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
+ {
+ if(ttl != PERMANENT_TTL)
+ ttl -= time_now;
- DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list);
- if (namerec!=NULL) {
- update_wins_owner(namerec, wins_ip);
- update_wins_flag(namerec, wins_flags);
- /* we don't reload the ID, on startup we restart at 1 */
- get_global_id_and_update(&namerec->data.id, True);
- }
+ DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- } else {
- DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
+ (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
+ ttl, REGISTER_NAME, num_ips, ip_list );
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(ip_list);
- }
+ }
+ else
+ {
+ DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+ }
+
+ SAFE_FREE(ip_list);
+ }
- tdb_close(tdb);
- DEBUG(2,("initialise_wins: done\n"));
- return True;
+ x_fclose(fp);
+ return True;
}
/****************************************************************************
@@ -1765,113 +1819,87 @@ we are not the wins owner !\n", nmb_namestr(&namerec->name)));
******************************************************************/
void wins_write_database(BOOL background)
{
- struct name_record *namerec;
- pstring fname, fnamenew;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf;
- pstring key, buf;
- int len;
- int num_record=0;
- SMB_BIG_UINT id;
-
- if(!lp_we_are_a_wins_server())
- return;
-
- /* we will do the writing in a child process to ensure that the parent
- doesn't block while this is done */
- if (background) {
- CatchChild();
- if (sys_fork()) {
- return;
- }
- }
-
- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
- tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
- if (!tdb) {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background)
- _exit(0);
- return;
- }
-
- DEBUG(3,("wins_write_database: Dump of WINS name list.\n"));
-
- tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION);
-
- for (namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) ) {
-
- int i;
- struct tm *tm;
-
- DEBUGADD(3,("%-19s ", nmb_namestr(&namerec->name) ));
+ struct name_record *namerec;
+ pstring fname, fnamenew;
- if( namerec->data.death_time != PERMANENT_TTL ) {
- char *ts, *nl;
-
- tm = LocalTime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr_m( ts, '\n' );
- if( NULL != nl )
- *nl = '\0';
+ XFILE *fp;
+
+ if(!lp_we_are_a_wins_server())
+ return;
- DEBUGADD(3,("TTL = %s ", ts ));
- } else
- DEBUGADD(3,("TTL = PERMANENT "));
+ /* we will do the writing in a child process to ensure that the parent
+ doesn't block while this is done */
+ if (background) {
+ CatchChild();
+ if (sys_fork()) {
+ return;
+ }
+ }
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
+ all_string_sub(fname,"//", "/", 0);
+ slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
- DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip)));
+ if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL)
+ {
+ DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
+ if (background) {
+ _exit(0);
+ }
+ return;
+ }
- if( namerec->data.source == REGISTER_NAME ) {
-
- /* store the type in the key to make the name unique */
- slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type);
-
- len = tdb_pack(buf, sizeof(buf), "dddfddd",
- (int)namerec->data.nb_flags,
- (int)(namerec->data.id>>32),
- (int)(namerec->data.id&0xffffffff),
- inet_ntoa(namerec->data.wins_ip),
- (int)namerec->data.death_time,
- namerec->data.num_ips,
- namerec->data.wins_flags);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i]));
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- dbuf.dsize = len;
- dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return;
+ DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
- num_record++;
- }
- }
+ x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
+
+ for( namerec
+ = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ int i;
+ struct tm *tm;
- /* store the number of records */
- tdb_store_int32(tdb, INFO_COUNT, num_record);
+ DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
- /* get and store the last used ID */
- get_global_id_and_update(&id, False);
- tdb_store_int32(tdb, INFO_ID_HIGH, id>>32);
- tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff);
+ if( namerec->data.death_time != PERMANENT_TTL )
+ {
+ char *ts, *nl;
+
+ tm = LocalTime(&namerec->data.death_time);
+ ts = asctime(tm);
+ nl = strrchr( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(4,("TTL = %s ", ts ));
+ }
+ else
+ DEBUGADD(4,("TTL = PERMANENT "));
- tdb_close(tdb);
+ for (i = 0; i < namerec->data.num_ips; i++)
+ DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
+ if( namerec->data.source == REGISTER_NAME )
+ {
+ x_fprintf(fp, "\"%s#%02x\" %d ",
+ namerec->name.name,namerec->name.name_type, /* Ignore scope. */
+ (int)namerec->data.death_time);
- if (background)
- _exit(0);
+ for (i = 0; i < namerec->data.num_ips; i++)
+ x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
+ x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
+ }
+ }
+
+ x_fclose(fp);
+ chmod(fnamenew,0644);
+ unlink(fname);
+ rename(fnamenew,fname);
+ if (background) {
+ _exit(0);
+ }
}
/****************************************************************************
diff --git a/source/nmbd/nmbd_workgroupdb.c b/source/nmbd/nmbd_workgroupdb.c
index b8ea60dec07..2357fd637b5 100644
--- a/source/nmbd/nmbd_workgroupdb.c
+++ b/source/nmbd/nmbd_workgroupdb.c
@@ -57,7 +57,7 @@ static struct work_record *create_workgroup(const char *name, int ttl)
}
memset((char *)work, '\0', sizeof(*work));
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
+ fstrcpy(work->work_group,name);
work->serverlist = NULL;
work->RunningElection = False;
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index 2d9a0b59499..987a58e502f 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -219,7 +219,7 @@ struct winbindd_idmap_methods {
void (*status)(void);
};
-#include "winbindd_proto.h"
+#include "../nsswitch/winbindd_proto.h"
#include "rpc_parse.h"
#include "rpc_client.h"
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index f3dc1263b9b..1b817592ae8 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -100,12 +100,12 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
ret = smb_xmalloc(sizeof(*ret));
ZERO_STRUCTP(ret);
-
+ switch (lp_security()) { /* winbind pdc disabled until ready
if (!strcmp(domain->name, lp_workgroup()) && (lp_security() == SEC_USER)) {
extern struct winbindd_methods passdb_methods;
ret->backend = &passdb_methods;
- } else switch (lp_security()) {
+ } else switch (lp_security()) { */
#ifdef HAVE_ADS
case SEC_ADS: {
extern struct winbindd_methods ads_methods;
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 02fd15e0691..2aa07afdfc4 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -246,65 +246,11 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
}
}
-/* Open a new smb pipe connection to a DC on a given domain. Cache
- negative creation attempts so we don't try and connect to broken
- machines too often. */
-
-#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
-
-struct failed_connection_cache {
- fstring domain_name;
- fstring controller;
- time_t lookup_time;
- NTSTATUS nt_status;
- struct failed_connection_cache *prev, *next;
-};
-
-static struct failed_connection_cache *failed_connection_cache;
-
-/* Add an entry to the failed conneciton cache */
-
-static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn,
- NTSTATUS result)
-{
- struct failed_connection_cache *fcc;
-
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
-
- /* Check we already aren't in the cache */
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
- if (strequal(fcc->domain_name, new_conn->domain)) {
- DEBUG(10, ("domain %s already tried and failed\n",
- fcc->domain_name));
- return;
- }
- }
-
- /* Create negative lookup cache entry for this domain and controller */
-
- if (!(fcc = (struct failed_connection_cache *)
- malloc(sizeof(struct failed_connection_cache)))) {
- DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
- return;
- }
-
- ZERO_STRUCTP(fcc);
-
- fstrcpy(fcc->domain_name, new_conn->domain);
- fstrcpy(fcc->controller, new_conn->controller);
- fcc->lookup_time = time(NULL);
- fcc->nt_status = result;
-
- DLIST_ADD(failed_connection_cache, fcc);
-}
-
/* Open a connction to the remote server, cache failures for 30 seconds */
static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
struct winbindd_cm_conn *new_conn)
{
- struct failed_connection_cache *fcc;
NTSTATUS result;
char *ipc_username, *ipc_domain, *ipc_password;
struct in_addr dc_ip;
@@ -316,47 +262,15 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
fstrcpy(new_conn->domain, domain);
fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
- /* Look for a domain controller for this domain. Negative results
- are cached so don't bother applying the caching for this
- function just yet. */
+ /* connection failure cache has been moved inside of get_dc_name
+ so we can deal with half dead DC's --jerry */
if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(new_conn, result);
+ add_failed_connection_entry(domain, "", result);
return result;
}
- /* Return false if we have tried to look up this domain and netbios
- name before and failed. */
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
-
- if (!(strequal(domain, fcc->domain_name) &&
- strequal(new_conn->controller, fcc->controller)))
- continue; /* Not our domain */
-
- if ((time(NULL) - fcc->lookup_time) >
- FAILED_CONNECTION_CACHE_TIMEOUT) {
-
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("cm_open_connection cache entry expired for %s, %s\n", domain, new_conn->controller));
-
- DLIST_REMOVE(failed_connection_cache, fcc);
- free(fcc);
-
- break;
- }
-
- /* The timeout hasn't expired yet so return false */
-
- DEBUG(10, ("returning negative open_connection_cache entry for %s, %s\n", domain, new_conn->controller));
-
- result = fcc->nt_status;
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
- return result;
- }
-
/* Initialise SMB connection */
cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
@@ -402,7 +316,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
* specific UUID right now, i'm not going to bother. --jerry
*/
if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(new_conn, result);
+ add_failed_connection_entry(domain, new_conn->controller, result);
cli_shutdown(new_conn->cli);
return result;
}
@@ -415,21 +329,19 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
static BOOL connection_ok(struct winbindd_cm_conn *conn)
{
if (!conn) {
- smb_panic("Invalid paramater passed to conneciton_ok(): conn was NULL!\n");
+ smb_panic("Invalid parameter passed to connection_ok(): conn was NULL!\n");
return False;
}
if (!conn->cli) {
- DEBUG(0, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
+ DEBUG(3, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
conn->controller, conn->domain, conn->pipe_name));
- smb_panic("connection_ok: conn->cli was null!");
return False;
}
if (!conn->cli->initialised) {
- DEBUG(0, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
+ DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
conn->controller, conn->domain, conn->pipe_name));
- smb_panic("connection_ok: conn->cli->initialised is False!");
return False;
}
@@ -442,52 +354,73 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn)
return True;
}
-/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
+/* Search the cache for a connection. If there is a broken one,
+ shut it down properly and return NULL. */
-static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
- struct winbindd_cm_conn **conn_out)
+static void find_cm_connection(const char *domain, const char *pipe_name,
+ struct winbindd_cm_conn **conn_out)
{
- struct winbindd_cm_conn *conn, conn_temp;
- NTSTATUS result;
-
- *conn_out = NULL;
+ struct winbindd_cm_conn *conn;
- for (conn = cm_conns; conn; conn = conn->next) {
+ for (conn = cm_conns; conn; ) {
if (strequal(conn->domain, domain) &&
strequal(conn->pipe_name, pipe_name)) {
if (!connection_ok(conn)) {
+ /* Dead connection - remove it. */
+ struct winbindd_cm_conn *conn_temp = conn->next;
if (conn->cli)
cli_shutdown(conn->cli);
- ZERO_STRUCT(conn_temp);
- conn_temp.next = conn->next;
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
- conn = &conn_temp; /* Just to keep the loop moving */
+ conn = conn_temp; /* Keep the loop moving */
+ continue;
} else {
break;
}
}
+ conn = conn->next;
}
-
- if (!conn) {
- if (!(conn = malloc(sizeof(*conn))))
- return NT_STATUS_NO_MEMORY;
+
+ *conn_out = conn;
+}
+
+/* Initialize a new connection up to the RPC BIND. */
+
+static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name,
+ struct winbindd_cm_conn **conn_out)
+{
+ struct winbindd_cm_conn *conn;
+ NTSTATUS result;
+
+ if (!(conn = malloc(sizeof(*conn))))
+ return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(conn);
+ ZERO_STRUCTP(conn);
- if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) {
- DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
- domain, pipe_name, nt_errstr(result)));
- SAFE_FREE(conn);
- return result;
- }
- DLIST_ADD(cm_conns, conn);
+ if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) {
+ DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
+ domain, pipe_name, nt_errstr(result)));
+ SAFE_FREE(conn);
+ return result;
}
-
+ DLIST_ADD(cm_conns, conn);
+
*conn_out = conn;
return NT_STATUS_OK;
}
+/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
+
+static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
+ struct winbindd_cm_conn **conn_out)
+{
+ find_cm_connection(domain, pipe_name, conn_out);
+
+ if (*conn_out != NULL)
+ return NT_STATUS_OK;
+
+ return new_cm_connection(domain, pipe_name, conn_out);
+}
/**********************************************************************************
**********************************************************************************/
@@ -625,244 +558,17 @@ CLI_POLICY_HND *cm_get_sam_handle(char *domain)
return &hnd;
}
-#if 0 /* This code now *well* out of date */
-
-/* Return a SAM domain policy handle on a domain */
-
-CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a basic handle to open a domain handle from */
-
- if (!cm_get_sam_handle(domain))
- return False;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_BASIC)
- basic_conn = conn;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_DOM;
- conn->cli = basic_conn->cli;
-
- result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access,
- domain_sid, &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-/* Return a SAM policy handle on a domain user */
-
-CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
- uint32 user_rid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_USER &&
- conn->pipe_data.samr.rid == user_rid) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a domain handle to open a user handle from */
-
- if (!cm_get_sam_dom_handle(domain, domain_sid))
- return NULL;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
- basic_conn = conn;
- }
-
- if (!basic_conn) {
- DEBUG(0, ("No domain sam handle was created!\n"));
- return NULL;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_USER;
- conn->cli = basic_conn->cli;
- conn->pipe_data.samr.rid = user_rid;
-
- result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access, user_rid,
- &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-/* Return a SAM policy handle on a domain group */
-
-CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
- uint32 group_rid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_GROUP &&
- conn->pipe_data.samr.rid == group_rid) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a domain handle to open a user handle from */
-
- if (!cm_get_sam_dom_handle(domain, domain_sid))
- return NULL;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
- basic_conn = conn;
- }
-
- if (!basic_conn) {
- DEBUG(0, ("No domain sam handle was created!\n"));
- return NULL;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_GROUP;
- conn->cli = basic_conn->cli;
- conn->pipe_data.samr.rid = group_rid;
-
- result = cli_samr_open_group(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access, group_rid,
- &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-#endif
-
/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
netlogon pipe as no handle is returned. */
NTSTATUS cm_get_netlogon_cli(const char *domain,
const unsigned char *trust_passwd,
uint32 sec_channel_type,
+ BOOL fresh,
struct cli_state **cli)
{
NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
struct winbindd_cm_conn *conn;
- uint32 neg_flags = 0x000001ff;
fstring lock_name;
BOOL got_mutex;
@@ -871,7 +577,30 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
/* Open an initial conection - keep the mutex. */
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn)))
+ find_cm_connection(domain, PIPE_NETLOGON, &conn);
+
+ if ( fresh && (conn != NULL) ) {
+ cli_shutdown(conn->cli);
+ conn->cli = NULL;
+
+ conn = NULL;
+
+ /* purge connection from cache */
+ find_cm_connection(domain, PIPE_NETLOGON, &conn);
+ if (conn != NULL) {
+ DEBUG(0,("Could not purge connection\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (conn != NULL) {
+ *cli = conn->cli;
+ return NT_STATUS_OK;
+ }
+
+ result = new_cm_connection(domain, PIPE_NETLOGON, &conn);
+
+ if (!NT_STATUS_IS_OK(result))
return result;
snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
@@ -880,38 +609,16 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
}
- result = cli_nt_setup_creds(conn->cli, sec_channel_type, trust_passwd, &neg_flags, 2);
+ result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
if (got_mutex)
secrets_named_mutex_release(lock_name);
-
+
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("error connecting to domain password server: %s\n",
- nt_errstr(result)));
-
- /* Hit the cache code again. This cleans out the old connection and gets a new one */
- if (conn->cli->fd == -1) {
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn)))
- return result;
-
- snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
- if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
- DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
- }
-
- /* Try again */
- result = cli_nt_setup_creds( conn->cli, sec_channel_type,trust_passwd, &neg_flags, 2);
-
- if (got_mutex)
- secrets_named_mutex_release(lock_name);
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_shutdown(conn->cli);
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
- return result;
- }
+ cli_shutdown(conn->cli);
+ DLIST_REMOVE(cm_conns, conn);
+ SAFE_FREE(conn);
+ return result;
}
*cli = conn->cli;
diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c
index fb56d0e6574..8d7cdc47317 100644
--- a/source/nsswitch/winbindd_misc.c
+++ b/source/nsswitch/winbindd_misc.c
@@ -50,7 +50,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
the trust account password. */
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, &cli);
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, True, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 2998372bd21..3b306eed3b2 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -68,6 +68,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
TALLOC_CTX *mem_ctx = NULL;
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
+ DOM_CRED ret_creds;
+ int attempts = 0;
/* Ensure null termination */
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
@@ -119,23 +121,35 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
goto done;
}
- ZERO_STRUCT(info3);
+ do {
+ ZERO_STRUCT(info3);
+ ZERO_STRUCT(ret_creds);
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
- sec_channel_type,
- &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
- goto done;
- }
-
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- name_user, name_domain,
- global_myname(), chal,
- lm_resp, nt_resp,
- &info3);
+ /* Don't shut this down - it belongs to the connection cache code */
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
+ sec_channel_type, False, &cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
+ goto done;
+ }
+
+ result = cli_netlogon_sam_network_logon(cli, mem_ctx,
+ &ret_creds,
+ name_user, name_domain,
+ global_myname(), chal,
+ lm_resp, nt_resp,
+ &info3);
+ attempts += 1;
+
+ /* We have to try a second time as cm_get_netlogon_cli
+ might not yet have noticed that the DC has killed
+ our connection. */
+
+ } while ( (attempts < 2) && (cli->fd == -1) );
+
+
+ clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
uni_group_cache_store_netlogon(mem_ctx, &info3);
done:
@@ -176,6 +190,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
const char *domain = NULL;
const char *contact_domain;
const char *workstation;
+ DOM_CRED ret_creds;
+ int attempts = 0;
DATA_BLOB lm_resp, nt_resp;
@@ -264,21 +280,37 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
goto done;
}
- ZERO_STRUCT(info3);
+ do {
+ ZERO_STRUCT(info3);
+ ZERO_STRUCT(ret_creds);
+
+ /* Don't shut this down - it belongs to the connection cache code */
+ result = cm_get_netlogon_cli(contact_domain, trust_passwd,
+ sec_channel_type, False, &cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
+ nt_errstr(result)));
+ goto done;
+ }
+
+ result = cli_netlogon_sam_network_logon(cli, mem_ctx,
+ &ret_creds,
+ user, domain,
+ workstation,
+ state->request.data.auth_crap.chal,
+ lm_resp, nt_resp,
+ &info3);
+
+ attempts += 1;
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, &cli);
+ /* We have to try a second time as cm_get_netlogon_cli
+ might not yet have noticed that the DC has killed
+ our connection. */
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
- goto done;
- }
+ } while ( (attempts < 2) && (cli->fd == -1) );
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- user, domain,
- workstation, state->request.data.auth_crap.chal,
- lm_resp, nt_resp,
- &info3);
+ clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
if (NT_STATUS_IS_OK(result)) {
uni_group_cache_store_netlogon(mem_ctx, &info3);
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 3925a569ca5..a5e9b1467f2 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -109,6 +109,8 @@ typedef struct
char *szRootdir;
char *szDefaultService;
char *szDfree;
+ char *szGetQuota;
+ char *szSetQuota;
char *szMsgCommand;
char *szHostsEquiv;
char *szServerString;
@@ -221,6 +223,8 @@ typedef struct
int iLockSpinTime;
char *szLdapMachineSuffix;
char *szLdapUserSuffix;
+ char *szLdapIdmapSuffix;
+ char *szLdapGroupSuffix;
#ifdef WITH_LDAP_SAMCONFIG
int ldap_port;
char *szLdapServer;
@@ -339,9 +343,7 @@ typedef struct
char **printer_admin;
char *volume;
char *fstype;
- char *szVfsObjectFile;
- char *szVfsOptions;
- char *szVfsPath;
+ char **szVfsObjects;
char *szMSDfsProxy;
int iMinPrintSpace;
int iMaxPrintJobs;
@@ -460,9 +462,7 @@ static service sDefault = {
NULL, /* printer admin */
NULL, /* volume */
NULL, /* fstype */
- NULL, /* vfs object */
- NULL, /* vfs options */
- NULL, /* vfs path */
+ NULL, /* vfs objects */
NULL, /* szMSDfsProxy */
0, /* iMinPrintSpace */
1000, /* iMaxPrintJobs */
@@ -562,9 +562,8 @@ static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
-static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
-static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
+static BOOL handle_ldap_sub_suffix ( const char *pszParmValue, char **ptr );
static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
@@ -751,8 +750,8 @@ static struct parm_struct parm_table[] = {
{"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC},
- {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC},
+ {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -763,7 +762,7 @@ static struct parm_struct parm_table[] = {
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -804,12 +803,12 @@ static struct parm_struct parm_table[] = {
{"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
{"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
{"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
{"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
@@ -856,11 +855,11 @@ static struct parm_struct parm_table[] = {
{"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
{"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
- {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
+ {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_DEVELOPER},
{"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
+ {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED},
{"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
{"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
@@ -1003,6 +1002,7 @@ static struct parm_struct parm_table[] = {
{"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
{"WINS Options", P_SEP, P_SEPARATOR},
+
{"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -1027,7 +1027,7 @@ static struct parm_struct parm_table[] = {
{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"Ldap Options", P_SEP, P_SEPARATOR},
@@ -1036,8 +1036,10 @@ static struct parm_struct parm_table[] = {
{"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
#endif
{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -1066,6 +1068,8 @@ static struct parm_struct parm_table[] = {
{"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
{"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
@@ -1104,10 +1108,9 @@ static struct parm_struct parm_table[] = {
{"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"VFS module options", P_SEP, P_SEPARATOR},
-
- {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjectFile, NULL, NULL, FLAG_SHARE},
- {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
- {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
+
+ {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE},
+ {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE | FLAG_HIDE},
{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
@@ -1119,9 +1122,7 @@ static struct parm_struct parm_table[] = {
{"idmap only", P_BOOL, P_GLOBAL, &Globals.bIdmapOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
{"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
{"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -1341,8 +1342,8 @@ static void init_globals(void)
Globals.paranoid_server_security = True;
Globals.bEncryptPasswords = True;
Globals.bUpdateEncrypt = False;
- Globals.clientSchannel = False;
- Globals.serverSchannel = False;
+ Globals.clientSchannel = Auto;
+ Globals.serverSchannel = Auto;
Globals.bReadRaw = True;
Globals.bWriteRaw = True;
Globals.bReadPrediction = False;
@@ -1410,7 +1411,7 @@ static void init_globals(void)
#ifdef WITH_LDAP_SAMCONFIG
string_set(&Globals.szLdapServer, "localhost");
Globals.ldap_port = 636;
- Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
+ Globals.szPassdbBackend = str_list_make("ldapsam_compat guest", NULL);
#else
Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
#endif /* WITH_LDAP_SAMCONFIG */
@@ -1419,6 +1420,8 @@ static void init_globals(void)
string_set(&Globals.szLdapFilter, "(uid=%u)");
string_set(&Globals.szLdapMachineSuffix, "");
string_set(&Globals.szLdapUserSuffix, "");
+ string_set(&Globals.szLdapGroupSuffix, "");
+ string_set(&Globals.szLdapIdmapSuffix, "");
string_set(&Globals.szLdapAdminDn, "");
Globals.ldap_ssl = LDAP_SSL_ON;
@@ -1496,8 +1499,7 @@ void lp_talloc_free(void)
static char *lp_string(const char *s)
{
- size_t len = s ? strlen(s) : 0;
- char *ret;
+ char *ret, *tmpstr;
/* The follow debug is useful for tracking down memory problems
especially if you have an inner loop that is calling a lp_*()
@@ -1511,25 +1513,16 @@ static char *lp_string(const char *s)
if (!lp_talloc)
lp_talloc = talloc_init("lp_talloc");
- ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
-
- if (!ret)
- return NULL;
-
- /* Note: StrnCpy touches len+1 bytes, but we allocate 100
- * extra bytes so we're OK. */
-
- if (!s)
- *ret = 0;
- else
- StrnCpy(ret, s, len);
-
- if (trim_string(ret, "\"", "\"")) {
- if (strchr(ret,'"') != NULL)
- StrnCpy(ret, s, len);
+ tmpstr = alloc_sub_basic(current_user_info.smb_name, s);
+ if (trim_string(tmpstr, "\"", "\"")) {
+ if (strchr(tmpstr,'"') != NULL) {
+ SAFE_FREE(tmpstr);
+ tmpstr = alloc_sub_basic(current_user_info.smb_name,s);
+ }
}
-
- standard_sub_basic(current_user_info.smb_name,ret,len+100);
+ ret = talloc_strdup(lp_talloc, tmpstr);
+ SAFE_FREE(tmpstr);
+
return (ret);
}
@@ -1592,6 +1585,8 @@ FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
+FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
+FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
@@ -1651,6 +1646,8 @@ FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
+FN_GLOBAL_STRING(lp_ldap_idmap_suffix, &Globals.szLdapIdmapSuffix)
+FN_GLOBAL_STRING(lp_ldap_group_suffix, &Globals.szLdapGroupSuffix)
FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
@@ -1777,9 +1774,7 @@ FN_LOCAL_LIST(lp_readlist, readlist)
FN_LOCAL_LIST(lp_writelist, writelist)
FN_LOCAL_LIST(lp_printer_admin, printer_admin)
FN_LOCAL_STRING(lp_fstype, fstype)
-FN_LOCAL_LIST(lp_vfsobj, szVfsObjectFile)
-FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
-FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
+FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
static FN_LOCAL_STRING(lp_volume, volume)
FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
@@ -2259,6 +2254,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
} else {
pstrcpy(newHomedir, lp_pathname(iDefaultService));
string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
+ string_sub(newHomedir,"%S", pszHomename, sizeof(newHomedir));
}
string_set(&ServicePtrs[i]->szPath, newHomedir);
@@ -2942,91 +2938,61 @@ static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
}
/***************************************************************************
- Handle the ldap machine suffix option.
+ Handle setting ldap suffix and determines whether ldap machine suffix needs
+ to be set as well.
+
+ Set all of the sub suffix strings to be the 'ldap suffix' by default
***************************************************************************/
-static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
+static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr )
{
- pstring suffix;
-
- pstrcpy(suffix, pszParmValue);
-
- if (! *Globals.szLdapSuffix ) {
- string_set( ptr, suffix );
- return True;
- }
-
- if (! strstr(suffix, Globals.szLdapSuffix) ) {
- if ( *pszParmValue )
- pstrcat(suffix, ",");
- pstrcat(suffix, Globals.szLdapSuffix);
- }
- string_set( ptr, suffix );
- return True;
+ pstring suffix;
+
+ pstrcpy(suffix, pszParmValue);
+
+ /* set defaults for the the sub-suffixes */
+
+ if (! *Globals.szLdapMachineSuffix )
+ string_set(&Globals.szLdapMachineSuffix, suffix);
+ if (! *Globals.szLdapUserSuffix )
+ string_set(&Globals.szLdapUserSuffix, suffix);
+ if (! *Globals.szLdapGroupSuffix )
+ string_set(&Globals.szLdapGroupSuffix, suffix);
+ if (! *Globals.szLdapIdmapSuffix )
+ string_set(&Globals.szLdapIdmapSuffix, suffix);
+
+ string_set(ptr, suffix);
+ return True;
}
/***************************************************************************
- Handle the ldap user suffix option.
+ Handle the ldap sub suffix option.
+ Always append the 'ldap suffix' if it is set
***************************************************************************/
-static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
+static BOOL handle_ldap_sub_suffix( const char *pszParmValue, char **ptr)
{
- pstring suffix;
+ pstring suffix;
- pstrcpy(suffix, pszParmValue);
+ pstrcpy(suffix, pszParmValue);
- if (! *Globals.szLdapSuffix ) {
- string_set( ptr, suffix );
- return True;
- }
-
- if (! strstr(suffix, Globals.szLdapSuffix) ) {
- if ( *pszParmValue )
- pstrcat(suffix, ",");
- pstrcat(suffix, Globals.szLdapSuffix);
- }
- string_set( ptr, suffix );
- return True;
+ if (! *Globals.szLdapSuffix ) {
+ string_set( ptr, suffix );
+ return True;
+ }
+ else {
+ if ( *pszParmValue )
+ pstrcat(suffix, ",");
+ pstrcat(suffix, Globals.szLdapSuffix);
+ }
+
+ string_set( ptr, suffix );
+ return True;
}
/***************************************************************************
- Handle setting ldap suffix and determines whether ldap machine suffix needs
- to be set as well.
***************************************************************************/
-static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
-{
- pstring suffix;
- pstring user_suffix;
- pstring machine_suffix;
-
- pstrcpy(suffix, pszParmValue);
-
- if (! *Globals.szLdapMachineSuffix )
- string_set(&Globals.szLdapMachineSuffix, suffix);
- if (! *Globals.szLdapUserSuffix )
- string_set(&Globals.szLdapUserSuffix, suffix);
-
- if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
- pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
- if ( *Globals.szLdapMachineSuffix )
- pstrcat(machine_suffix, ",");
- pstrcat(machine_suffix, suffix);
- string_set(&Globals.szLdapMachineSuffix, machine_suffix);
- }
-
- if (! strstr(Globals.szLdapUserSuffix, suffix)) {
- pstrcpy(user_suffix, Globals.szLdapUserSuffix);
- if ( *Globals.szLdapUserSuffix )
- pstrcat(user_suffix, ",");
- pstrcat(user_suffix, suffix);
- string_set(&Globals.szLdapUserSuffix, user_suffix);
- }
-
- string_set(ptr, suffix);
- return True;
-}
-
static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
{
if (strequal(pszParmValue, "auto"))
@@ -3040,6 +3006,7 @@ static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
return True;
}
+
/***************************************************************************
Initialise a copymap.
***************************************************************************/
@@ -4242,7 +4209,7 @@ void lp_set_logfile(const char *name)
}
/*******************************************************************
- Return the NetBIOS called name.
+ Return the NetBIOS called name, or my IP - but never global_myname().
********************************************************************/
const char *get_called_name(void)
@@ -4250,22 +4217,11 @@ const char *get_called_name(void)
extern fstring local_machine;
static fstring called_name;
- if (! *local_machine)
- return global_myname();
-
- /*
- * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
- * arrggg!!! but we've already rewritten the client's
- * netbios name at this point...
- */
-
- if (*local_machine) {
- if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) {
- fstrcpy(called_name, get_my_primary_ip());
- DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
- called_name));
- return called_name;
- }
+ if (!*local_machine) {
+ fstrcpy(called_name, get_my_primary_ip());
+ DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
+ called_name));
+ return called_name;
}
return local_machine;
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 7b44df193fc..7640228ab98 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -74,7 +74,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
struct pdb_init_function_entry *entry = backends;
while(entry) {
- if (strcasecmp(entry->name, name) == 0) return entry;
+ if (strcmp(entry->name, name)==0) return entry;
entry = entry->next;
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index fb63e81d28b..3ddbd99ca3b 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -59,6 +59,8 @@
#define SAM_ACCOUNT struct sam_passwd
#endif
+#include "smbldap.h"
+
struct ldapsam_privates {
/* Former statics */
LDAP *ldap_struct;
@@ -93,177 +95,6 @@ struct ldapsam_privates {
static struct ldapsam_privates *static_ldap_state;
-/* specify schema versions between 2.2. and 3.0 */
-
-#define SCHEMAVER_SAMBAACCOUNT 1
-#define SCHEMAVER_SAMBASAMACCOUNT 2
-
-/* objectclass names */
-
-#define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount"
-#define LDAP_OBJ_SAMBAACCOUNT "sambaAccount"
-#define LDAP_OBJ_GROUPMAP "sambaGroupMapping"
-#define LDAP_OBJ_DOMINFO "sambaDomain"
-
-#define LDAP_OBJ_ACCOUNT "account"
-#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
-#define LDAP_OBJ_POSIXGROUP "posixGroup"
-
-/* some generic attributes that get reused a lot */
-
-#define LDAP_ATTRIBUTE_SID "sambaSID"
-
-/* attribute map table indexes */
-
-#define LDAP_ATTR_LIST_END 0
-#define LDAP_ATTR_UID 1
-#define LDAP_ATTR_UIDNUMBER 2
-#define LDAP_ATTR_GIDNUMBER 3
-#define LDAP_ATTR_UNIX_HOME 4
-#define LDAP_ATTR_PWD_LAST_SET 5
-#define LDAP_ATTR_PWD_CAN_CHANGE 6
-#define LDAP_ATTR_PWD_MUST_CHANGE 7
-#define LDAP_ATTR_LOGON_TIME 8
-#define LDAP_ATTR_LOGOFF_TIME 9
-#define LDAP_ATTR_KICKOFF_TIME 10
-#define LDAP_ATTR_CN 11
-#define LDAP_ATTR_DISPLAY_NAME 12
-#define LDAP_ATTR_HOME_PATH 13
-#define LDAP_ATTR_LOGON_SCRIPT 14
-#define LDAP_ATTR_PROFILE_PATH 15
-#define LDAP_ATTR_DESC 16
-#define LDAP_ATTR_USER_WKS 17
-#define LDAP_ATTR_USER_SID 18
-#define LDAP_ATTR_USER_RID 18
-#define LDAP_ATTR_PRIMARY_GROUP_SID 19
-#define LDAP_ATTR_PRIMARY_GROUP_RID 20
-#define LDAP_ATTR_LMPW 21
-#define LDAP_ATTR_NTPW 22
-#define LDAP_ATTR_DOMAIN 23
-#define LDAP_ATTR_OBJCLASS 24
-#define LDAP_ATTR_ACB_INFO 25
-#define LDAP_ATTR_NEXT_USERRID 26
-#define LDAP_ATTR_NEXT_GROUPRID 27
-#define LDAP_ATTR_DOM_SID 28
-#define LDAP_ATTR_HOME_DRIVE 29
-#define LDAP_ATTR_GROUP_SID 30
-#define LDAP_ATTR_GROUP_TYPE 31
-
-
-typedef struct _attrib_map_entry {
- int attrib;
- const char *name;
-} ATTRIB_MAP_ENTRY;
-
-
-/* attributes used by Samba 2.2 */
-
-static ATTRIB_MAP_ENTRY attrib_map_v22[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, "uidNumber" },
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "logonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_PATH, "smbHome" },
- { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
- { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
- { LDAP_ATTR_PROFILE_PATH, "profilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "userWorkstations"},
- { LDAP_ATTR_USER_RID, "rid" },
- { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
- { LDAP_ATTR_LMPW, "lmPassword" },
- { LDAP_ATTR_NTPW, "ntPassword" },
- { LDAP_ATTR_DOMAIN, "domain" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "acctFlags" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used by Samba 3.0's sambaSamAccount */
-
-static ATTRIB_MAP_ENTRY attrib_map_v30[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, "uidNumber" },
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
- { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
- { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
- { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
- { LDAP_ATTR_USER_SID, "sambaSID" },
- { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
- { LDAP_ATTR_LMPW, "sambaLMPassword" },
- { LDAP_ATTR_NTPW, "sambaNTPassword" },
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used for alalocating RIDs */
-
-static ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
- { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
- { LDAP_ATTR_DOM_SID, "sambaSID" },
- { LDAP_ATTR_LIST_END, NULL },
-};
-
-/* Samba 3.0 group mapping attributes */
-
-static ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_GROUP_SID, "sambaSID" },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-static ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
- { LDAP_ATTR_GROUP_SID, "sambaSID" },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/**********************************************************************
- perform a simple table lookup and return the attribute name
- **********************************************************************/
-
-static const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
-{
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- if ( table[i].attrib == key )
- return table[i].name;
- i++;
- }
-
- return NULL;
-}
/**********************************************************************
get the attribute name given a user schame version
@@ -287,52 +118,6 @@ static const char* get_userattr_key2string( int schema_ver, int key )
}
/**********************************************************************
- Return the list of attribute names from a mapping table
- **********************************************************************/
-
-static char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
-{
- char **names;
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END )
- i++;
- i++;
-
- names = (char**)malloc( sizeof(char*)*i );
- if ( !names ) {
- DEBUG(0,("get_attr_list: out of memory\n"));
- return NULL;
- }
-
- i = 0;
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- names[i] = strdup( table[i].name );
- i++;
- }
- names[i] = NULL;
-
- return names;
-}
-
-/*********************************************************************
- Cleanup
- ********************************************************************/
-
-static void free_attr_list( char **list )
-{
- int i = 0;
-
- if ( !list )
- return;
-
- while ( list[i] )
- SAFE_FREE( list[i] );
-
- SAFE_FREE( list );
-}
-
-/**********************************************************************
return the list of attribute names given a user schema version
**********************************************************************/
@@ -352,70 +137,6 @@ static char** get_userattr_list( int schema_ver )
return NULL;
}
-
-/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldapsam_pw(char **dn, char** pw)
-{
- char *key = NULL;
- size_t size;
-
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
- }
-
- *pw=secrets_fetch(key, &size);
- SAFE_FREE(key);
-
- if (!size) {
- /* Upgrade 2.2 style entry */
- char *p;
- char* old_style_key = strdup(*dn);
- char *data;
- fstring old_style_pw;
-
- if (!old_style_key) {
- DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
- return False;
- }
-
- for (p=old_style_key; *p; p++)
- if (*p == ',') *p = '/';
-
- data=secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
-
- strncpy(old_style_pw, data, size);
- old_style_pw[size] = 0;
-
- SAFE_FREE(data);
-
- if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
- if (!secrets_delete(old_style_key)) {
- DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
- }
-
- return True;
-}
/*******************************************************************
open a connection to the ldap server.
@@ -632,7 +353,7 @@ static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ld
static_ldap_state = ldap_state;
/* get the password */
- if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
{
DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
return LDAP_INVALID_CREDENTIALS;
@@ -1097,93 +818,6 @@ static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
return True;
}
-/************************************************************************
-Routine to manage the LDAPMod structure array
-manage memory used by the array, by each struct, and values
-
-************************************************************************/
-static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
-{
- LDAPMod **mods;
- int i;
- int j;
-
- mods = *modlist;
-
- /* sanity checks on the mod values */
-
- if (attribute == NULL || *attribute == '\0')
- return;
-#if 0 /* commented out after discussion with abartlet. Do not reenable.
- left here so other so re-add similar code --jerry */
- if (value == NULL || *value == '\0')
- return;
-#endif
-
- if (mods == NULL)
- {
- mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
- if (mods == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[0] = NULL;
- }
-
- for (i = 0; mods[i] != NULL; ++i) {
- if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
- break;
- }
-
- if (mods[i] == NULL)
- {
- mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
- if (mods == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
- if (mods[i] == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[i]->mod_op = modop;
- mods[i]->mod_values = NULL;
- mods[i]->mod_type = strdup(attribute);
- mods[i + 1] = NULL;
- }
-
- if (value != NULL)
- {
- char *utf8_value = NULL;
-
- j = 0;
- if (mods[i]->mod_values != NULL) {
- for (; mods[i]->mod_values[j] != NULL; j++);
- }
- mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
- (j + 2) * sizeof (char *));
-
- if (mods[i]->mod_values == NULL) {
- DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
- return;
- }
-
- if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
- DEBUG (0, ("make_a_mod: String conversion failure!\n"));
- return;
- }
-
- mods[i]->mod_values[j] = utf8_value;
-
- mods[i]->mod_values[j + 1] = NULL;
- }
- *modlist = mods;
-}
-
/**********************************************************************
Set attribute to newval in LDAP, regardless of what value the
attribute had in LDAP before.
@@ -1217,7 +851,7 @@ static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
the old value, should it exist. */
if ((newval != NULL) && (strlen(newval) > 0)) {
- make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
+ ldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
}
if (values == NULL) {
@@ -1232,7 +866,7 @@ static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
deny the complete operation if somebody changed the
attribute behind our back. */
- make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
+ ldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
ldap_value_free(values);
}
@@ -1288,7 +922,7 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
{
if (StrCaseCmp(*attrib, name) == 0) {
DEBUG(10, ("deleting attribute %s\n", name));
- make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL);
+ ldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
}
}
@@ -1299,10 +933,10 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
ber_free(ptr, 0);
}
- make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
+ ldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
rc = ldapsam_modify(ldap_state, dn, mods);
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
@@ -1488,12 +1122,11 @@ static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int
static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
{
pstring tmp;
- pstring filter;
+ pstring filter, dn;
LDAPMod **mods = NULL;
int rc;
int ldap_op;
LDAPMessage *result = NULL;
- char *dn = NULL;
int num_result;
char **attr_list;
@@ -1533,29 +1166,26 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
/* Check if we need to add an entry */
DEBUG(3,("Adding new domain\n"));
ldap_op = LDAP_MOD_ADD;
- asprintf (&dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
ldap_state->domain_name, lp_ldap_suffix());
/* Free original search */
ldap_msgfree(result);
- if (!dn)
- return NT_STATUS_NO_MEMORY;
-
/* make the changes - the entry *must* not already have samba attributes */
- make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
ldap_state->domain_name);
sid_to_string(tmp, &ldap_state->domain_sid);
- make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_user_rid);
- make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_group_rid);
- make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
- make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
switch(ldap_op)
{
@@ -1581,12 +1211,12 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
- ldap_mods_free(mods,1);
+ ldap_mods_free(mods, True);
return NT_STATUS_UNSUCCESSFUL;
}
DEBUG(2,("added: domain = %s in the LDAP database\n", ldap_state->domain_name));
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
return NT_STATUS_OK;
}
@@ -1766,20 +1396,20 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
domain_sid_string))
{
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
ldap_memfree(dn);
ldap_msgfree(result);
return ret;
}
if (!string_to_sid(&dom_sid, domain_sid_string)) {
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
ldap_memfree(dn);
ldap_msgfree(result);
return ret;
}
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
mods = NULL;
ldap_memfree(dn);
ldap_msgfree(result);
@@ -1802,7 +1432,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
DEBUG(2, ("Failed to modify rid: %s\n", ld_error));
SAFE_FREE(ld_error);
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
mods = NULL;
ldap_memfree(dn);
@@ -2268,13 +1898,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
"finding next available NUA RID failed, "
"cannot store!\n",
pdb_get_username(sampass)));
- ldap_mods_free(*mods, 1);
+ ldap_mods_free(*mods, True);
return False;
}
} else {
DEBUG(0, ("NO user RID specified on account %s, "
"cannot store!\n", pdb_get_username(sampass)));
- ldap_mods_free(*mods, 1);
+ ldap_mods_free(*mods, True);
return False;
}
@@ -2284,7 +1914,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if (!pdb_set_user_sid_from_rid(sampass, rid, PDB_CHANGED)) {
DEBUG(0, ("Could not store RID back onto SAM_ACCOUNT for user %s!\n",
pdb_get_username(sampass)));
- ldap_mods_free(*mods, 1);
+ ldap_mods_free(*mods, True);
return False;
}
}
@@ -2693,7 +2323,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
switch(ldap_op)
{
case LDAP_MOD_ADD:
- make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
rc = ldapsam_add(ldap_state, dn, mods);
break;
case LDAP_MOD_REPLACE:
@@ -2884,12 +2514,12 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
if (mods == NULL) {
DEBUG(4,("mods is empty: nothing to update for user: %s\n",
pdb_get_username(newpwd)));
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
return NT_STATUS_OK;
}
ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
- ldap_mods_free(mods,1);
+ ldap_mods_free(mods,True);
if (!NT_STATUS_IS_OK(ret)) {
char *ld_error = NULL;
@@ -3020,10 +2650,10 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
switch ( ldap_state->schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT:
- make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
break;
case SCHEMAVER_SAMBASAMACCOUNT:
- make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
+ ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
break;
default:
DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
@@ -3034,12 +2664,12 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
pdb_get_username(newpwd),dn));
- ldap_mods_free(mods,1);
+ ldap_mods_free(mods, True);
return ret;
}
DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
return NT_STATUS_OK;
}
@@ -3083,7 +2713,7 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
attr_list = get_attr_list(groupmap_attr_list);
- rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
+ rc = ldapsam_search(ldap_state, lp_ldap_group_suffix (), scope,
filter, attr_list, 0, result);
free_attr_list( attr_list );
@@ -3095,7 +2725,7 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
"Problem during the LDAP search: LDAP error: %s (%s)",
ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
- lp_ldap_suffix(), filter));
+ lp_ldap_group_suffix(), filter));
SAFE_FREE(ld_error);
}
@@ -3372,7 +3002,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
if (!init_ldap_from_group(ldap_state->ldap_struct,
result, &mods, map)) {
DEBUG(0, ("init_ldap_from_group failed!\n"));
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -3384,11 +3014,10 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
- "sambaGroupMapping");
+ ldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
rc = ldapsam_modify(ldap_state, dn, mods);
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
@@ -3449,7 +3078,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
rc = ldapsam_modify(ldap_state, dn, mods);
- ldap_mods_free(mods, 1);
+ ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
@@ -3509,14 +3138,14 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
attr_list = get_attr_list( groupmap_attr_list );
- rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
+ rc = ldapsam_search(ldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &ldap_state->result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
+ DEBUG(3, ("Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
ldap_msgfree(ldap_state->result);
ldap_state->result = NULL;
return NT_STATUS_UNSUCCESSFUL;
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index c392846d935..7095e8a4529 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1133,24 +1133,34 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
********************************************************************/
static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
{
- uid_t uid;
uint32 rid;
if (sampass == NULL)
return False;
-
- rid = pdb_get_user_rid(sampass);
-
- /* If the user specified a RID, make sure its able to be both stored and retreived */
- if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) {
- DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
- return False;
- }
-
ZERO_STRUCTP(smb_pw);
- smb_pw->smb_userid_set = True;
- smb_pw->smb_userid=uid;
+ if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
+ rid = pdb_get_user_rid(sampass);
+
+ /* If the user specified a RID, make sure its able to be both stored and retreived */
+ if (rid == DOMAIN_USER_RID_GUEST) {
+ struct passwd *passwd = getpwnam_alloc(lp_guestaccount());
+ if (!passwd) {
+ DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));
+ return False;
+ }
+ smb_pw->smb_userid_set = True;
+ smb_pw->smb_userid=passwd->pw_uid;
+ passwd_free(&passwd);
+
+ } else if (fallback_pdb_rid_is_user(rid)) {
+ smb_pw->smb_userid_set = True;
+ smb_pw->smb_userid=fallback_pdb_user_rid_to_uid(rid);
+ } else {
+ DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
+ return False;
+ }
+ }
smb_pw->smb_name=(const char*)pdb_get_username(sampass);
diff --git a/source/printing/lpq_parse.c b/source/printing/lpq_parse.c
index c845170749e..b2f45ad3662 100644
--- a/source/printing/lpq_parse.c
+++ b/source/printing/lpq_parse.c
@@ -145,8 +145,8 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
buf->size = atoi(tok[TOTALTOK]);
buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[USERTOK],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[USERTOK]);
+ fstrcpy(buf->fs_file,tok[FILETOK]);
if ((FILETOK + 1) != TOTALTOK) {
int i;
@@ -266,7 +266,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
- StrnCpy(buf->fs_user,tokarr[LPRNG_USERTOK],sizeof(buf->fs_user)-1);
+ fstrcpy(buf->fs_user,tokarr[LPRNG_USERTOK]);
/* The '@hostname' prevents windows from displaying the printing icon
* for the current user on the taskbar. Plop in a null.
@@ -276,7 +276,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
*ptr = '\0';
}
- StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_file,tokarr[LPRNG_FILETOK]);
if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
int i;
@@ -353,8 +353,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[3],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[3]);
+ fstrcpy(buf->fs_file,tok[2]);
}
else
{
@@ -387,8 +387,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[5],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[4],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[5]);
+ fstrcpy(buf->fs_file,tok[4]);
}
@@ -449,14 +449,14 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
fstrcpy(tok[0],"STDIN");
buf->size = atoi(tok[1]);
- StrnCpy(buf->fs_file,tok[0],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_file,tok[0]);
/* fill things from header line */
buf->time = jobtime;
buf->job = jobid;
buf->status = jobstat;
buf->priority = jobprio;
- StrnCpy(buf->fs_user,jobuser,sizeof(buf->fs_user)-1);
+ fstrcpy(buf->fs_user,jobuser);
return(True);
}
@@ -482,7 +482,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
/* the 2nd, 5th & 7th column must be integer */
if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
jobid = atoi(tok[1]);
- StrnCpy(jobuser,tok[2],sizeof(buf->fs_user)-1);
+ fstrcpy(jobuser,tok[2]);
jobprio = atoi(tok[4]);
/* process time */
@@ -573,8 +573,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
buf->status = LPQ_QUEUED;
buf->priority = 0;
buf->time = EntryTime(tok, 4, count, 7);
- StrnCpy(buf->fs_user,tok[2],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[2]);
+ fstrcpy(buf->fs_file,tok[2]);
return(True);
}
@@ -633,8 +633,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[1]);
+ fstrcpy(buf->fs_file,tok[6]);
return(True);
}
@@ -704,8 +704,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user,tok[1]);
+ fstrcpy(buf->fs_file,tok[6]);
return(True);
}
@@ -779,8 +779,8 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
buf->priority = 0;
buf->size = atoi(parse_line.size);
buf->time = time(NULL);
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_user, parse_line.owner);
+ fstrcpy(buf->fs_file, parse_line.jobname);
if (strequal(parse_line.status, LPRNT_PRINTING))
buf->status = LPQ_PRINTING;
else if (strequal(parse_line.status, LPRNT_PAUSED))
@@ -838,7 +838,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
/* Get the job name */
parse_line.space2[0] = '\0';
trim_string(parse_line.jobname, NULL, " ");
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
+ fstrcpy(buf->fs_file, parse_line.jobname);
buf->priority = 0;
buf->size = atoi(parse_line.size);
@@ -856,7 +856,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
!strequal(parse_line.status, LPROS2_WAITING))
return(False);
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
+ fstrcpy(buf->fs_user, parse_line.owner);
if (strequal(parse_line.status, LPROS2_PRINTING))
buf->status = LPQ_PRINTING;
else if (strequal(parse_line.status, LPROS2_PAUSED))
@@ -990,23 +990,23 @@ BOOL parse_lpq_entry(int snum,char *line,
case LPSTAT_OK:
for (i=0; stat0_strings[i]; i++)
if (strstr(line,stat0_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_OK;
- return ret;
+ fstrcpy(status->message,line);
+ status->status=LPSTAT_OK;
+ return ret;
}
case LPSTAT_STOPPED:
for (i=0; stat1_strings[i]; i++)
if (strstr(line,stat1_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_STOPPED;
- return ret;
+ fstrcpy(status->message,line);
+ status->status=LPSTAT_STOPPED;
+ return ret;
}
case LPSTAT_ERROR:
for (i=0; stat2_strings[i]; i++)
if (strstr(line,stat2_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_ERROR;
- return ret;
+ fstrcpy(status->message,line);
+ status->status=LPSTAT_ERROR;
+ return ret;
}
break;
}
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 2b4b7dab6ba..f6c5c183a47 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -198,6 +198,22 @@ static const nt_forms_struct default_forms[] = {
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
+struct table_node {
+ const char *long_archi;
+ const char *short_archi;
+ int version;
+};
+
+static const struct table_node archi_table[]= {
+
+ {"Windows 4.0", "WIN40", 0 },
+ {"Windows NT x86", "W32X86", 2 },
+ {"Windows NT R4000", "W32MIPS", 2 },
+ {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
+ {"Windows NT PowerPC", "W32PPC", 2 },
+ {NULL, "", -1 }
+};
+
static BOOL upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
@@ -638,12 +654,12 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count)
int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
{
int total=0;
- fstring short_archi;
+ const char *short_archi;
fstring *fl;
pstring key;
TDB_DATA kbuf, newkey;
- get_short_archi(short_archi, architecture);
+ short_archi = get_short_archi(architecture);
slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
for (kbuf = tdb_firstkey(tdb_drivers);
@@ -667,52 +683,32 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
}
/****************************************************************************
- Function to do the mapping between the long architecture name and
- the short one.
+function to do the mapping between the long architecture name and
+the short one.
****************************************************************************/
-BOOL get_short_archi(char *short_archi, const char *long_archi)
+const char *get_short_archi(const char *long_archi)
{
- struct table {
- const char *long_archi;
- const char *short_archi;
- };
-
- struct table archi_table[]=
- {
- {"Windows 4.0", "WIN40" },
- {"Windows NT x86", "W32X86" },
- {"Windows NT R4000", "W32MIPS" },
- {"Windows NT Alpha_AXP", "W32ALPHA" },
- {"Windows NT PowerPC", "W32PPC" },
- {NULL, "" }
- };
-
- int i=-1;
+ int i=-1;
- DEBUG(107,("Getting architecture dependant directory\n"));
+ DEBUG(107,("Getting architecture dependant directory\n"));
+ do {
+ i++;
+ } while ( (archi_table[i].long_archi!=NULL ) &&
+ StrCaseCmp(long_archi, archi_table[i].long_archi) );
- if (long_archi == NULL) {
- DEBUGADD(107,("Bad long_archi param.!\n"));
- return False;
- }
+ if (archi_table[i].long_archi==NULL) {
+ DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
+ return NULL;
+ }
- do {
- i++;
- } while ( (archi_table[i].long_archi!=NULL ) &&
- StrCaseCmp(long_archi, archi_table[i].long_archi) );
+ /* this might be client code - but shouldn't this be an fstrcpy etc? */
- if (archi_table[i].long_archi==NULL) {
- DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
- return False;
- }
- StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
+ DEBUGADD(108,("index: [%d]\n", i));
+ DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
+ DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
- DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", short_archi));
-
- return True;
+ return archi_table[i].short_archi;
}
/****************************************************************************
@@ -750,7 +746,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
fname, errno));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
@@ -810,7 +806,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
/* Seek to the start of the .rsrc section info */
- if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
fname, errno));
goto error_exit;
@@ -903,7 +899,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
* twice, as it is simpler to read the code. */
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
/* Compute skip alignment to next long address */
- int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
+ int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
sizeof(VS_SIGNATURE)) & 3;
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
@@ -996,7 +992,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
old_file));
use_version = False;
- if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
old_create_time = st.st_mtime;
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
@@ -1025,7 +1021,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
new_file));
use_version = False;
- if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
new_create_time = st.st_mtime;
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
@@ -1066,7 +1062,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
+static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
struct current_user *user, WERROR *perr)
{
int cversion;
@@ -1111,7 +1107,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
}
/* We are temporarily becoming the connection user. */
- if (!become_user(conn, conn->vuid)) {
+ if (!become_user(conn, user->vuid)) {
DEBUG(0,("get_correct_cversion: Can't become user!\n"));
*perr = WERR_ACCESS_DENIED;
return -1;
@@ -1192,7 +1188,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
struct current_user *user)
{
- fstring architecture;
+ const char *architecture;
fstring new_name;
char *p;
int i;
@@ -1232,7 +1228,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
}
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
@@ -1256,7 +1252,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
****************************************************************************/
static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
{
- fstring architecture;
+ const char *architecture;
fstring new_name;
char *p;
int i;
@@ -1296,7 +1292,7 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
}
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
@@ -1382,7 +1378,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
- fstring architecture;
+ const char *architecture;
pstring new_dir;
pstring old_name;
pstring new_name;
@@ -1409,7 +1405,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
return False;
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/*
* Connect to the print$ share under the same account as the user connected to the rpc pipe.
@@ -1589,7 +1585,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
int len, buflen;
- fstring architecture;
+ const char *architecture;
pstring directory;
fstring temp_name;
pstring key;
@@ -1597,7 +1593,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
int i, ret;
TDB_DATA kbuf, dbuf;
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
* \\server is added in the rpc server layer.
@@ -1751,14 +1747,14 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA kbuf, dbuf;
- fstring architecture;
+ const char *architecture;
int len = 0;
int i;
pstring key;
ZERO_STRUCT(driver);
- get_short_archi(architecture, arch);
+ architecture = get_short_archi(arch);
DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
@@ -2611,6 +2607,10 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
}
+ setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
+ SAFE_FREE(ads->auth.password);
+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
+ NULL, NULL);
ads_rc = ads_connect(ads);
if (!ADS_ERR_OK(ads_rc)) {
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -2668,6 +2668,10 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
}
+ setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
+ SAFE_FREE(ads->auth.password);
+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
+ NULL, NULL);
ads_rc = ads_connect(ads);
if (!ADS_ERR_OK(ads_rc)) {
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -4405,13 +4409,13 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
uint32 version, BOOL delete_files )
{
pstring key;
- fstring arch;
+ const char *arch;
TDB_DATA kbuf, dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
- get_short_archi(arch, info_3->environment);
+ arch = get_short_archi(info_3->environment);
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
arch, version, info_3->name);
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index c399c3c6cc4..1bdbf4a789e 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -384,7 +384,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
if (strlen(p)>strlen(comment) && has_punctuation)
{
- StrnCpy(comment,p,sizeof(comment)-1);
+ pstrcpy(comment,p);
continue;
}
@@ -398,8 +398,8 @@ void pcap_printer_fn(void (*fn)(char *, char *))
if (!strchr_m(comment,' ') &&
strlen(p) > strlen(comment))
{
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
+ pstrcpy(comment,p);
+ continue;
}
}
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index 45d937f29c4..0b6d4fdbe1c 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -80,7 +80,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
fsp->wbmpx_ptr = NULL;
fsp->wcp = NULL;
- conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
+ SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf);
fsp->mode = sbuf.st_mode;
fsp->inode = sbuf.st_ino;
fsp->dev = sbuf.st_dev;
diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c
index 0c40861c701..db66be2321a 100644
--- a/source/python/py_winbind.c
+++ b/source/python/py_winbind.c
@@ -261,12 +261,12 @@ static PyObject *py_config_dict(void)
/* Winbind uid/gid range */
- if (lp_idmap_uid(&ulow, &uhi)) {
+ if (lp_winbind_uid(&ulow, &uhi)) {
PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow));
PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi));
}
- if (lp_idmap_gid(&glow, &ghi)) {
+ if (lp_winbind_gid(&glow, &ghi)) {
PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow));
PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi));
}
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index 9002ad3d1b5..db873236e46 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -1164,7 +1164,7 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
LSA_Q_ENUM_ACCT_RIGHTS q;
LSA_R_ENUM_ACCT_RIGHTS r;
NTSTATUS result;
- unsigned int i;
+ int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1199,7 +1199,7 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*privs_name = (char **)talloc(mem_ctx, (*count) * sizeof(char **));
for (i=0;i<*count;i++) {
- (*privs_name)[i] = unistr2_tdup(mem_ctx, &r.rights.strings[i].string);
+ pull_ucs2_talloc(mem_ctx, &(*privs_name)[i], r.rights.strings[i].string.buffer);
}
done:
@@ -1293,58 +1293,6 @@ done:
}
-/* list account SIDs that have the specified right */
-
-NTSTATUS cli_lsa_enum_account_with_right(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, const char *right,
- uint32 *count, DOM_SID **sids)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_ENUM_ACCT_WITH_RIGHT q;
- LSA_R_ENUM_ACCT_WITH_RIGHT r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
-
- /* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
- init_q_enum_acct_with_right(&q, pol, right);
-
- if (!lsa_io_q_enum_acct_with_right("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUMACCTWITHRIGHT, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_enum_acct_with_right("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- *count = r.count;
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- if (*count) {
- int i;
- (*sids) = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (*count));
- for (i=0; i<*count; i++) {
- sid_copy(&(*sids)[i], &r.sids.sids[i].sid.sid);
- }
- }
-done:
-
- return result;
-}
-
-
#if 0
/** An example of how to use the routines in this file. Fetch a DOMAIN
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index ce0dd95e94a..831101ed81e 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -280,7 +280,7 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
}
if (!NT_STATUS_IS_OK(result))
- DEBUG(1,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result)));
+ DEBUG(3,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result)));
return result;
}
@@ -472,6 +472,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Logon domain user */
NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ DOM_CRED *ret_creds,
const char *username, const char *password,
int logon_type)
{
@@ -486,6 +487,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
+ ZERO_STRUCT(dummy_rtn_creds);
/* Initialise parse structures */
@@ -498,8 +500,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
q.validation_level = validation_level;
- memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
- dummy_rtn_creds.timestamp.time = time(NULL);
+ if (ret_creds == NULL)
+ ret_creds = &dummy_rtn_creds;
ctr.switch_value = logon_type;
@@ -542,7 +544,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
- &clnt_creds, &dummy_rtn_creds, logon_type,
+ &clnt_creds, ret_creds, logon_type,
&ctr);
/* Marshall data and send request */
@@ -563,6 +565,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return results */
result = r.status;
+ memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
done:
prs_mem_free(&qbuf);
@@ -579,6 +582,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
**/
NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ DOM_CRED *ret_creds,
const char *username, const char *domain, const char *workstation,
const uint8 chal[8],
DATA_BLOB lm_response, DATA_BLOB nt_response,
@@ -598,6 +602,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
ZERO_STRUCT(q);
ZERO_STRUCT(r);
+ ZERO_STRUCT(dummy_rtn_creds);
workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
@@ -617,8 +622,8 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
q.validation_level = validation_level;
- memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
- dummy_rtn_creds.timestamp.time = time(NULL);
+ if (ret_creds == NULL)
+ ret_creds = &dummy_rtn_creds;
ctr.switch_value = NET_LOGON_TYPE;
@@ -629,7 +634,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
lm_response.data, lm_response.length, nt_response.data, nt_response.length);
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
- &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE,
+ &clnt_creds, ret_creds, NET_LOGON_TYPE,
&ctr);
/* Marshall data and send request */
@@ -659,6 +664,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
/* Return results */
result = r.status;
+ memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
done:
prs_mem_free(&qbuf);
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index a5cb6d425ee..a6a49dd3ebe 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -174,7 +174,8 @@ static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 l
Never on bind requests/responses.
****************************************************************************/
-static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len)
+static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
+ uint32 fragment_start, int len, int auth_len, int *pauth_padding_len)
{
/*
* The following is that length of the data we must sign or seal.
@@ -187,12 +188,14 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
/*
* The start of the data to sign/seal is just after the RPC headers.
*/
- char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
+ char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0);
BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0);
BOOL auth_schannel = (cli->saved_netlogon_pipe_fnum != 0);
+ *pauth_padding_len = 0;
+
DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s schannel %s\n",
len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal), BOOLSTR(auth_schannel)));
@@ -297,11 +300,33 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
if (auth_schannel) {
RPC_AUTH_NETSEC_CHK chk;
- char data[RPC_AUTH_NETSEC_CHK_LEN];
- char *dp = prs_data_p(rdata) + len - auth_len;
+ RPC_HDR_AUTH rhdr_auth;
+ char data[RPC_HDR_AUTH_LEN+RPC_AUTH_NETSEC_CHK_LEN];
+ char *dp = prs_data_p(rdata) + fragment_start + len -
+ RPC_HDR_AUTH_LEN - RPC_AUTH_NETSEC_CHK_LEN;
prs_struct auth_verf;
if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
+
+ if ( (auth_len == 12) &&
+ (cli->auth_info.seq_num == 0) ) {
+
+ /* This is the reply to our bind. Ok,
+ the sequence number can wrap
+ around. But this only means that
+ every 4 billion request we
+ misdetect a wrong length in a
+ reply. This is an error condition
+ which will lead to failure anyway
+ later.
+
+ The reply contains a
+ RPC_AUTH_VERIFIER with no content
+ (12 bytes), so ignore it.
+ */
+ return True;
+ }
+
DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
return False;
}
@@ -322,7 +347,19 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
/* The endinness must be preserved. JRA. */
prs_set_endian_data( &auth_verf, rdata->bigendian_data);
- prs_give_memory(&auth_verf, data, RPC_AUTH_NETSEC_CHK_LEN, False);
+ prs_give_memory(&auth_verf, data, sizeof(data), False);
+
+ if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
+ DEBUG(0, ("rpc_auth_pipe: Could not parse schannel auth header\n"));
+ return False;
+ }
+
+ if ((rhdr_auth.auth_type != NETSEC_AUTH_TYPE) ||
+ (rhdr_auth.auth_level != NETSEC_AUTH_LEVEL)) {
+ DEBUG(0, ("rpc_auth_pipe: Got wrong schannel auth type/level: %d/%d\n",
+ rhdr_auth.auth_type, rhdr_auth.auth_level));
+ return False;
+ }
if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) {
DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
@@ -336,6 +373,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
return False;
}
+ *pauth_padding_len = rhdr_auth.padding;
}
return True;
}
@@ -379,6 +417,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
char *prdata = NULL;
uint32 rdata_len = 0;
uint32 current_offset = 0;
+ uint32 fragment_start = 0;
uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024;
/* Create setup parameters - must be in native byte order. */
@@ -469,7 +508,10 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
*/
if (rhdr.auth_len != 0) {
- if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+ int auth_padding_len = 0;
+
+ if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
+ rhdr.auth_len, &auth_padding_len))
return False;
/*
* Drop the auth footers from the current offset.
@@ -477,7 +519,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
* The auth footers consist of the auth_data and the
* preceeding 8 byte auth_header.
*/
- current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
+ current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
}
/*
@@ -557,12 +599,17 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
if (!rpc_read(cli, rdata, len, &current_offset))
return False;
+ fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+
/*
* Verify any authentication footer.
*/
if (rhdr.auth_len != 0 ) {
- if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+ int auth_padding_len = 0;
+
+ if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
+ rhdr.auth_len, &auth_padding_len))
return False;
/*
* Drop the auth footers from the current offset.
@@ -570,7 +617,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
* preceeding 8 byte auth_header.
* We need this if there are more fragments.
*/
- current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
+ current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
}
}
@@ -650,6 +697,12 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse
init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL,
0x00, 1);
+
+ /* Use lp_workgroup() if domain not specified */
+
+ if (!domain || !domain[0])
+ domain = lp_workgroup();
+
init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);
/*
@@ -967,8 +1020,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
* be stored in the auth header.
*/
- if (auth_schannel)
- auth_padding = 8 - (send_size & 7);
+ if (auth_schannel) {
+ if (send_size % 8)
+ auth_padding = 8 - (send_size % 8);
+ }
data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size +
((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) +
@@ -1536,8 +1591,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
Open a session to the NETLOGON pipe using schannel.
****************************************************************************/
-BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
- int sec_chan)
+NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
+ const char *trust_password)
{
NTSTATUS result;
uint32 neg_flags = 0x000001ff;
@@ -1546,22 +1601,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
if (lp_client_schannel() != False)
neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- return False;
- }
-
- if (!secrets_init()) {
- DEBUG(3,("Failed to init secrets.tdb\n"));
- return False;
- }
-
result = cli_nt_setup_creds(cli, sec_chan, trust_password,
&neg_flags, 2);
if (!NT_STATUS_IS_OK(result)) {
cli_nt_session_close(cli);
- return False;
+ return result;
}
if ((lp_client_schannel() == True) &&
@@ -1569,12 +1614,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
DEBUG(3, ("Server did not offer schannel\n"));
cli_nt_session_close(cli);
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
if ((lp_client_schannel() == False) ||
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
- return True;
+ return NT_STATUS_OK;
}
/* Server offered schannel, so try it. */
@@ -1597,7 +1642,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
"Error was %s\n",
PIPE_NETLOGON, cli->desthost,
cli_errstr(cli)));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
cli->nt_pipe_fnum = (uint16)fnum;
@@ -1608,7 +1653,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
"Error was %s\n",
PIPE_NETLOGON, cli->desthost,
cli_errstr(cli)));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
cli->nt_pipe_fnum = (uint16)fnum;
@@ -1618,17 +1663,17 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
DEBUG(0,("Pipe hnd state failed. Error was %s\n",
cli_errstr(cli)));
cli_close(cli, cli->nt_pipe_fnum);
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
}
if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) {
DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
cli_close(cli, cli->nt_pipe_fnum);
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
- return True;
+ return NT_STATUS_OK;
}
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index 767c6a12b25..4fe8fba7b0b 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -1000,6 +1000,8 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
+ *num_entries = 0;
+
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index 7ff2aa7d01d..f620845d3b3 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -2219,21 +2219,18 @@ BOOL lsa_io_r_query_info2(const char *desc, LSA_R_QUERY_INFO2 *r_c,
if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
return False;
-
- if (r_c->ptr != 0) {
- if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
+ if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
+ return False;
+ switch(r_c->info_class) {
+ case 0x000c:
+ if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
+ ps, depth))
return False;
- switch(r_c->info_class) {
- case 0x000c:
- if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
- ps, depth))
- return False;
break;
- default:
- DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
- r_c->info_class));
- return False;
- }
+ default:
+ DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
+ r_c->info_class));
+ return False;
}
if(!prs_align(ps))
@@ -2304,19 +2301,6 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr
return True;
}
-/*******************************************************************
- Inits an LSA_R_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-void init_r_enum_acct_rights(LSA_R_ENUM_ACCT_RIGHTS *q_r,
- uint32 count,
- const char **rights)
-{
- DEBUG(5, ("init_r_enum_acct_rights\n"));
-
- q_r->count = count;
- init_unistr2_array(&q_r->rights, count, rights);
-}
-
/*******************************************************************
Inits an LSA_Q_ADD_ACCT_RIGHTS structure.
@@ -2332,6 +2316,7 @@ void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q,
q_q->pol = *hnd;
init_dom_sid2(&q_q->sid, sid);
init_unistr2_array(&q_q->rights, count, rights);
+ q_q->count = 5;
}
@@ -2372,15 +2357,6 @@ BOOL lsa_io_r_add_acct_rights(const char *desc, LSA_R_ADD_ACCT_RIGHTS *r_c, prs_
return True;
}
-/*******************************************************************
- Inits an LSA_R_ADD_ACCT_RIGHTS structure.
-********************************************************************/
-void init_r_add_acct_rights(LSA_R_ADD_ACCT_RIGHTS *q_r)
-{
- DEBUG(5, ("init_r_add_acct_rights\n"));
- /* oh what a silly function! */
-}
-
/*******************************************************************
Inits an LSA_Q_REMOVE_ACCT_RIGHTS structure.
@@ -2398,6 +2374,7 @@ void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q,
init_dom_sid2(&q_q->sid, sid);
q_q->removeall = removeall;
init_unistr2_array(&q_q->rights, count, rights);
+ q_q->count = 5;
}
@@ -2428,7 +2405,7 @@ BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q
}
/*******************************************************************
-reads or writes a LSA_R_REMOVE_ACCT_RIGHTS structure.
+reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure.
********************************************************************/
BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c, prs_struct *ps, int depth)
{
@@ -2440,89 +2417,3 @@ BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c
return True;
}
-
-/*******************************************************************
- Inits an LSA_R_REMOVE_ACCT_RIGHTS structure.
-********************************************************************/
-void init_r_remove_acct_rights(LSA_R_REMOVE_ACCT_RIGHTS *q_r)
-{
- DEBUG(5, ("init_r_remove_acct_rights\n"));
-}
-
-/*******************************************************************
- Inits an LSA_Q_ENUM_ACCT_WITH_RIGHT structure.
-********************************************************************/
-void init_q_enum_acct_with_right(LSA_Q_ENUM_ACCT_WITH_RIGHT *q_q,
- POLICY_HND *hnd,
- const char *right)
-{
- DEBUG(5, ("init_q_enum_acct_with_right\n"));
-
- q_q->pol = *hnd;
- init_unistr2(&q_q->right, right, strlen(right));
- init_str_hdr(&q_q->right_hdr,
- q_q->right.uni_max_len*2,
- q_q->right.uni_max_len*2, right?1:0);
-}
-
-
-/*******************************************************************
-reads or writes a LSA_Q_ENUM_ACCT_WITH_RIGHT structure.
-********************************************************************/
-BOOL lsa_io_q_enum_acct_with_right(const char *desc, LSA_Q_ENUM_ACCT_WITH_RIGHT *q_q, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_q_enum_acct_with_right");
- depth++;
-
- if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
-
- if (!prs_uint32("ref_id ", ps, depth, &q_q->right_hdr.buffer))
- return False;
-
- if (UNMARSHALLING(ps) && q_q->right_hdr.buffer == 0) {
- return True;
- }
-
- if (!smb_io_strhdr("", &q_q->right_hdr, ps, depth))
- return False;
-
- if (!smb_io_unistr2("", &q_q->right, q_q->right_hdr.buffer, ps, depth))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
-reads or writes a LSA_R_ENUM_ACCT_WITH_RIGHT structure.
-********************************************************************/
-BOOL lsa_io_r_enum_acct_with_right(const char *desc, LSA_R_ENUM_ACCT_WITH_RIGHT *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_enum_acct_with_right");
- depth++;
-
- if (!prs_uint32("count ", ps, depth, &r_c->count))
- return False;
-
- if (!smb_io_sid_array("sids ", &r_c->sids, ps, depth))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits an LSA_R_ENUM_ACCT_WITH_RIGHT structure.
-********************************************************************/
-void init_r_enum_acct_with_right(LSA_R_ENUM_ACCT_WITH_RIGHT *r_c,
- uint32 count,
- DOM_SID *sids)
-{
- DEBUG(5, ("init_r_enum_acct_with_right\n"));
-
- r_c->count = count;
- init_sid_array(&r_c->sids, count, sids);
-}
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index a39e3391bbe..17a96fff80c 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -1122,78 +1122,6 @@ BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps
}
-/*
- initialise a SID_ARRAY from a list of sids
-*/
-BOOL init_sid_array(SID_ARRAY *array,
- uint32 count, DOM_SID *sids)
-{
- unsigned int i;
-
- array->count = count;
- array->ref_id = count?1:0;
- if (array->count == 0) {
- return True;
- }
-
- array->sids = (SID_ARRAY_EL *)talloc_zero(get_talloc_ctx(), count * sizeof(SID_ARRAY_EL));
- if (!array->sids) {
- return False;
- }
-
- for (i=0;i<count;i++) {
- array->sids[i].ref_id = 1;
- init_dom_sid2(&array->sids[i].sid, &sids[i]);
- }
-
- return True;
-}
-
-
-/*******************************************************************
- Reads or writes a SID_ARRAY structure.
-********************************************************************/
-BOOL smb_io_sid_array(const char *desc, SID_ARRAY *array, prs_struct *ps, int depth)
-{
- unsigned int i;
-
- prs_debug(ps, depth, desc, "smb_io_sid_array");
- depth++;
-
- if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
- return False;
-
- if (! array->ref_id) {
- return True;
- }
-
- if(!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (array->count == 0) {
- return True;
- }
-
- if (UNMARSHALLING(ps)) {
- array->sids = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->sids[0]));
- }
- if (! array->sids) {
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if(!prs_uint32("ref_id", ps, depth, &array->sids[i].ref_id))
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if (!smb_io_dom_sid2("sid", &array->sids[i].sid, ps, depth))
- return False;
- }
-
- return True;
-}
-
/*******************************************************************
Inits a DOM_RID2 structure.
********************************************************************/
@@ -1289,22 +1217,22 @@ void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
Inits a DOM_CLNT_SRV structure.
********************************************************************/
-static void init_clnt_srv(DOM_CLNT_SRV *dlog, const char *logon_srv, const char *comp_name)
+static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
{
DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
if (logon_srv != NULL) {
- dlog->undoc_buffer = 1;
- init_unistr2(&dlog->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
+ logcln->undoc_buffer = 1;
+ init_unistr2(&logcln->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
} else {
- dlog->undoc_buffer = 0;
+ logcln->undoc_buffer = 0;
}
if (comp_name != NULL) {
- dlog->undoc_buffer2 = 1;
- init_unistr2(&dlog->uni_comp_name, comp_name, strlen(comp_name)+1);
+ logcln->undoc_buffer2 = 1;
+ init_unistr2(&logcln->uni_comp_name, comp_name, strlen(comp_name)+1);
} else {
- dlog->undoc_buffer2 = 0;
+ logcln->undoc_buffer2 = 0;
}
}
@@ -1312,9 +1240,9 @@ static void init_clnt_srv(DOM_CLNT_SRV *dlog, const char *logon_srv, const char
Inits or writes a DOM_CLNT_SRV structure.
********************************************************************/
-static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps, int depth)
+static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
{
- if (dlog == NULL)
+ if (logcln == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_clnt_srv");
@@ -1323,22 +1251,22 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer ", ps, depth, &dlog->undoc_buffer))
+ if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
return False;
- if (dlog->undoc_buffer != 0) {
- if(!smb_io_unistr2("unistr2", &dlog->uni_logon_srv, dlog->undoc_buffer, ps, depth))
+ if (logcln->undoc_buffer != 0) {
+ if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer2", ps, depth, &dlog->undoc_buffer2))
+ if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
return False;
- if (dlog->undoc_buffer2 != 0) {
- if(!smb_io_unistr2("unistr2", &dlog->uni_comp_name, dlog->undoc_buffer2, ps, depth))
+ if (logcln->undoc_buffer2 != 0) {
+ if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
return False;
}
@@ -1349,28 +1277,28 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps
Inits a DOM_LOG_INFO structure.
********************************************************************/
-void init_log_info(DOM_LOG_INFO *dlog, const char *logon_srv, const char *acct_name,
+void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name)
{
DEBUG(5,("make_log_info %d\n", __LINE__));
- dlog->undoc_buffer = 1;
+ loginfo->undoc_buffer = 1;
- init_unistr2(&dlog->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
- init_unistr2(&dlog->uni_acct_name, acct_name, strlen(acct_name)+1);
+ init_unistr2(&loginfo->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
+ init_unistr2(&loginfo->uni_acct_name, acct_name, strlen(acct_name)+1);
- dlog->sec_chan = sec_chan;
+ loginfo->sec_chan = sec_chan;
- init_unistr2(&dlog->uni_comp_name, comp_name, strlen(comp_name)+1);
+ init_unistr2(&loginfo->uni_comp_name, comp_name, strlen(comp_name)+1);
}
/*******************************************************************
Reads or writes a DOM_LOG_INFO structure.
********************************************************************/
-BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *dlog, prs_struct *ps, int depth)
+BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
{
- if (dlog == NULL)
+ if (loginfo == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_log_info");
@@ -1379,18 +1307,18 @@ BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *dlog, prs_struct *ps, int d
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer", ps, depth, &dlog->undoc_buffer))
+ if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
return False;
- if(!smb_io_unistr2("unistr2", &dlog->uni_logon_srv, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
return False;
- if(!smb_io_unistr2("unistr2", &dlog->uni_acct_name, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
return False;
- if(!prs_uint16("sec_chan", ps, depth, &dlog->sec_chan))
+ if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
return False;
- if(!smb_io_unistr2("unistr2", &dlog->uni_comp_name, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
return False;
return True;
@@ -1529,21 +1457,21 @@ BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, in
Inits a DOM_LOGON_ID structure.
********************************************************************/
-void init_logon_id(DOM_LOGON_ID *dlog, uint32 log_id_low, uint32 log_id_high)
+void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
{
DEBUG(5,("make_logon_id: %d\n", __LINE__));
- dlog->low = log_id_low;
- dlog->high = log_id_high;
+ logonid->low = log_id_low;
+ logonid->high = log_id_high;
}
/*******************************************************************
Reads or writes a DOM_LOGON_ID structure.
********************************************************************/
-BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *dlog, prs_struct *ps, int depth)
+BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
{
- if (dlog == NULL)
+ if (logonid == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_logon_id");
@@ -1552,9 +1480,9 @@ BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *dlog, prs_struct *ps, int d
if(!prs_align(ps))
return False;
- if(!prs_uint32("low ", ps, depth, &dlog->low ))
+ if(!prs_uint32("low ", ps, depth, &logonid->low ))
return False;
- if(!prs_uint32("high", ps, depth, &dlog->high))
+ if(!prs_uint32("high", ps, depth, &logonid->high))
return False;
return True;
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 1a14915c9f5..7d04eace230 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1808,9 +1808,9 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
return False;
- if (prs_offset(ps) + 40 > prs_data_size(ps))
+ if (ps->data_offset + 40 > ps->buffer_size)
return False;
- prs_set_offset(ps, prs_offset(ps) + 40);
+ ps->data_offset += 40;
if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
info->hdr_dom_name.buffer, ps, depth))
@@ -1847,9 +1847,9 @@ static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
return False;
- if (prs_offset(ps) + 48 > prs_data_size(ps))
+ if (ps->data_offset + 48 > ps->buffer_size)
return False;
- prs_set_offset(ps, prs_offset(ps) + 48);
+ ps->data_offset += 48;
if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
info->hdr_grp_name.buffer, ps, depth))
@@ -2128,13 +2128,13 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
uint32 len = 0x44;
if (!prs_uint32("pwd_len", ps, depth, &len))
return False;
- old_offset = prs_offset(ps);
+ old_offset = ps->data_offset;
if (len > 0)
{
if (ps->io)
{
/* reading */
- if (!prs_hash1(ps, prs_offset(ps), sess_key))
+ if (!prs_hash1(ps, ps->data_offset, sess_key, len))
return False;
}
if (!net_io_sam_passwd_info("pass", &info->pass,
@@ -2144,13 +2144,13 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
if (!ps->io)
{
/* writing */
- if (!prs_hash1(ps, old_offset, sess_key))
+ if (!prs_hash1(ps, old_offset, sess_key, len))
return False;
}
}
- if (old_offset + len > prs_data_size(ps))
+ if (old_offset + len > ps->buffer_size)
return False;
- prs_set_offset(ps, old_offset + len);
+ ps->data_offset = old_offset + len;
}
if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
info->hdr_sec_desc.buffer, ps, depth))
@@ -2185,9 +2185,9 @@ static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * inf
if (!prs_uint32("num_members", ps, depth, &info->num_members))
return False;
- if (prs_offset(ps) + 16 > prs_data_size(ps))
+ if (ps->data_offset + 16 > ps->buffer_size)
return False;
- prs_set_offset(ps, prs_offset(ps) + 16);
+ ps->data_offset += 16;
if (info->ptr_rids != 0)
{
@@ -2267,9 +2267,9 @@ static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
return False;
- if (prs_offset(ps) + 40 > prs_data_size(ps))
+ if (ps->data_offset + 40 > ps->buffer_size)
return False;
- prs_set_offset(ps, prs_offset(ps) + 40);
+ ps->data_offset += 40;
if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
info->hdr_als_name.buffer, ps, depth))
@@ -2307,9 +2307,9 @@ static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * inf
if (info->ptr_members != 0)
{
- if (prs_offset(ps) + 16 > prs_data_size(ps))
+ if (ps->data_offset + 16 > ps->buffer_size)
return False;
- prs_set_offset(ps, prs_offset(ps) + 16);
+ ps->data_offset += 16;
if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
return False;
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index e0a75d73825..88150c718b6 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -1316,7 +1316,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
/*******************************************************************
hash a stream.
********************************************************************/
-BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
+BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
{
char *q;
@@ -1326,12 +1326,12 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
#ifdef DEBUG_PASSWORD
DEBUG(100, ("prs_hash1\n"));
dump_data(100, sess_key, 16);
- dump_data(100, q, 68);
+ dump_data(100, q, len);
#endif
- SamOEMhash((uchar *) q, sess_key, 68);
+ SamOEMhash((uchar *) q, sess_key, len);
#ifdef DEBUG_PASSWORD
- dump_data(100, q, 68);
+ dump_data(100, q, len);
#endif
return True;
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index ac1e9da61be..47bf3f390dd 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -4598,7 +4598,6 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
prs_struct *ps, int depth)
{
uint32 i;
- uint32 ptr_sid[MAX_LOOKUP_SIDS];
if (r_u == NULL)
return False;
@@ -4614,28 +4613,31 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
return False;
- if (r_u->ptr != 0) {
- SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids);
-
- if (r_u->num_sids != 0) {
- if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1))
- return False;
-
- for (i = 0; i < r_u->num_sids1; i++) {
- ptr_sid[i] = 1;
- if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i]))
- return False;
- }
+ if (r_u->ptr != 0 && r_u->num_sids != 0) {
+ uint32 *ptr_sid = NULL;
- if (UNMARSHALLING(ps)) {
- r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2));
- }
+ if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1))
+ return False;
- for (i = 0; i < r_u->num_sids1; i++) {
- if (ptr_sid[i] != 0) {
- if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth))
- return False;
- }
+ ptr_sid = talloc(ps->mem_ctx, sizeof(uint32) * r_u->num_sids1);
+ if (!ptr_sid) {
+ return False;
+ }
+
+ for (i = 0; i < r_u->num_sids1; i++) {
+ ptr_sid[i] = 1;
+ if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i]))
+ return False;
+ }
+
+ if (UNMARSHALLING(ps)) {
+ r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2));
+ }
+
+ for (i = 0; i < r_u->num_sids1; i++) {
+ if (ptr_sid[i] != 0) {
+ if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth))
+ return False;
}
}
}
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index 081173cf8de..870402db5d3 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -48,7 +48,7 @@ BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "sec_io_access");
depth++;
- if(!prs_uint32("mask", ps, depth, &(t->mask)))
+ if(!prs_uint32("mask", ps, depth, &t->mask))
return False;
return True;
@@ -579,8 +579,6 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
{
SEC_DESC *dst;
uint32 offset = 0;
- uint32 offset_sid = SEC_DESC_HEADER_SIZE;
- uint32 offset_acl = 0;
*sd_size = 0;
@@ -610,58 +608,33 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
goto error_exit;
- offset = 0;
+ offset = SEC_DESC_HEADER_SIZE;
/*
* Work out the linearization sizes.
*/
- if (dst->owner_sid != NULL) {
-
- if (offset == 0)
- offset = SEC_DESC_HEADER_SIZE;
-
- offset += sid_size(dst->owner_sid);
- }
-
- if (dst->grp_sid != NULL) {
-
- if (offset == 0)
- offset = SEC_DESC_HEADER_SIZE;
-
- offset += sid_size(dst->grp_sid);
- }
if (dst->sacl != NULL) {
-
- offset_acl = SEC_DESC_HEADER_SIZE;
-
- dst->off_sacl = offset_acl;
- offset_acl += dst->sacl->size;
- offset += dst->sacl->size;
- offset_sid += dst->sacl->size;
+ dst->off_sacl = offset;
+ offset += dst->sacl->size;
}
if (dst->dacl != NULL) {
-
- if (offset_acl == 0)
- offset_acl = SEC_DESC_HEADER_SIZE;
-
- dst->off_dacl = offset_acl;
- offset_acl += dst->dacl->size;
- offset += dst->dacl->size;
- offset_sid += dst->dacl->size;
+ dst->off_dacl = offset;
+ offset += dst->dacl->size;
}
- *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset);
+ if (dst->owner_sid != NULL) {
+ dst->off_owner_sid = offset;
+ offset += sid_size(dst->owner_sid);
+ }
- if (dst->owner_sid != NULL)
- dst->off_owner_sid = offset_sid;
-
- /* sid_size() returns 0 if the sid is NULL so this is ok */
-
- if (dst->grp_sid != NULL)
- dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid);
+ if (dst->grp_sid != NULL) {
+ dst->off_grp_sid = offset;
+ offset += sid_size(dst->grp_sid);
+ }
+ *sd_size = (size_t)offset;
return dst;
error_exit:
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 1c4ef6c8e6f..679cfb73bba 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -642,176 +642,45 @@ static BOOL api_lsa_query_info2(pipes_struct *p)
}
-
-/***************************************************************************
- api_lsa_enum_acctrights
- ***************************************************************************/
-static BOOL api_lsa_enum_acct_rights(pipes_struct *p)
-{
- LSA_Q_ENUM_ACCT_RIGHTS q_u;
- LSA_R_ENUM_ACCT_RIGHTS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_enum_acct_rights("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_enum_acct_rights: failed to unmarshall LSA_Q_ENUM_ACCT_RIGHTS.\n"));
- return False;
- }
-
- r_u.status = _lsa_enum_acct_rights(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_enum_acct_rights("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_enum_acct_rights: Failed to marshall LSA_R_ENUM_ACCT_RIGHTS.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/***************************************************************************
- api_lsa_enum_acct_with_right
- ***************************************************************************/
-static BOOL api_lsa_enum_acct_with_right(pipes_struct *p)
-{
- LSA_Q_ENUM_ACCT_WITH_RIGHT q_u;
- LSA_R_ENUM_ACCT_WITH_RIGHT r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_enum_acct_with_right("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_enum_acct_with_right: failed to unmarshall LSA_Q_ENUM_ACCT_WITH_RIGHT.\n"));
- return False;
- }
-
- r_u.status = _lsa_enum_acct_with_right(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_enum_acct_with_right("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_enum_acct_with_right: Failed to marshall LSA_R_ENUM_ACCT_WITH_RIGHT.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/***************************************************************************
- api_lsa_add_acctrights
- ***************************************************************************/
-static BOOL api_lsa_add_acct_rights(pipes_struct *p)
-{
- LSA_Q_ADD_ACCT_RIGHTS q_u;
- LSA_R_ADD_ACCT_RIGHTS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_add_acct_rights("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_add_acct_rights: failed to unmarshall LSA_Q_ADD_ACCT_RIGHTS.\n"));
- return False;
- }
-
- r_u.status = _lsa_add_acct_rights(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_add_acct_rights("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_add_acct_rights: Failed to marshall LSA_R_ADD_ACCT_RIGHTS.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/***************************************************************************
- api_lsa_remove_acctrights
- ***************************************************************************/
-static BOOL api_lsa_remove_acct_rights(pipes_struct *p)
-{
- LSA_Q_REMOVE_ACCT_RIGHTS q_u;
- LSA_R_REMOVE_ACCT_RIGHTS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_remove_acct_rights("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_remove_acct_rights: failed to unmarshall LSA_Q_REMOVE_ACCT_RIGHTS.\n"));
- return False;
- }
-
- r_u.status = _lsa_remove_acct_rights(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_remove_acct_rights("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_remove_acct_rights: Failed to marshall LSA_R_REMOVE_ACCT_RIGHTS.\n"));
- return False;
- }
-
- return True;
-}
-
-
/***************************************************************************
\PIPE\ntlsa commands
***************************************************************************/
-
NTSTATUS rpc_lsa_init(void)
{
- static const struct api_struct api_lsa_cmds[] =
- {
- { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
- { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
- { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
- { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
- { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
- { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
- { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
- { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
- { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
- { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
- { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
- { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser },
- { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
- { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
- { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount },
- { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount },
- { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
- { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
- { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
- { "LSA_ENUMACCTRIGHTS" , LSA_ENUMACCTRIGHTS , api_lsa_enum_acct_rights },
- { "LSA_ENUMACCTWITHRIGHT", LSA_ENUMACCTWITHRIGHT, api_lsa_enum_acct_with_right },
- { "LSA_ADDACCTRIGHTS" , LSA_ADDACCTRIGHTS , api_lsa_add_acct_rights },
- { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights},
- /* be careful of the adding of new RPC's. See commentrs below about
- * ADS DC capabilities */
- { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 },
- };
-
+static const struct api_struct api_lsa_cmds[] =
+{
+ { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
+ { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
+ { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
+ { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
+ { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
+ { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
+ { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
+ { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
+ { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
+ { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
+ { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
+ { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser },
+ { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
+ { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
+ { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount },
+ { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount },
+ { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
+ { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
+ { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
+ /* be careful of the adding of new RPC's. See commentrs below about
+ ADS DC capabilities */
+ { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 }
+};
/*
* NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
* these calls are always last and that you decrement by the amount of calls
* to disable.
- */
+ */
int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
- funcs -= 1;
+ funcs -= 1;
}
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 3581be01819..2a24d7faa57 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -547,7 +547,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
- name = lp_workgroup();
+ name = get_global_sam_name();
sid = get_global_sam_sid();
break;
case ROLE_DOMAIN_MEMBER:
@@ -573,23 +573,8 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF
return NT_STATUS_ACCESS_DENIED;
/* Request PolicyAccountDomainInformation. */
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- name = lp_workgroup();
- sid = get_global_sam_sid();
- break;
- case ROLE_DOMAIN_MEMBER:
- name = global_myname();
- sid = get_global_sam_sid();
- break;
- case ROLE_STANDALONE:
- name = global_myname();
- sid = get_global_sam_sid();
- break;
- default:
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
+ name = get_global_sam_name();
+ sid = get_global_sam_sid();
init_dom_query(&r_u->dom.id5, name, sid);
break;
case 0x06:
@@ -645,7 +630,7 @@ NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_
num_entries = MAX_LOOKUP_SIDS;
DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries));
}
-
+
ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF));
names = (LSA_TRANS_NAME_ENUM *)talloc_zero(p->mem_ctx, sizeof(LSA_TRANS_NAME_ENUM));
@@ -1240,7 +1225,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
- nb_name = lp_workgroup();
+ nb_name = get_global_sam_name();
/* ugly temp hack for these next two */
/* This should be a 'netbios domain -> DNS domain' mapping */
@@ -1273,140 +1258,3 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I
return r_u->status;
}
-
-
-/***************************************************************************
- For a given SID, enumerate all the privilege this account has.
- ***************************************************************************/
-NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
-{
- struct lsa_info *info=NULL;
- char **rights = NULL;
- int num_rights = 0;
- int i;
-
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- r_u->status = privilege_enum_account_rights(&q_u->sid.sid, &num_rights, &rights);
-
- init_r_enum_acct_rights(r_u, num_rights, (const char **)rights);
-
- for (i=0;i<num_rights;i++) {
- free(rights[i]);
- }
- safe_free(rights);
-
- return r_u->status;
-}
-
-/***************************************************************************
-return a list of SIDs for a particular privilege
- ***************************************************************************/
-NTSTATUS _lsa_enum_acct_with_right(pipes_struct *p,
- LSA_Q_ENUM_ACCT_WITH_RIGHT *q_u,
- LSA_R_ENUM_ACCT_WITH_RIGHT *r_u)
-{
- struct lsa_info *info=NULL;
- char *right;
- DOM_SID *sids = NULL;
- uint32 count = 0;
-
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- right = unistr2_tdup(p->mem_ctx, &q_u->right);
-
- DEBUG(5,("lsa_enum_acct_with_right on right %s\n", right));
-
- r_u->status = privilege_enum_account_with_right(right, &count, &sids);
-
- init_r_enum_acct_with_right(r_u, count, sids);
-
- safe_free(sids);
-
- return r_u->status;
-}
-
-/***************************************************************************
- add privileges to a acct by SID
- ***************************************************************************/
-NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
-{
- struct lsa_info *info=NULL;
- int i;
-
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(5,("_lsa_add_acct_rights to %s (%d rights)\n",
- sid_string_static(&q_u->sid.sid), q_u->rights.count));
-
- for (i=0;i<q_u->rights.count;i++) {
- DEBUG(5,("\t%s\n", unistr2_static(&q_u->rights.strings[i].string)));
- }
-
-
- for (i=0;i<q_u->rights.count;i++) {
- r_u->status = privilege_add_account_right(unistr2_static(&q_u->rights.strings[i].string),
- &q_u->sid.sid);
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(2,("Failed to add right '%s'\n",
- unistr2_static(&q_u->rights.strings[i].string)));
- break;
- }
- }
-
- init_r_add_acct_rights(r_u);
-
- return r_u->status;
-}
-
-
-/***************************************************************************
- remove privileges from a acct by SID
- ***************************************************************************/
-NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
-{
- struct lsa_info *info=NULL;
- int i;
-
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
-
- DEBUG(5,("_lsa_remove_acct_rights from %s all=%d (%d rights)\n",
- sid_string_static(&q_u->sid.sid),
- q_u->removeall,
- q_u->rights.count));
-
- for (i=0;i<q_u->rights.count;i++) {
- DEBUG(5,("\t%s\n", unistr2_static(&q_u->rights.strings[i].string)));
- }
-
- for (i=0;i<q_u->rights.count;i++) {
- r_u->status = privilege_remove_account_right(unistr2_static(&q_u->rights.strings[i].string),
- &q_u->sid.sid);
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(2,("Failed to remove right '%s'\n",
- unistr2_static(&q_u->rights.strings[i].string)));
- break;
- }
- }
-
- init_r_remove_acct_rights(r_u);
-
- return r_u->status;
-}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index fc29df39761..ee496126ada 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -2575,14 +2575,7 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN
return r_u->status;
}
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- name = lp_workgroup();
- break;
- default:
- name = global_myname();
- }
+ name = get_global_sam_name();
fstrcpy(dom[0],name);
strupper(dom[0]);
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 24459a26f09..92b1481ab82 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -1025,9 +1025,9 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
}
if ( sending_msg_count ) {
- cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd,
- data_len, data, p->notify.change, 0 );
- }
+ cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd,
+ data_len, data, p->notify.change, 0 );
+ }
}
done:
@@ -7609,12 +7609,12 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
{
pstring path;
pstring long_archi;
- pstring short_archi;
+ const char *short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
- if (get_short_archi(short_archi, long_archi)==False)
+ if (!(short_archi = get_short_archi(long_archi)))
return WERR_INVALID_ENVIRONMENT;
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
@@ -8440,7 +8440,7 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
int i=0;
BOOL found=False;
@@ -8453,7 +8453,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin
}
for (i=0; i<count && found==False; i++) {
- if (queue[i].job==(int)jobid)
+ if ((*queue)[i].job==(int)jobid)
found=True;
}
@@ -8463,7 +8463,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin
return WERR_INVALID_PARAM;
}
- fill_job_info_1(info_1, &(queue[i-1]), i, snum);
+ fill_job_info_1(info_1, &((*queue)[i-1]), i, snum);
*needed += spoolss_size_job_info_1(info_1);
@@ -8485,7 +8485,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
int i = 0;
BOOL found = False;
@@ -8506,7 +8506,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin
for ( i=0; i<count && found==False; i++ )
{
- if (queue[i].job == (int)jobid)
+ if ((*queue)[i].job == (int)jobid)
found = True;
}
@@ -8537,7 +8537,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin
}
}
- fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter, devmode);
+ fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
*needed += spoolss_size_job_info_2(info_2);
@@ -8601,11 +8601,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
switch ( level ) {
case 1:
- wstatus = getjob_level_1(queue, count, snum, jobid,
+ wstatus = getjob_level_1(&queue, count, snum, jobid,
buffer, offered, needed);
break;
case 2:
- wstatus = getjob_level_2(queue, count, snum, jobid,
+ wstatus = getjob_level_2(&queue, count, snum, jobid,
buffer, offered, needed);
break;
default:
@@ -9143,12 +9143,12 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
{
pstring path;
pstring long_archi;
- pstring short_archi;
+ const char *short_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
- if (get_short_archi(short_archi, long_archi)==False)
+ if (!(short_archi = get_short_archi(long_archi)))
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index 4d9130fb970..57ba055aefa 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -1840,8 +1840,6 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
struct current_user user;
connection_struct *conn = NULL;
BOOL became_user = False;
- fstring dev;
- fstrcpy(dev, "A:");
ZERO_STRUCT(st);
@@ -1855,7 +1853,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
get_current_user(&user, p);
become_root();
- conn = make_connection(qualname, null_pw, dev, user.vuid, &nt_status);
+ conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
@@ -1889,7 +1887,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
}
}
- sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
+ sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
if (sd_size == 0) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
@@ -1945,12 +1943,9 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
struct current_user user;
connection_struct *conn = NULL;
BOOL became_user = False;
- fstring dev;
- fstrcpy(dev, "A:");
ZERO_STRUCT(st);
-
r_u->status = WERR_OK;
unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
@@ -1961,7 +1956,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
get_current_user(&user, p);
become_root();
- conn = make_connection(qualname, null_pw, dev, user.vuid, &nt_status);
+ conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
@@ -1996,7 +1991,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
}
}
- ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
+ ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
if (ret == False) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index f96ccaef672..c43eb22375e 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -194,7 +194,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
break;
}
- free(groups);
+ if(num_groups) free(groups);
/* now check for the user's gid (the primary group rid) */
for (i=0; i<cur_rid && grid!=rids[i]; i++)
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 808ef50a455..db74370bc0b 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -543,50 +543,6 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
}
-/* Enumerate the accounts with a specific right */
-
-static NTSTATUS cmd_lsa_enum_acct_with_right(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- POLICY_HND dom_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_SID *sids;
- uint32 count;
- const char *right;
-
- int i;
-
- if (argc != 2 ) {
- printf("Usage: %s <RIGHT>\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- right = argv[1];
-
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &dom_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_enum_account_with_right(cli, mem_ctx, &dom_pol, right, &count, &sids);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- printf("found %d SIDs for '%s'\n", count, right);
-
- for (i = 0; i < count; i++) {
- printf("\t%s\n", sid_string_static(&sids[i]));
- }
-
- done:
- return result;
-}
-
-
/* add some privileges to a SID via LsaAddAccountRights */
static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli,
@@ -750,7 +706,6 @@ struct cmd_set lsarpc_commands[] = {
{ "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, "Enumerate the LSA SIDS", "" },
{ "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID", "" },
{ "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, "Enumerate the rights of an SID", "" },
- { "lsaenumacctwithright",RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_with_right,NULL, PI_LSARPC,"Enumerate accounts with a right", "" },
{ "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, "Add rights to an account", "" },
{ "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" },
{ "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookupprivvalue, NULL, PI_LSARPC, "Get a privilege value given its name", "" },
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 32fa9c3699f..0ec78a06734 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -275,6 +275,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
const char *username, *password;
uint32 neg_flags = 0x000001ff;
int auth_level = 2;
+ DOM_CRED ret_creds;
/* Check arguments */
@@ -299,7 +300,13 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
/* Perform the sam logon */
- result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type);
+ ZERO_STRUCT(ret_creds);
+
+ result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
+
+ clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
+
+ result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
if (!NT_STATUS_IS_OK(result))
goto done;
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 3ce7f9e6ac8..e4ff06a35ec 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -54,7 +54,7 @@ static const struct table_node archi_table[]= {
function to do the mapping between the long architecture name and
the short one.
****************************************************************************/
-BOOL get_short_archi(char *short_archi, const char *long_archi)
+static const char *cmd_spoolss_get_short_archi(const char *long_archi)
{
int i=-1;
@@ -66,18 +66,17 @@ BOOL get_short_archi(char *short_archi, const char *long_archi)
if (archi_table[i].long_archi==NULL) {
DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
- return False;
+ return NULL;
}
/* this might be client code - but shouldn't this be an fstrcpy etc? */
- StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", short_archi));
+ DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
+ DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
- return True;
+ return archi_table[i].short_archi;
}
#if 0
@@ -1153,7 +1152,7 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des
parameter because two consecutive delimiters
will not return an empty string. See man strtok(3)
for details */
- if (StrCaseCmp(ptr, "NULL") == 0)
+ if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
ptr = NULL;
if (dest != NULL)
@@ -1227,7 +1226,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
uint32 level = 3;
PRINTER_DRIVER_CTR ctr;
DRIVER_INFO_3 info3;
- fstring arch;
+ const char *arch;
fstring driver_name;
/* parse the command arguements */
@@ -1243,7 +1242,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
/* Fill in the DRIVER_INFO_3 struct */
ZERO_STRUCT(info3);
- if (!get_short_archi(arch, argv[1]))
+ if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
{
printf ("Error Unknown architechture [%s]\n", argv[1]);
return WERR_INVALID_PARAM;
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index b01e2d694c5..a1b0a8cd345 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -391,6 +391,14 @@ static NTSTATUS do_cmd(struct cli_state *cli,
/* Open pipe */
+ if (cmd_entry->pipe_idx != -1) {
+ if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
+ DEBUG(0, ("Could not initialise %s\n",
+ get_pipe_name_from_index(cmd_entry->pipe_idx)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
if (cmd_entry->pipe_idx == PI_NETLOGON) {
uchar trust_password[16];
uint32 sec_channel_type;
@@ -401,19 +409,11 @@ static NTSTATUS do_cmd(struct cli_state *cli,
return NT_STATUS_UNSUCCESSFUL;
}
- if (!cli_nt_open_netlogon(cli, trust_password,
- sec_channel_type)) {
+ if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel_type,
+ trust_password))) {
DEBUG(0, ("Could not initialise NETLOGON pipe\n"));
return NT_STATUS_UNSUCCESSFUL;
}
- } else {
- if (cmd_entry->pipe_idx != -1) {
- if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(cmd_entry->pipe_idx)));
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
}
/* Run command */
diff --git a/source/sam/idmap.c b/source/sam/idmap.c
index 9695e7b764e..d031c49e257 100644
--- a/source/sam/idmap.c
+++ b/source/sam/idmap.c
@@ -24,49 +24,69 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
-static struct {
-
+struct idmap_function_entry {
const char *name;
- /* Function to create a member of the idmap_methods list */
- NTSTATUS (*reg_meth)(struct idmap_methods **methods);
struct idmap_methods *methods;
-
-} remote_idmap_functions[] = {
- { NULL, NULL, NULL }
+ struct idmap_function_entry *prev,*next;
};
+static struct idmap_function_entry *backends = NULL;
+
static struct idmap_methods *local_map;
static struct idmap_methods *remote_map;
static void lazy_initialize_idmap(void)
{
static BOOL initialized = False;
- if (initialized) return;
- idmap_init();
- initialized = True;
-}
-
+ if(!initialized) {
+ idmap_init();
+ initialized = True;
+ }
+}
static struct idmap_methods *get_methods(const char *name)
{
- int i = 0;
- struct idmap_methods *ret = NULL;
+ struct idmap_function_entry *entry = backends;
- while (remote_idmap_functions[i].name && strcmp(remote_idmap_functions[i].name, name)) {
- i++;
+ while(entry) {
+ if (strcmp(entry->name, name) == 0) return entry->methods;
+ entry = entry->next;
}
- if (remote_idmap_functions[i].name) {
+ return NULL;
+}
- if (!remote_idmap_functions[i].methods) {
- remote_idmap_functions[i].reg_meth(&remote_idmap_functions[i].methods);
- }
+NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods)
+{
+ struct idmap_function_entry *entry;
+
+ if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
+ DEBUG(0, ("Failed to register idmap module.\n"
+ "The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n"
+ "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
+ "Please recompile against the current version of samba!\n",
+ version, SMB_IDMAP_INTERFACE_VERSION));
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!name || !name[0] || !methods) {
+ DEBUG(0,("smb_register_idmap() called with NULL pointer or empty name!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- ret = remote_idmap_functions[i].methods;
+ if (get_methods(name)) {
+ DEBUG(0,("idmap module %s already registered!\n", name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
}
- return ret;
+ entry = smb_xmalloc(sizeof(struct idmap_function_entry));
+ entry->name = smb_xstrdup(name);
+ entry->methods = methods;
+
+ DLIST_ADD(backends, entry);
+ DEBUG(5, ("Successfully added idmap backend '%s'\n", name));
+ return NT_STATUS_OK;
}
/* Initialize backend */
@@ -74,23 +94,46 @@ BOOL idmap_init(void)
{
const char *remote_backend = lp_idmap_backend();
+ if (!backends)
+ static_init_idmap;
+
if (!local_map) {
- idmap_reg_tdb(&local_map);
- if (NT_STATUS_IS_ERR(local_map->init())) {
+ local_map = get_methods("tdb");
+
+ if (!local_map) {
+ DEBUG(0, ("idmap_init: could not find tdb backend!\n"));
+ return False;
+ }
+
+ if (NT_STATUS_IS_ERR(local_map->init( NULL ))) {
DEBUG(0, ("idmap_init: could not load or create local backend!\n"));
return False;
}
}
if (!remote_map && remote_backend && *remote_backend != 0) {
+ fstring params = "";
+ char *pparams;
+
+ /* get any mode parameters passed in */
+
+ if ( (pparams = strchr( remote_backend, ':' )) != NULL ) {
+ pparams = '\0';
+ pparams++;
+ fstrcpy( params, pparams );
+ }
+
DEBUG(3, ("idmap_init: using '%s' as remote backend\n", remote_backend));
- remote_map = get_methods(remote_backend);
- if (!remote_map) {
+ if((remote_map = get_methods(remote_backend)) ||
+ (NT_STATUS_IS_OK(smb_probe_module("idmap", remote_backend)) &&
+ (remote_map = get_methods(remote_backend)))) {
+ remote_map->init(params);
+ } else {
DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", remote_backend));
return False;
}
- remote_map->init();
+
}
return True;
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
index 33cf5fb0302..379f7729abb 100644
--- a/source/sam/idmap_ldap.c
+++ b/source/sam/idmap_ldap.c
@@ -3,9 +3,10 @@
idmap LDAP backend
- Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
- Copyright (C) Simo Sorce 2003
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Anthony Liguori 2003
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Gerald Carter 2003
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
@@ -31,10 +32,16 @@
#include <lber.h>
#include <ldap.h>
+#include "smbldap.h"
+
+#define IDMAP_GROUP_SUFFIX "ou=idmap group"
+#define IDMAP_USER_SUFFIX "ou=idmap people"
+
+
struct ldap_idmap_state {
LDAP *ldap_struct;
time_t last_ping;
- const char *uri;
+ char *uri;
char *bind_dn;
char *bind_secret;
unsigned int num_failures;
@@ -53,70 +60,6 @@ static NTSTATUS ldap_idmap_close(void);
/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldapsam_pw(char **dn, char** pw)
-{
- char *key = NULL;
- size_t size;
-
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
- }
-
- *pw=secrets_fetch(key, &size);
- SAFE_FREE(key);
-
- if (!size) {
- /* Upgrade 2.2 style entry */
- char *p;
- char* old_style_key = strdup(*dn);
- char *data;
- fstring old_style_pw;
-
- if (!old_style_key) {
- DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
- return False;
- }
-
- for (p=old_style_key; *p; p++)
- if (*p == ',') *p = '/';
-
- data=secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
-
- strncpy(old_style_pw, data, size);
- old_style_pw[size] = 0;
-
- SAFE_FREE(data);
-
- if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
- if (!secrets_delete(old_style_key)) {
- DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
- }
-
- return True;
-}
-
-/*******************************************************************
open a connection to the ldap server.
******************************************************************/
static int ldap_idmap_open_connection(struct ldap_idmap_state *state)
@@ -284,6 +227,9 @@ static int ldap_idmap_open(struct ldap_idmap_state *state)
return LDAP_SUCCESS;
}
+/*******************************************************************
+******************************************************************/
+
static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts)
{
int rc;
@@ -319,6 +265,7 @@ static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts)
a rebind function for authenticated referrals
This version takes a void* that we can shove useful stuff in :-)
******************************************************************/
+
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
#else
static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
@@ -421,7 +368,7 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state)
char *ldap_secret;
/* get the password */
- if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
{
DEBUG(0, ("ldap_idmap_connect_system: Failed to retrieve "
"password from secrets.tdb\n"));
@@ -478,9 +425,13 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state)
return rc;
}
+/*****************************************************************************
+ wrapper around ldap_search()
+*****************************************************************************/
+
static int ldap_idmap_search(struct ldap_idmap_state *state,
const char *base, int scope, const char *filter,
- const char *attrs[], int attrsonly,
+ char *attrs[], int attrsonly,
LDAPMessage **res)
{
int rc = LDAP_SERVER_DOWN;
@@ -510,9 +461,10 @@ static int ldap_idmap_search(struct ldap_idmap_state *state,
return rc;
}
-/*******************************************************************
-search an attribute and return the first value found.
-******************************************************************/
+/***********************************************************************
+ search an attribute and return the first value found.
+***********************************************************************/
+
static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
LDAPMessage * entry,
const char *attribute, pstring value)
@@ -520,12 +472,16 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
char **values;
value[0] = '\0';
- if ((values = ldap_get_values (state->ldap_struct, entry, attribute))
- == NULL) {
+ if ( !entry )
+ return False;
+
+ if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) == NULL)
+ {
DEBUG(10,("get_single_attribute: [%s] = [<does not exist>]\n",
attribute));
return False;
}
+
if (convert_string(CH_UTF8, CH_UNIX,
values[0], -1,
value, sizeof(pstring)) == (size_t)-1)
@@ -540,9 +496,9 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
return True;
}
-static const char *attrs[] = {"objectClass", "uidNumber", "gidNumber",
- "ntSid", NULL};
-static const char *pool_attr[] = {"uidNumber", "gidNumber", NULL};
+/*****************************************************************************
+ Allocate a new uid or gid
+*****************************************************************************/
static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
{
@@ -552,23 +508,36 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
LDAPMessage *result = 0;
LDAPMessage *entry = 0;
pstring id_str, new_id_str;
- LDAPMod mod[2];
- LDAPMod *mods[3];
- const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
- char *val[4];
+ LDAPMod **mods = NULL;
+ const char *type;
char *dn;
+ char **attr_list;
+ pstring filter;
+ uid_t luid, huid;
+ gid_t lgid, hgid;
+
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, "(objectClass=unixIdPool)",
- pool_attr, 0, &result);
+ type = (id_type & ID_USERID) ?
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) :
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+
+ snprintf(filter, sizeof(filter)-1, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
+
+ attr_list = get_attr_list( idpool_attr_list );
+
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter,
+ attr_list, 0, &result);
+ free_attr_list( attr_list );
+
if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: unixIdPool object not found\n"));
+ DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL));
goto out;
}
count = ldap_count_entries(ldap_state.ldap_struct, result);
if (count != 1) {
- DEBUG(0,("ldap_allocate_id: single unixIdPool not found\n"));
+ DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL));
goto out;
}
@@ -580,210 +549,308 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
type));
goto out;
}
+
+ /* this must succeed or else we wouldn't have initialized */
+
+ lp_idmap_uid( &luid, &huid);
+ lp_idmap_gid( &lgid, &hgid);
+
+ /* make sure we still have room to grow */
+
if (id_type & ID_USERID) {
id->uid = strtoul(id_str, NULL, 10);
- } else {
+ if (id->uid > huid ) {
+ DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %d!\n", huid));
+ goto out;
+ }
+ }
+ else {
id->gid = strtoul(id_str, NULL, 10);
+ if (id->gid > hgid ) {
+ DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %d!\n", hgid));
+ goto out;
+ }
}
-
- mod[0].mod_op = LDAP_MOD_DELETE;
- mod[0].mod_type = strdup(type);
- val[0] = id_str; val[1] = NULL;
- mod[0].mod_values = val;
-
- pstr_sprintf(new_id_str, "%ud",
+
+ snprintf(new_id_str, sizeof(new_id_str), "%u",
((id_type & ID_USERID) ? id->uid : id->gid) + 1);
- mod[1].mod_op = LDAP_MOD_ADD;
- mod[1].mod_type = strdup(type);
- val[3] = new_id_str; val[4] = NULL;
- mod[1].mod_values = val + 2;
-
- mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL;
+
+ ldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
+
rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods);
- ldap_memfree(dn);
- if (rc == LDAP_SUCCESS) ret = NT_STATUS_OK;
+ ldap_memfree(dn);
+ ldap_mods_free( mods, True );
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
+ type));
+ goto out;
+ }
+
+ ret = NT_STATUS_OK;
out:
return ret;
}
-/* Get a sid from an id */
+/*****************************************************************************
+ get a sid from an id
+*****************************************************************************/
+
static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
LDAPMessage *result = 0;
LDAPMessage *entry = 0;
pstring sid_str;
pstring filter;
- char type = (id_type & ID_USERID) ? 'u' : 'g';
+ pstring suffix;
+ const char *type;
int rc;
int count;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- pstr_sprintf(filter, "(&(%cidNumber=%ud)(objectClass=sambaAccount))",
- type, ((id_type & ID_USERID) ? id.uid : id.gid));
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0,
- &result);
- if (rc != LDAP_SUCCESS) {
- goto out;
- }
+ char **attr_list;
+
+ /* first we try for a samba user or group mapping */
+
+ if ( id_type & ID_USERID ) {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_SAMBASAMACCOUNT, type, id.uid );
+ pstrcpy( suffix, lp_ldap_suffix());
+ }
+ else {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_GROUPMAP, type, id.gid );
+ pstrcpy( suffix, lp_ldap_group_suffix() );
+ }
+
+ attr_list = get_attr_list( sidmap_attr_list );
+ rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+ if (rc != LDAP_SUCCESS)
+ goto out;
+
count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ /* fall back to looking up an idmap entry if we didn't find and
+ actual user or group */
+
if (count == 0) {
- pstr_sprintf(filter,
- "(&(objectClass=idmapEntry)(%cidNumber=%ud))",
- type, ((id_type & ID_USERID) ? id.uid : id.gid));
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid));
+
+#if 0 /* commented out for now -- jerry */
+ if ( id_type & ID_USERID )
+ snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() );
+ else
+ snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() );
+#else
+ pstrcpy( suffix, lp_ldap_idmap_suffix() );
+#endif
+
+ rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
goto out;
- }
- count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ count = ldap_count_entries(ldap_state.ldap_struct, result);
}
if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for "
- "%cid: %ud\n", (id_type&ID_USERID)?'u':'g',
- ((id_type & ID_USERID) ? id.uid : id.gid)));
+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %u\n",
+ type, ((id_type & ID_USERID) ? id.uid : id.gid)));
goto out;
}
entry = ldap_first_entry(ldap_state.ldap_struct, result);
- if (!ldap_idmap_attribute(&ldap_state, entry, "ntSid", sid_str)) {
+ if ( !ldap_idmap_attribute(&ldap_state, entry, LDAP_ATTRIBUTE_SID, sid_str) )
goto out;
- }
- if (!string_to_sid(sid, sid_str)) {
+ if (!string_to_sid(sid, sid_str))
goto out;
- }
ret = NT_STATUS_OK;
out:
+ free_attr_list( attr_list );
+
return ret;
}
-/* Get an id from a sid */
-static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type,
- const DOM_SID *sid)
+/***********************************************************************
+ Get an id from a sid
+***********************************************************************/
+
+static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
{
LDAPMessage *result = 0;
LDAPMessage *entry = 0;
pstring sid_str;
pstring filter;
pstring id_str;
- const char *type = (*id_type & ID_USERID) ? "uidNumber" : "gidNumber";
- const char *class =
- (*id_type & ID_USERID) ? "sambaAccount" : "sambaGroupMapping";
+ pstring suffix;
+ const char *type;
+ const char *obj_class;
int rc;
int count;
+ char **attr_list;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ /* first try getting the mapping from a samba user or group */
+
+ if ( *id_type & ID_USERID ) {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
+ obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
+ pstrcpy( suffix, lp_ldap_suffix() );
+ }
+ else {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+ obj_class = LDAP_OBJ_GROUPMAP;
+ pstrcpy( suffix, lp_ldap_group_suffix() );
+ }
sid_to_string(sid_str, sid);
- pstr_sprintf(filter, "(&(objectClass=%s)(ntSid=%s)", class, sid_str);
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", obj_class,
+ LDAP_ATTRIBUTE_SID, sid_str);
+
+ attr_list = get_attr_list( sidmap_attr_list );
+ rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
goto out;
- }
+
count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ /* fall back to looking up an idmap entry if we didn't find and
+ actual user or group */
+
if (count == 0) {
- pstr_sprintf(filter,
- "(&(objectClass=idmapEntry)(ntSid=%s))", sid_str);
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
+
+#if 0 /* commented out for now -- jerry */
+ if ( *id_type & ID_USERID )
+ snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() );
+ else
+ snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() );
+#else
+ pstrcpy( suffix, lp_ldap_idmap_suffix() );
+#endif
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
- goto out;
- }
- count = ldap_count_entries(ldap_state.ldap_struct, result);
+ rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
+ goto out;
+
+ count = ldap_count_entries(ldap_state.ldap_struct, result);
}
-
- /* our search filters may 2 objects in the case that a user and group
- rid are the same */
- if (count != 1 && count != 2) {
- DEBUG(0,
- ("ldap_get_id_from_sid: incorrect number of objects\n"));
+
+ if ( count > 1 ) {
+ DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n",
+ filter));
goto out;
}
- entry = ldap_first_entry(ldap_state.ldap_struct, result);
- if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) {
- entry = ldap_next_entry(ldap_state.ldap_struct, entry);
-
- if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) {
- int i;
+ /* we might have an existing entry to work with so pull out the requested information */
+
+ if ( count )
+ entry = ldap_first_entry(ldap_state.ldap_struct, result);
+
+ /* if entry == NULL, then we will default to allocating a new id */
+
+ if ( !ldap_idmap_attribute(&ldap_state, entry, type, id_str) )
+ {
+ int i;
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
- ret = ldap_allocate_id(id, *id_type);
- if (NT_STATUS_IS_OK(ret)) {
- break;
- }
- }
- if (NT_STATUS_IS_OK(ret)) {
- ret = ldap_set_mapping(sid, *id, *id_type);
- } else {
- DEBUG(0,("ldap_allocate_id: cannot acquire id"
- " lock\n"));
- }
- } else {
- if ((*id_type & ID_USERID)) {
- id->uid = strtoul(id_str, NULL, 10);
- } else {
- id->gid = strtoul(id_str, NULL, 10);
- }
- ret = NT_STATUS_OK;
+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++)
+ {
+ ret = ldap_allocate_id(id, *id_type);
+ if ( NT_STATUS_IS_OK(ret) )
+ break;
}
- } else {
- if ((*id_type & ID_USERID)) {
+
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ goto out;
+ }
+
+ ret = ldap_set_mapping(sid, *id, *id_type);
+
+ }
+ else
+ {
+ if ( (*id_type & ID_USERID) )
id->uid = strtoul(id_str, NULL, 10);
- } else {
+ else
id->gid = strtoul(id_str, NULL, 10);
- }
+
ret = NT_STATUS_OK;
}
out:
+ free_attr_list( attr_list );
+
return ret;
}
-/* This function cannot be called to modify a mapping, only set a new one */
+/***********************************************************************
+ This function cannot be called to modify a mapping, only set a new one
+***********************************************************************/
+
static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
{
pstring dn, sid_str, id_str;
- const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
- LDAPMod *mods[3];
- LDAPMod mod[2];
- char *val[4];
+ fstring type;
+ LDAPMod **mods = NULL;
int rc;
int attempts = 0;
- pstr_sprintf(id_str, "%ud", ((id_type & ID_USERID) ? id.uid : id.gid));
- sid_to_string(sid_str, sid);
- pstr_sprintf(dn, "%s=%ud,%s", type, ((id_type & ID_USERID) ? id.uid : id.gid), lp_ldap_suffix());
- mod[0].mod_op = LDAP_MOD_REPLACE;
- mod[0].mod_type = strdup(type);
- val[0] = id_str; val[1] = NULL;
- mod[0].mod_values = val;
+ if ( id_type & ID_USERID )
+ fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) );
+ else
+ fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ) );
- mod[1].mod_op = LDAP_MOD_REPLACE;
- mod[1].mod_type = strdup("ntSid");
- val[2] = sid_str; val[3] = NULL;
- mod[1].mod_values = val + 2;
+#if 0
+ snprintf(dn, sizeof(dn), "%s=%u,%s,%s", type,
+ ((id_type & ID_USERID) ? id.uid : id.gid),
+ ((id_type & ID_USERID) ? IDMAP_USER_SUFFIX : IDMAP_GROUP_SUFFIX ),
+ lp_ldap_idmap_suffix());
+#else
+ snprintf(dn, sizeof(dn), "%s=%u,%s", type,
+ ((id_type & ID_USERID) ? id.uid : id.gid),
+ lp_ldap_idmap_suffix());
+#endif
- mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL;
+ snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid));
+ sid_to_string( sid_str, sid );
+
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, type, id_str );
+ ldap_set_mod( &mods, LDAP_MOD_ADD,
+ get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid_str );
do {
- if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) !=
- LDAP_SUCCESS) continue;
+ if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS)
+ continue;
- rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods);
+ rc = ldap_add_s(ldap_state.ldap_struct, dn, mods);
} while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8));
+ ldap_mods_free( mods, True );
+
if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_set_mapping: Failed to create mapping from %s to %d [%s]\n",
+ sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type));
return NT_STATUS_UNSUCCESSFUL;
}
+
+ DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n",
+ sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type));
return NT_STATUS_OK;
}
@@ -791,21 +858,109 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
/*****************************************************************************
Initialise idmap database.
*****************************************************************************/
-static NTSTATUS ldap_idmap_init(void)
+static NTSTATUS ldap_idmap_init( char *params )
{
- /* We wait for the first search request before we try to connect to
- the LDAP server. We may want to connect upon initialization though
- -- aliguori */
+ fstring filter;
+#if 0
+ pstring dn;
+#endif
+ int rc;
+ char **attr_list;
+ LDAPMessage *result = NULL;
+ LDAPMod **mods = NULL;
+ int count;
+
+ /* parse out the server (assuming only parameter is a URI) */
+
+ if ( params )
+ ldap_state.uri = smb_xstrdup( params );
+ else
+ ldap_state.uri = smb_xstrdup( "ldap://localhost/" );
+
+ /* see if the idmap suffix and sub entries exists */
+
+ snprintf( filter, sizeof(filter), "(objectclass=%s)", LDAP_OBJ_IDPOOL );
+
+ attr_list = get_attr_list( idpool_attr_list );
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result);
+ free_attr_list ( attr_list );
+
+ if (rc != LDAP_SUCCESS)
+ return NT_STATUS_UNSUCCESSFUL;
+
+ count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ if ( count > 1 ) {
+ DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
+ filter, lp_ldap_idmap_suffix() ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ else if (count == 0) {
+ uid_t luid, huid;
+ gid_t lgid, hgid;
+ fstring uid_str, gid_str;
+ int attempts = 0;
+
+ if ( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid( &lgid, &hgid ) ) {
+ DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ snprintf( uid_str, sizeof(uid_str), "%d", luid );
+ snprintf( gid_str, sizeof(gid_str), "%d", lgid );
+
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
+ ldap_set_mod( &mods, LDAP_MOD_ADD,
+ get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER), uid_str );
+ ldap_set_mod( &mods, LDAP_MOD_ADD,
+ get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER), gid_str );
+
+ do {
+ if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_modify_s(ldap_state.ldap_struct, lp_ldap_idmap_suffix(), mods);
+ } while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8));
+ }
+
+ /* we have the initial entry now; let's create the sub entries */
+ /* if they already exist then this will fail, but we don't care */
+
+#if 0 /* commenting out for now, but I will come back to this --jerry */
+
+ mods = NULL;
+ snprintf( dn, sizeof(dn), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap people" );
+ ldap_add_s(ldap_state.ldap_struct, dn, mods);
+ ldap_mods_free( mods, True );
+
+ mods = NULL;
+ snprintf( dn, sizeof(dn), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
+ ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap group" );
+ ldap_add_s(ldap_state.ldap_struct, dn, mods);
+ ldap_mods_free( mods, True );
+#endif
+
return NT_STATUS_OK;
}
-/* End the LDAP session */
+/*****************************************************************************
+ End the LDAP session
+*****************************************************************************/
+
static NTSTATUS ldap_idmap_close(void)
{
if (ldap_state.ldap_struct != NULL) {
ldap_unbind_ext(ldap_state.ldap_struct, NULL, NULL);
ldap_state.ldap_struct = NULL;
}
+
+ SAFE_FREE( ldap_state.uri );
+ SAFE_FREE( ldap_state.bind_dn );
+ SAFE_FREE( ldap_state.bind_secret );
DEBUG(5,("The connection to the LDAP server was closed\n"));
/* maybe free the results here --metze */
@@ -833,6 +988,5 @@ static struct idmap_methods ldap_methods = {
NTSTATUS idmap_ldap_init(void)
{
- DEBUG(0,("idmap_reg_ldap: no LDAP support\n"));
return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap", &ldap_methods);
}
diff --git a/source/sam/idmap_tdb.c b/source/sam/idmap_tdb.c
index 31c12241bf7..278269e8198 100644
--- a/source/sam/idmap_tdb.c
+++ b/source/sam/idmap_tdb.c
@@ -263,7 +263,7 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
/*****************************************************************************
Initialise idmap database.
*****************************************************************************/
-static NTSTATUS db_idmap_init(void)
+static NTSTATUS db_idmap_init( char *params )
{
SMB_STRUCT_STAT stbuf;
char *tdbfile = NULL;
@@ -424,7 +424,7 @@ static void db_idmap_status(void)
/* Display complete mapping of users and groups to rids */
}
-struct idmap_methods db_methods = {
+static struct idmap_methods db_methods = {
db_idmap_init,
db_get_sid_from_id,
@@ -435,9 +435,7 @@ struct idmap_methods db_methods = {
};
-NTSTATUS idmap_reg_tdb(struct idmap_methods **meth)
+NTSTATUS idmap_tdb_init(void)
{
- *meth = &db_methods;
-
- return NT_STATUS_OK;
+ return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods);
}
diff --git a/source/script/.cvsignore b/source/script/.cvsignore
index 5efd0d33db3..7a8114ecd73 100644
--- a/source/script/.cvsignore
+++ b/source/script/.cvsignore
@@ -1,2 +1 @@
findsmb
-mkproto.sh
diff --git a/source/script/build_env.sh b/source/script/build_env.sh
index 0000759f160..eb54f37aeda 100755
--- a/source/script/build_env.sh
+++ b/source/script/build_env.sh
@@ -1,25 +1,31 @@
#!/bin/sh
+if [ $# -lt 3 ]
+then
+ echo "Usage: $0 srcdir builddir compiler"
+ exit 1
+fi
+
uname=`uname -a`
date=`date`
srcdir=$1
builddir=$2
compiler=$3
- if [ ! "x$USER" = "x" ]; then
- whoami=$USER
- else
- if [ ! "x$LOGNAME" = "x" ]; then
- whoami=$LOGNAME
- else
- whoami=`whoami || id -un`
- fi
- fi
+if [ ! "x$USER" = "x" ]; then
+ whoami=$USER
+else
+ if [ ! "x$LOGNAME" = "x" ]; then
+ whoami=$LOGNAME
+ else
+ whoami=`whoami || id -un`
+ fi
+fi
host=`hostname`
cat <<EOF
-/* This file is automatically generated with "make build_env". DO NOT EDIT */
+/* This file is automatically generated with "make include/build_env.h". DO NOT EDIT */
#ifndef _BUILD_ENV_H
#define _BUILD_ENV_H
diff --git a/source/script/installswat.sh b/source/script/installswat.sh
index c66604cdb84..d1f8ea191d9 100755
--- a/source/script/installswat.sh
+++ b/source/script/installswat.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-#fist version March 1998, Andrew Tridgell
+#first version March 1998, Andrew Tridgell
SWATDIR=$1
SRCDIR=$2/
diff --git a/source/smbd/.cvsignore b/source/smbd/.cvsignore
index 5f2a5c4cf75..d2b1fd5b2ee 100644
--- a/source/smbd/.cvsignore
+++ b/source/smbd/.cvsignore
@@ -1,2 +1,3 @@
*.po
*.po32
+build_options.c
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 5cca85500fd..1be13270bab 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -185,7 +185,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
if (normal_close && delete_on_close) {
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
fsp->fsp_name));
- if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 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 deleted
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index b6c7aa1076e..eb2d2bbcbf2 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -93,6 +93,7 @@ thinking the server is still available.
****************************************************************************/
connection_struct *conn_new(void)
{
+ TALLOC_CTX *mem_ctx;
connection_struct *conn;
int i;
@@ -103,10 +104,16 @@ connection_struct *conn_new(void)
return NULL;
}
- conn = (connection_struct *)malloc(sizeof(*conn));
- if (!conn) return NULL;
+ if ((mem_ctx=talloc_init("connection_struct"))==NULL) {
+ DEBUG(0,("talloc_init(connection_struct) failed!\n"));
+ return NULL;
+ }
- ZERO_STRUCTP(conn);
+ if ((conn=(connection_struct *)talloc_zero(mem_ctx, sizeof(*conn)))==NULL) {
+ DEBUG(0,("talloc_zero() failed!\n"));
+ return NULL;
+ }
+ conn->mem_ctx = mem_ctx;
conn->cnum = i;
bitmap_set(bmap, i);
@@ -195,27 +202,16 @@ void conn_clear_vuid_cache(uint16 vuid)
void conn_free(connection_struct *conn)
{
- smb_vfs_handle_struct *handle, *thandle;
- void (*done_fptr)(connection_struct *the_conn);
+ vfs_handle_struct *handle = NULL, *thandle = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
/* Free vfs_connection_struct */
- handle = conn->vfs_private;
+ handle = conn->vfs_handles;
while(handle) {
- /* Only call dlclose for the old modules */
- if (handle->handle) {
- /* Close dlopen() handle */
- done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done");
-
- if (done_fptr == NULL) {
- DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle));
- } else {
- done_fptr(conn);
- }
- sys_dlclose(handle->handle);
- }
- DLIST_REMOVE(conn->vfs_private, handle);
+ DLIST_REMOVE(conn->vfs_handles, handle);
thandle = handle->next;
- SAFE_FREE(handle);
+ if (handle->free_data)
+ handle->free_data(&handle->data);
handle = thandle;
}
@@ -238,8 +234,9 @@ void conn_free(connection_struct *conn)
bitmap_clear(bmap, conn->cnum);
num_open--;
+ mem_ctx = conn->mem_ctx;
ZERO_STRUCTP(conn);
- SAFE_FREE(conn);
+ talloc_destroy(mem_ctx);
}
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index c2718d4d703..5bb76eb3bd8 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -38,10 +38,17 @@ TDB_CONTEXT *conn_tdb_ctx(void)
static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey)
{
ZERO_STRUCTP(pkey);
- ZERO_STRUCTP(pkbuf);
pkey->pid = sys_getpid();
pkey->cnum = conn?conn->cnum:-1;
fstrcpy(pkey->name, name);
+#ifdef DEVELOPER
+ /* valgrind fixer... */
+ {
+ size_t sl = strlen(pkey->name);
+ if (sizeof(fstring)-sl)
+ memset(&pkey->name[sl], '\0', sizeof(fstring)-sl);
+ }
+#endif
pkbuf->dptr = (char *)pkey;
pkbuf->dsize = sizeof(*pkey);
diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c
index 71b3f2bf772..f93cdf3791e 100644
--- a/source/smbd/dfree.c
+++ b/source/smbd/dfree.c
@@ -80,7 +80,7 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query,
dfree_command = lp_dfree_command();
if (dfree_command && *dfree_command) {
- char *p;
+ const char *p;
char **lines;
pstring syscmd;
@@ -93,15 +93,15 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query,
DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
- *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10);
- while (p && *p & isspace(*p))
+ *dsize = STR_TO_SMB_BIG_UINT(line, &p);
+ while (p && *p && isspace(*p))
p++;
if (p && *p)
- *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10);
- while (p && *p & isspace(*p))
+ *dfree = STR_TO_SMB_BIG_UINT(p, &p);
+ while (p && *p && isspace(*p))
p++;
if (p && *p)
- *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10);
+ *bsize = STR_TO_SMB_BIG_UINT(p, NULL);
else
*bsize = 1024;
file_lines_free(lines);
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 6cf56fd373b..94b605ee8f9 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -643,7 +643,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
pstrcpy(pathreal,path);
pstrcat(path,fname);
pstrcat(pathreal,dname);
- if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0) {
+ if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) {
DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
continue;
}
@@ -700,7 +700,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
return True;
/* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
+ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
return False;
/* Pseudo-open the file (note - no fd's created). */
@@ -715,7 +715,8 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
return False;
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
close_file(fsp, True);
/* No access if SD get failed. */
@@ -753,7 +754,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
return True;
/* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
+ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
return False;
/* Pseudo-open the file (note - no fd's created). */
@@ -768,7 +769,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
return False;
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
close_file(fsp, False);
/* No access if SD get failed. */
@@ -794,7 +796,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT
return True;
/* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
+ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
return True;
if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
@@ -811,7 +813,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
{
Dir *dirp;
const char *n;
- DIR *p = conn->vfs_ops.opendir(conn,name);
+ DIR *p = SMB_VFS_OPENDIR(conn,name);
int used=0;
if (!p)
@@ -819,7 +821,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
dirp = (Dir *)malloc(sizeof(Dir));
if (!dirp) {
DEBUG(0,("Out of memory in OpenDir\n"));
- conn->vfs_ops.closedir(conn,p);
+ SMB_VFS_CLOSEDIR(conn,p);
return(NULL);
}
dirp->pos = dirp->numentries = dirp->mallocsize = 0;
@@ -912,7 +914,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
dirp->numentries++;
}
- conn->vfs_ops.closedir(conn,p);
+ SMB_VFS_CLOSEDIR(conn,p);
return((void *)dirp);
}
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 6c21dc04d0f..aaee41b546a 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -56,7 +56,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
dname = parent_dirname(fname);
DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
- if (vfs_stat(conn,dname,&sbuf) != 0) {
+ if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) {
DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
return(0); /* *** shouldn't happen! *** */
}
@@ -191,7 +191,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
if (!st) {
st = &st1;
- if (vfs_stat(conn,fname,st))
+ if (SMB_VFS_STAT(conn,fname,st))
return(-1);
}
@@ -235,7 +235,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
- if ((ret = vfs_chmod(conn,fname,unixmode)) == 0)
+ if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0)
return 0;
if((errno != EPERM) && (errno != EACCES))
@@ -262,7 +262,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
if (!fsp)
return -1;
become_root();
- ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode);
+ ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode);
unbecome_root();
close_file_fchmod(fsp);
}
@@ -283,7 +283,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
errno = 0;
- if(conn->vfs_ops.utime(conn,fname, times) == 0)
+ if(SMB_VFS_UTIME(conn,fname, times) == 0)
return 0;
if((errno != EPERM) && (errno != EACCES))
@@ -298,7 +298,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
(as DOS does).
*/
- if(vfs_stat(conn,fname,&sb) != 0)
+ if(SMB_VFS_STAT(conn,fname,&sb) != 0)
return -1;
/* Check if we have write access. */
@@ -311,7 +311,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
current_user.ngroups,current_user.groups)))) {
/* We are allowed to become root and change the filetime. */
become_root();
- ret = conn->vfs_ops.utime(conn,fname, times);
+ ret = SMB_VFS_UTIME(conn,fname, times);
unbecome_root();
}
}
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index b612b1a4514..6be5f6af7d0 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -32,7 +32,7 @@ static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
{
SMB_OFF_T seek_ret;
- seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos,SEEK_SET);
+ seek_ret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET);
if(seek_ret == -1) {
DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n",
@@ -101,7 +101,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
#ifdef DMF_FIX
int numretries = 3;
tryagain:
- readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
+ readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
if (readret == -1) {
if ((errno == EAGAIN) && numretries) {
DEBUG(3,("read_file EAGAIN retry in 10 seconds\n"));
@@ -112,7 +112,7 @@ tryagain:
return -1;
}
#else /* NO DMF fix. */
- readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
+ readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
if (readret == -1)
return -1;
#endif
@@ -181,7 +181,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
SMB_STRUCT_STAT st;
fsp->modified = True;
- if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) {
+ if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
fsp->size = (SMB_BIG_UINT)st.st_size;
if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode))
@@ -760,7 +760,7 @@ void sync_file(connection_struct *conn, files_struct *fsp)
{
if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) {
flush_write_cache(fsp, SYNC_FLUSH);
- conn->vfs_ops.fsync(fsp,fsp->fd);
+ SMB_VFS_FSYNC(fsp,fsp->fd);
}
}
@@ -772,7 +772,7 @@ void sync_file(connection_struct *conn, files_struct *fsp)
int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
{
if (fsp->fd == -1)
- return vfs_stat(fsp->conn, fsp->fsp_name, pst);
+ return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst);
else
- return vfs_fstat(fsp,fsp->fd, pst);
+ return SMB_VFS_FSTAT(fsp,fsp->fd, pst);
}
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index b9e33e8f934..ad107f9c3e1 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -178,7 +178,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* stat the name - if it exists then we are all done!
*/
- if (vfs_stat(conn,name,&st) == 0) {
+ if (SMB_VFS_STAT(conn,name,&st) == 0) {
stat_cache_add(orig_path, name);
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
*pst = st;
@@ -234,7 +234,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* Check if the name exists up to this point.
*/
- if (vfs_stat(conn,name, &st) == 0) {
+ if (SMB_VFS_STAT(conn,name, &st) == 0) {
/*
* It exists. it must either be a directory or this must be
* the last part of the path for it to be OK.
@@ -342,7 +342,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* JRA.
*/
- if (vfs_stat(conn,name, &st) == 0) {
+ if (SMB_VFS_STAT(conn,name, &st) == 0) {
*pst = st;
} else {
ZERO_STRUCT(st);
@@ -418,7 +418,7 @@ BOOL check_name(pstring name,connection_struct *conn)
#ifdef S_ISLNK
if (!lp_symlinks(SNUM(conn))) {
SMB_STRUCT_STAT statbuf;
- if ( (conn->vfs_ops.lstat(conn,name,&statbuf) != -1) &&
+ if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) &&
(S_ISLNK(statbuf.st_mode)) ) {
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
ret=0;
diff --git a/source/smbd/files.c b/source/smbd/files.c
index b9b27ad5ff9..f0fd6b7a736 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -346,6 +346,10 @@ void file_free(files_struct *fsp)
string_free(&fsp->fsp_name);
+ if (fsp->fake_file_handle) {
+ destroy_fake_file_handle(&fsp->fake_file_handle);
+ }
+
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
files_used--;
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index e220d2f6d2b..d2eb996899c 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -556,8 +556,8 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
/* Fill the new cache entry, and add it to the cache. */
s1 = (char *)(new_entry + 1);
s2 = (char *)&(s1[mangled_len + 1]);
- (void)StrnCpy( s1, mangled_name, mangled_len );
- (void)StrnCpy( s2, raw_name, raw_len );
+ safe_strcpy( s1, mangled_name, mangled_len );
+ safe_strcpy( s2, raw_name, raw_len );
ubi_cachePut( mangled_cache, i, new_entry, s1 );
}
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 66cd8352400..2a2ca25532b 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -100,8 +100,8 @@ static int reply_lanman1(char *inbuf, char *outbuf)
SSVAL(outbuf,smb_vwv1,secword);
/* Create a token value and add it to the outgoing packet. */
if (global_encrypted_passwords_negotiated) {
- SSVAL(outbuf,smb_vwv11, 8);
get_challenge(smb_buf(outbuf));
+ SSVAL(outbuf,smb_vwv11, 8);
}
Protocol = PROTOCOL_LANMAN1;
@@ -144,8 +144,8 @@ static int reply_lanman2(char *inbuf, char *outbuf)
/* Create a token value and add it to the outgoing packet. */
if (global_encrypted_passwords_negotiated) {
- SSVAL(outbuf,smb_vwv11, 8);
get_challenge(smb_buf(outbuf));
+ SSVAL(outbuf,smb_vwv11, 8);
}
Protocol = PROTOCOL_LANMAN2;
@@ -182,6 +182,16 @@ static int negprot_spnego(char *p)
ZERO_STRUCT(guid);
safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1);
+
+#ifdef DEVELOPER
+ /* valgrind fixer... */
+ {
+ size_t sl = strlen(guid);
+ if (sizeof(guid)-sl)
+ memset(&guid[sl], '\0', sizeof(guid)-sl);
+ }
+#endif
+
strlower((char *)guid);
#if 0
diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c
index d8b35462acb..810e5079ba5 100644
--- a/source/smbd/notify_hash.c
+++ b/source/smbd/notify_hash.c
@@ -48,7 +48,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
ZERO_STRUCTP(data);
- if(vfs_stat(conn,path, &st) == -1)
+ if(SMB_VFS_STAT(conn,path, &st) == -1)
return False;
data->modify_time = st.st_mtime;
@@ -100,7 +100,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
/*
* Do the stat - but ignore errors.
*/
- vfs_stat(conn,full_name, &st);
+ SMB_VFS_STAT(conn,full_name, &st);
/*
* Always sum the times.
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 9f7fabb75e4..fa7b78ecc26 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
SMB NT transaction handling
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Stefan (metze) Metzmacher 2003
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
@@ -26,6 +27,7 @@ extern int global_oplock_break;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
+extern struct current_user current_user;
static const char *known_nt_pipes[] = {
"\\LANMAN",
@@ -53,6 +55,24 @@ struct generic_mapping file_generic_mapping = {
FILE_GENERIC_ALL
};
+char *nttrans_realloc(char **ptr, size_t size)
+{
+ char *tptr = NULL;
+ if (ptr==NULL)
+ smb_panic("nttrans_realloc() called with NULL ptr\n");
+
+ tptr = Realloc_zero(*ptr, size);
+ if(tptr == NULL) {
+ *ptr = NULL;
+ return NULL;
+ }
+
+ *ptr = tptr;
+
+ return tptr;
+}
+
+
/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
@@ -542,6 +562,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
{
int result;
pstring fname;
+ enum FAKE_FILE_TYPE fake_file_type = 0;
uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
@@ -669,8 +690,25 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
*/
if( strchr_m(fname, ':')) {
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+
+#ifdef HAVE_SYS_QUOTAS
+ if ((fake_file_type=is_fake_file(fname))!=0) {
+ /*
+ * here we go! support for changing the disk quotas --metze
+ *
+ * we need to fake up to open this MAGIC QUOTA file
+ * and return a valid FID
+ *
+ * w2k close this file directly after openening
+ * xp also tries a QUERY_FILE_INFO on the file and then close it
+ */
+ } else {
+#endif
+ END_PROFILE(SMBntcreateX);
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+#ifdef HAVE_SYS_QUOTAS
+ }
+#endif
}
}
@@ -746,12 +784,21 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
* before issuing an oplock break request to
* our client. JRA. */
- fsp = open_file_shared1(conn,fname,&sbuf,
+ if (fake_file_type==0) {
+ fsp = open_file_shared1(conn,fname,&sbuf,
desired_access,
smb_open_mode,
smb_ofun,unixmode, oplock_request,
&rmode,&smb_action);
-
+ } else {
+ /* to open a fake_file --metze */
+ fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf,
+ desired_access,
+ smb_open_mode,
+ smb_ofun,unixmode, oplock_request,
+ &rmode,&smb_action);
+ }
+
if (!fsp) {
/* We cheat here. There are two cases we
* care about. One is a directory rename,
@@ -917,13 +964,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
Reply to a NT_TRANSACT_CREATE call to open a pipe.
****************************************************************************/
-static int do_nt_transact_create_pipe( connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup, char **ppparams,
- char **ppdata)
+static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
pstring fname;
- int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
char *params = *ppparams;
int ret;
int pnum = -1;
@@ -933,25 +979,21 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if(total_parameter_count < 54) {
- DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+ if(parameter_count < 54) {
+ DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
return ret;
/* Realloc the size of parameters and data we will return */
- params = Realloc(*ppparams, 69);
+ params = nttrans_realloc(ppparams, 69);
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
- *ppparams = params;
-
- memset((char *)params,'\0',69);
-
p = params;
SCVAL(p,0,NO_OPLOCK_RETURN);
@@ -1032,7 +1074,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
if (psd->off_dacl==0)
security_info_sent &= ~DACL_SECURITY_INFORMATION;
- ret = fsp->conn->vfs_ops.fset_nt_acl( fsp, fsp->fd, security_info_sent, psd);
+ ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fd, security_info_sent, psd);
if (!ret) {
talloc_destroy(mem_ctx);
@@ -1048,15 +1090,14 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
-static int call_nt_transact_create(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup, char **ppparams,
- char **ppdata)
+static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
pstring fname;
char *params = *ppparams;
char *data = *ppdata;
- int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
/* Breakout the oplock request bits so we can set the reply bits separately. */
int oplock_request = 0;
mode_t unixmode;
@@ -1092,7 +1133,10 @@ static int call_nt_transact_create(connection_struct *conn,
if (IS_IPC(conn)) {
if (lp_nt_pipe_support())
return do_nt_transact_create_pipe(conn, inbuf, outbuf, length,
- bufsize, ppsetup, ppparams, ppdata);
+ bufsize,
+ ppsetup, setup_count,
+ ppparams, parameter_count,
+ ppdata, data_count);
else
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1101,8 +1145,8 @@ static int call_nt_transact_create(connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if(total_parameter_count < 54) {
- DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+ if(parameter_count < 54) {
+ DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1146,7 +1190,7 @@ static int call_nt_transact_create(connection_struct *conn,
if(!dir_fsp->is_directory) {
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
/*
* Check to see if this is a mac fork of some kind.
@@ -1175,9 +1219,9 @@ static int call_nt_transact_create(connection_struct *conn,
}
srvstr_pull(inbuf, &fname[dir_name_len], params+53, sizeof(fname)-dir_name_len,
- total_parameter_count-53, STR_TERMINATE);
+ parameter_count-53, STR_TERMINATE);
} else {
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
/*
* Check to see if this is a mac fork of some kind.
@@ -1331,14 +1375,10 @@ static int call_nt_transact_create(connection_struct *conn,
}
/* Realloc the size of parameters and data we will return */
- params = Realloc(*ppparams, 69);
+ params = nttrans_realloc(ppparams, 69);
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
- *ppparams = params;
-
- memset((char *)params,'\0',69);
-
p = params;
if (extended_oplock_granted)
SCVAL(p,0, BATCH_OPLOCK_RETURN);
@@ -1428,11 +1468,10 @@ int reply_nttranss(connection_struct *conn,
don't allow a directory to be opened.
****************************************************************************/
-static int call_nt_transact_notify_change(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup,
- char **ppparams, char **ppdata)
+static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
char *setup = *ppsetup;
files_struct *fsp;
@@ -1462,17 +1501,22 @@ name = %s\n", fsp->fsp_name ));
Reply to an NT transact rename command.
****************************************************************************/
-static int call_nt_transact_rename(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup, char **ppparams, char **ppdata)
+static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
char *params = *ppparams;
pstring new_name;
- files_struct *fsp = file_fsp(params, 0);
- BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
+ files_struct *fsp = NULL;
+ BOOL replace_if_exists = False;
NTSTATUS status;
+ if(parameter_count < 4)
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+
+ fsp = file_fsp(params, 0);
+ replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
CHECK_FSP(fsp, conn);
srvstr_pull(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE);
@@ -1518,15 +1562,13 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
}
/****************************************************************************
- Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though). Right now it just returns the same thing NT would
- when queried on a FAT filesystem. JRA.
+ Reply to query a security descriptor.
****************************************************************************/
-static int call_nt_transact_query_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **ppsetup, char **ppparams, char **ppdata)
+static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
@@ -1534,21 +1576,25 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
prs_struct pd;
SEC_DESC *psd = NULL;
size_t sd_size;
+ uint32 security_info_wanted;
TALLOC_CTX *mem_ctx;
+ files_struct *fsp = NULL;
- files_struct *fsp = file_fsp(params,0);
+ if(parameter_count < 8)
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+ fsp = file_fsp(params,0);
if(!fsp)
return ERROR_DOS(ERRDOS,ERRbadfid);
+ security_info_wanted = IVAL(params,4);
+
DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
- params = Realloc(*ppparams, 4);
+ params = nttrans_realloc(ppparams, 4);
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
- *ppparams = params;
-
if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
return ERROR_DOS(ERRDOS,ERRnomem);
@@ -1561,7 +1607,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
if (!lp_nt_acl_support(SNUM(conn)))
sd_size = get_null_nt_acl(mem_ctx, &psd);
else
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd);
if (sd_size == 0) {
talloc_destroy(mem_ctx);
@@ -1584,16 +1630,12 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
* Allocate the data we will point this at.
*/
- data = Realloc(*ppdata, sd_size);
+ data = nttrans_realloc(ppdata, sd_size);
if(data == NULL) {
talloc_destroy(mem_ctx);
return ERROR_DOS(ERRDOS,ERRnomem);
}
- *ppdata = data;
-
- memset(data, '\0', sd_size);
-
/*
* Init the parse struct we will marshall into.
*/
@@ -1632,23 +1674,21 @@ security descriptor.\n"));
}
/****************************************************************************
- Reply to set a security descriptor. Map to UNIX perms.
+ Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
****************************************************************************/
-static int call_nt_transact_set_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup,
- char **ppparams, char **ppdata)
+static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
- uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
char *params= *ppparams;
char *data = *ppdata;
- uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
files_struct *fsp = NULL;
uint32 security_info_sent = 0;
NTSTATUS nt_status;
- if(total_parameter_count < 8)
+ if(parameter_count < 8)
return ERROR_DOS(ERRDOS,ERRbadfunc);
if((fsp = file_fsp(params,0)) == NULL)
@@ -1662,10 +1702,10 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
(unsigned int)security_info_sent ));
- if (total_data_count == 0)
+ if (data_count == 0)
return ERROR_DOS(ERRDOS, ERRnoaccess);
- if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, total_data_count, security_info_sent)))
+ if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent)))
return ERROR_NT(nt_status);
done:
@@ -1677,15 +1717,15 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
/****************************************************************************
Reply to NT IOCTL
****************************************************************************/
-static int call_nt_transact_ioctl(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup, int setup_count,
- char **ppparams, int parameter_count,
- char **ppdata, int data_count)
+
+static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
unsigned fnum, control;
static BOOL logged_message;
+ char *pdata = *ppdata;
if (setup_count != 8) {
DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
@@ -1695,28 +1735,475 @@ static int call_nt_transact_ioctl(connection_struct *conn,
fnum = SVAL(*ppsetup, 4);
control = IVAL(*ppsetup, 0);
- DEBUG(6,("call_nt_transact_ioctl: fnum=%d control=0x%x\n",
+ DEBUG(10,("call_nt_transact_ioctl: fnum=%d control=0x%08x\n",
fnum, control));
switch (control) {
- case NTIOCTL_SET_SPARSE:
+ case FSCTL_SET_SPARSE:
/* pretend this succeeded - tho strictly we should
mark the file sparse (if the local fs supports it)
so we can know if we need to pre-allocate or not */
+
+ DEBUG(10,("FSCTL_SET_SPARSE: fnum=%d control=0x%08x\n",fnum,control));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
+
+ case FSCTL_0x000900C0:
+ /* pretend this succeeded - don't know what this really is
+ but works ok like this --metze
+ */
+
+ DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
+ return -1;
+
+ case FSCTL_GET_REPARSE_POINT:
+ /* pretend this fail - my winXP does it like this
+ * --metze
+ */
+ DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
+ return -1;
+
+ case FSCTL_SET_REPARSE_POINT:
+ /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
+ * --metze
+ */
+
+ DEBUG(1,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
+ return -1;
+
+ case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
+ {
+ /* pretend this succeeded -
+ *
+ * we have to send back a list with all files owned by this SID
+ *
+ * but I have to check that --metze
+ */
+
+ DOM_SID sid;
+ uid_t uid;
+ size_t sid_len=SID_MAX_SIZE;
+
+ DEBUG(1,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control));
+
+ /* this is not the length of the sid :-( so unknown 4 bytes */
+ /*sid_len = IVAL(pdata,0);
+ DEBUGADD(0,("sid_len: (%u)\n",sid_len));*/
+
+ sid_parse(pdata+4,sid_len,&sid);
+ DEBUGADD(2,("SID: %s\n",sid_string_static(&sid)));
+
+ if (NT_STATUS_IS_ERR(sid_to_uid(&sid, &uid))) {
+ DEBUG(0,("sid_to_uid: failed, sid[%s]\n",
+ sid_string_static(&sid)));
+ uid = (-1);
+ }
+
+ /* we can take a look at the find source :-)
+ *
+ * find ./ -uid $uid -name '*' is what we need here
+ *
+ *
+ * and send 4bytes len and then NULL terminated unicode strings
+ * for each file
+ *
+ * but I don't know how to deal with the paged results
+ *
+ * we don't send all files at once
+ * and at the next we should *not* start from the beginning,
+ * so we have to cache the result
+ *
+ * --metze
+ */
+
+ /* this works for now... */
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
+ return -1;
+ }
default:
if (!logged_message) {
logged_message = True; /* Only print this once... */
- DEBUG(3,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
+ DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
control));
}
}
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
-
+
+
+#ifdef HAVE_SYS_QUOTAS
+/****************************************************************************
+ Reply to get user quota
+****************************************************************************/
+
+static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
+{
+ NTSTATUS nt_status = NT_STATUS_OK;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ char *params = *ppparams;
+ char *pdata = *ppdata;
+ char *entry;
+ int data_len=0,param_len=0;
+ int qt_len=0;
+ int entry_len = 0;
+ files_struct *fsp = NULL;
+ uint16 level = 0;
+ size_t sid_len;
+ DOM_SID sid;
+ BOOL start_enum = True;
+ SMB_NTQUOTA_STRUCT qt;
+ SMB_NTQUOTA_LIST *tmp_list;
+ SMB_NTQUOTA_HANDLE *qt_handle = NULL;
+
+ ZERO_STRUCT(qt);
+
+ /* access check */
+ if (conn->admin_user != True) {
+ DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ /*
+ * Ensure minimum number of parameters sent.
+ */
+
+ if (parameter_count < 4) {
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
+ return ERROR_DOS(ERRDOS,ERRinvalidparam);
+ }
+
+ /* maybe we can check the quota_fnum */
+ fsp = file_fsp(params,0);
+ if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
+ DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+
+ /* the NULL pointer cheking for fsp->fake_file_handle->pd
+ * is done by CHECK_NTQUOTA_HANDLE_OK()
+ */
+ qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
+
+ level = SVAL(params,2);
+
+ /* unknown 12 bytes leading in params */
+
+ switch (level) {
+ case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
+ /* seems that we should continue with the enum here --metze */
+
+ if (qt_handle->quota_list!=NULL &&
+ qt_handle->tmp_list==NULL) {
+
+ /* free the list */
+ free_ntquota_list(&(qt_handle->quota_list));
+
+ /* Realloc the size of parameters and data we will return */
+ param_len = 4;
+ params = nttrans_realloc(ppparams, param_len);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ data_len = 0;
+ SIVAL(params,0,data_len);
+
+ break;
+ }
+
+ start_enum = False;
+
+ case TRANSACT_GET_USER_QUOTA_LIST_START:
+
+ if (qt_handle->quota_list==NULL &&
+ qt_handle->tmp_list==NULL) {
+ start_enum = True;
+ }
+
+ if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
+ return ERROR_DOS(ERRSRV,ERRerror);
+
+ /* Realloc the size of parameters and data we will return */
+ param_len = 4;
+ params = nttrans_realloc(ppparams, param_len);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ /* we should not trust the value in max_data_count*/
+ max_data_count = MIN(max_data_count,2048);
+
+ pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
+ if(pdata == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ entry = pdata;
+
+
+ /* set params Size of returned Quota Data 4 bytes*/
+ /* but set it later when we know it */
+
+ /* for each entry push the data */
+
+ if (start_enum) {
+ qt_handle->tmp_list = qt_handle->quota_list;
+ }
+
+ tmp_list = qt_handle->tmp_list;
+
+ for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
+ tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
+
+ sid_len = sid_size(&tmp_list->quotas->sid);
+ entry_len = 40 + sid_len;
+
+ /* nextoffset entry 4 bytes */
+ SIVAL(entry,0,entry_len);
+
+ /* then the len of the SID 4 bytes */
+ SIVAL(entry,4,sid_len);
+
+ /* unknown data 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
+
+ /* the used disk space 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
+
+ /* the soft quotas 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,24,tmp_list->quotas->softlim);
+
+ /* the hard quotas 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
+
+ /* and now the SID */
+ sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
+ }
+
+ qt_handle->tmp_list = tmp_list;
+
+ /* overwrite the offset of the last entry */
+ SIVAL(entry-entry_len,0,0);
+
+ data_len = 4+qt_len;
+ /* overwrite the params quota_data_len */
+ SIVAL(params,0,data_len);
+
+ break;
+
+ case TRANSACT_GET_USER_QUOTA_FOR_SID:
+
+ /* unknown 4 bytes IVAL(pdata,0) */
+
+ if (data_count < 8) {
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ sid_len = IVAL(pdata,4);
+
+ if (data_count < 8+sid_len) {
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8+sid_len));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ data_len = 4+40+sid_len;
+
+ if (max_data_count < data_len) {
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
+ max_data_count, data_len));
+ param_len = 4;
+ SIVAL(params,0,data_len);
+ data_len = 0;
+ nt_status = NT_STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ sid_parse(pdata+8,sid_len,&sid);
+
+
+ if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
+ ZERO_STRUCT(qt);
+ /*
+ * we have to return zero's in all fields
+ * instead of returning an error here
+ * --metze
+ */
+ }
+
+ /* Realloc the size of parameters and data we will return */
+ param_len = 4;
+ params = nttrans_realloc(ppparams, param_len);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ pdata = nttrans_realloc(ppdata, data_len);
+ if(pdata == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ entry = pdata;
+
+ /* set params Size of returned Quota Data 4 bytes*/
+ SIVAL(params,0,data_len);
+
+ /* nextoffset entry 4 bytes */
+ SIVAL(entry,0,0);
+
+ /* then the len of the SID 4 bytes */
+ SIVAL(entry,4,sid_len);
+
+ /* unknown data 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
+
+ /* the used disk space 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,16,qt.usedspace);
+
+ /* the soft quotas 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,24,qt.softlim);
+
+ /* the hard quotas 8 bytes SMB_BIG_UINT */
+ SBIG_UINT(entry,32,qt.hardlim);
+
+ /* and now the SID */
+ sid_linearize(entry+40, sid_len, &sid);
+
+ break;
+
+ default:
+ DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ break;
+ }
+
+ send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len, pdata, data_len);
+
+ return -1;
+}
+
+/****************************************************************************
+ Reply to set user quota
+****************************************************************************/
+
+static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
+{
+ char *params = *ppparams;
+ char *pdata = *ppdata;
+ int data_len=0,param_len=0;
+ SMB_NTQUOTA_STRUCT qt;
+ size_t sid_len;
+ DOM_SID sid;
+ files_struct *fsp = NULL;
+
+ ZERO_STRUCT(qt);
+
+ /* access check */
+ if (conn->admin_user != True) {
+ DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ /*
+ * Ensure minimum number of parameters sent.
+ */
+
+ if (parameter_count < 2) {
+ DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
+ return ERROR_DOS(ERRDOS,ERRinvalidparam);
+ }
+
+ /* maybe we can check the quota_fnum */
+ fsp = file_fsp(params,0);
+ if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
+ DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+
+ if (data_count < 40) {
+ DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ /* offset to next quota record.
+ * 4 bytes IVAL(pdata,0)
+ * unused here...
+ */
+
+ /* sid len */
+ sid_len = IVAL(pdata,4);
+
+ if (data_count < 40+sid_len) {
+ DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40+sid_len));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ /* unknown 8 bytes in pdata
+ * maybe its the change time in NTTIME
+ */
+
+ /* the used space 8 bytes (SMB_BIG_UINT)*/
+ qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
+#ifdef LARGE_SMB_OFF_T
+ qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,20) != 0)&&
+ ((qt.usedspace != 0xFFFFFFFF)||
+ (IVAL(pdata,20)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
+ qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
+#ifdef LARGE_SMB_OFF_T
+ qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,28) != 0)&&
+ ((qt.softlim != 0xFFFFFFFF)||
+ (IVAL(pdata,28)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
+ qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
+#ifdef LARGE_SMB_OFF_T
+ qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,36) != 0)&&
+ ((qt.hardlim != 0xFFFFFFFF)||
+ (IVAL(pdata,36)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ sid_parse(pdata+40,sid_len,&sid);
+ DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
+
+ /* 44 unknown bytes left... */
+
+ if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, pdata, data_len);
+
+ return -1;
+}
+#endif /* HAVE_SYS_QUOTAS */
+
/****************************************************************************
Reply to a SMBNTtrans.
****************************************************************************/
@@ -1918,8 +2405,10 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
case NT_TRANSACT_CREATE:
START_PROFILE_NESTED(NT_transact_create);
outsize = call_nt_transact_create(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_create);
break;
case NT_TRANSACT_IOCTL:
@@ -1927,39 +2416,67 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
length, bufsize,
&setup, setup_count,
- &params, parameter_count,
- &data, data_count);
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_ioctl);
break;
case NT_TRANSACT_SET_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_set_security_desc);
outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_set_security_desc);
break;
case NT_TRANSACT_NOTIFY_CHANGE:
START_PROFILE_NESTED(NT_transact_notify_change);
outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_notify_change);
break;
case NT_TRANSACT_RENAME:
START_PROFILE_NESTED(NT_transact_rename);
outsize = call_nt_transact_rename(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_rename);
break;
case NT_TRANSACT_QUERY_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_query_security_desc);
outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_query_security_desc);
break;
+#ifdef HAVE_SYS_QUOTAS
+ case NT_TRANSACT_GET_USER_QUOTA:
+ START_PROFILE_NESTED(NT_transact_get_user_quota);
+ outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf,
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
+ END_PROFILE_NESTED(NT_transact_get_user_quota);
+ break;
+ case NT_TRANSACT_SET_USER_QUOTA:
+ START_PROFILE_NESTED(NT_transact_set_user_quota);
+ outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf,
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
+ END_PROFILE_NESTED(NT_transact_set_user_quota);
+ break;
+#endif /* HAVE_SYS_QUOTAS */
default:
/* Error in request */
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 510b28172d2..15171ce9e3d 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -38,13 +38,13 @@ static int fd_open(struct connection_struct *conn, char *fname,
flags |= O_NOFOLLOW;
#endif
- fd = conn->vfs_ops.open(conn,fname,flags,mode);
+ fd = SMB_VFS_OPEN(conn,fname,flags,mode);
/* Fix for files ending in '.' */
if((fd == -1) && (errno == ENOENT) &&
(strchr_m(fname,'.')==NULL)) {
pstrcat(fname,".");
- fd = conn->vfs_ops.open(conn,fname,flags,mode);
+ fd = SMB_VFS_OPEN(conn,fname,flags,mode);
}
DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
@@ -186,9 +186,9 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
int ret;
if (fsp->fd == -1)
- ret = vfs_stat(conn, fname, psbuf);
+ ret = SMB_VFS_STAT(conn, fname, psbuf);
else {
- ret = vfs_fstat(fsp,fsp->fd,psbuf);
+ ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
/* If we have an fd, this stat should succeed. */
if (ret == -1)
DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
@@ -259,7 +259,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct *
unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
return -1;
} else {
- return conn->vfs_ops.ftruncate(fsp,fsp->fd,0);
+ return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0);
}
}
@@ -1073,7 +1073,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
/*
* We are modifing the file after open - update the stat struct..
*/
- if ((truncate_unless_locked(conn,fsp) == -1) || (vfs_fstat(fsp,fsp->fd,psbuf)==-1)) {
+ if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
unlock_share_entry_fsp(fsp);
fd_close(conn,fsp);
file_free(fsp);
@@ -1148,11 +1148,11 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* selected.
*/
- if (!file_existed && !def_acl && (conn->vfs_ops.fchmod_acl != NULL)) {
+ if (!file_existed && !def_acl) {
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
- if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
+ if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
errno = saved_errno; /* Ignore ENOSYS */
} else if (new_mode) {
@@ -1161,9 +1161,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
/* Attributes need changing. File already existed. */
- if (conn->vfs_ops.fchmod_acl != NULL) {
+ {
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
- ret = conn->vfs_ops.fchmod_acl(fsp, fsp->fd, new_mode);
+ ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
if (ret == -1 && errno == ENOSYS) {
errno = saved_errno; /* Ignore ENOSYS */
@@ -1174,7 +1174,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
}
- if ((ret == -1) && (conn->vfs_ops.fchmod(fsp, fsp->fd, new_mode) == -1))
+ if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
fname, (int)new_mode));
}
@@ -1280,14 +1280,14 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return NULL;
}
- if(vfs_mkdir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
+ if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
return NULL;
}
- if(vfs_stat(conn,fname, psbuf) != 0) {
+ if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
file_free(fsp);
return NULL;
}
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 632dfe9e291..85256877937 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -391,7 +391,7 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
/*
* Keep this as a debug case - eventually we can remove it.
*/
- case (CMD_REPLY | KERNEL_OPLOCK_BREAK_CMD):
+ case 0x8001:
DEBUG(0,("process_local_message: Received unsolicited break \
reply - dumping info.\n"));
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index a362db7d564..12eef46595d 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -158,9 +158,9 @@ static mode_t convert_permset_to_mode_t(connection_struct *conn, SMB_ACL_PERMSET
{
mode_t ret = 0;
- ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0);
- ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0);
- ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0);
+ ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0);
+ ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0);
+ ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0);
return ret;
}
@@ -190,18 +190,18 @@ static mode_t unix_perms_to_acl_perms(mode_t mode, int r_mask, int w_mask, int x
static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_ACL_PERMSET_T *p_permset)
{
- if (conn->vfs_ops.sys_acl_clear_perms(conn, *p_permset) == -1)
+ if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) == -1)
return -1;
if (mode & S_IRUSR) {
- if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_READ) == -1)
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1)
return -1;
}
if (mode & S_IWUSR) {
- if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_WRITE) == -1)
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1)
return -1;
}
if (mode & S_IXUSR) {
- if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
return -1;
}
return 0;
@@ -637,62 +637,6 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
}
}
- /*
- * When setting ACLs and missing one out of SMB_ACL_USER_OBJ,
- * SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER, try to retrieve current
- * values. For user and other a simple vfs_stat would do, but
- * we would get mask instead of group. Let's do it via ACL.
- */
-
- if (setting_acl && (!got_user || !got_grp || !got_other)) {
-
- SMB_ACL_ENTRY_T entry;
- int entry_id = SMB_ACL_FIRST_ENTRY;
-
- if(fsp->is_directory || fsp->fd == -1) {
- current_posix_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
- } else {
- current_posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd);
- }
-
- if (current_posix_acl) {
- while (conn->vfs_ops.sys_acl_get_entry(conn, current_posix_acl, entry_id, &entry) == 1) {
- SMB_ACL_TAG_T tagtype;
- SMB_ACL_PERMSET_T permset;
-
- /* get_next... */
- if (entry_id == SMB_ACL_FIRST_ENTRY)
- entry_id = SMB_ACL_NEXT_ENTRY;
-
- /* Is this a MASK entry ? */
- if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
- continue;
-
- if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
- continue;
-
- switch(tagtype) {
- case SMB_ACL_USER_OBJ:
- current_user_perms = convert_permset_to_mode_t(conn, permset);
- got_current_user = True;
- break;
- case SMB_ACL_GROUP_OBJ:
- current_grp_perms = convert_permset_to_mode_t(conn, permset);
- got_current_grp = True;
- break;
- case SMB_ACL_OTHER:
- current_other_perms = convert_permset_to_mode_t(conn, permset);
- got_current_other = True;
- break;
- }
- }
- conn->vfs_ops.sys_acl_free_acl(conn, current_posix_acl);
- } else {
- DEBUG(10,("ensure_canon_entry_valid: failed to retrieve current ACL of %s\n",
- fsp->fsp_name));
- }
- }
-
if (!got_user) {
if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) {
DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
@@ -1684,7 +1628,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
SMB_ACL_ENTRY_T entry;
size_t ace_count;
- while ( posix_acl && (conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1)) {
+ while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
DOM_SID sid;
@@ -1696,10 +1640,10 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
entry_id = SMB_ACL_NEXT_ENTRY;
/* Is this a MASK entry ? */
- if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
continue;
- if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
continue;
/* Decide which SID to use based on the ACL type. */
@@ -1712,7 +1656,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
break;
case SMB_ACL_USER:
{
- uid_t *puid = (uid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry);
+ uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
if (puid == NULL) {
DEBUG(0,("canonicalise_acl: Failed to get uid.\n"));
continue;
@@ -1729,7 +1673,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
uid_to_sid( &sid, *puid);
unix_ug.uid = *puid;
owner_type = UID_ACE;
- conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)puid,tagtype);
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
break;
}
case SMB_ACL_GROUP_OBJ:
@@ -1740,7 +1684,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
break;
case SMB_ACL_GROUP:
{
- gid_t *pgid = (gid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry);
+ gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
if (pgid == NULL) {
DEBUG(0,("canonicalise_acl: Failed to get gid.\n"));
continue;
@@ -1748,7 +1692,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
gid_to_sid( &sid, *pgid);
unix_ug.gid = *pgid;
owner_type = GID_ACE;
- conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)pgid,tagtype);
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
break;
}
case SMB_ACL_MASK:
@@ -1833,7 +1777,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
{
connection_struct *conn = fsp->conn;
BOOL ret = False;
- SMB_ACL_T the_acl = conn->vfs_ops.sys_acl_init(conn, (int)count_canon_ace_list(the_ace) + 1);
+ SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, (int)count_canon_ace_list(the_ace) + 1);
canon_ace *p_ace;
int i;
SMB_ACL_ENTRY_T mask_entry;
@@ -1891,7 +1835,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Get the entry for this ACE.
*/
- if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &the_entry) == -1) {
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -1917,7 +1861,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* First tell the entry what type of ACE this is.
*/
- if (conn->vfs_ops.sys_acl_set_tag_type(conn, the_entry, p_ace->type) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, p_ace->type) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -1929,7 +1873,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) {
- if (conn->vfs_ops.sys_acl_set_qualifier(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -1940,7 +1884,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Convert the mode_t perms in the canon_ace to a POSIX permset.
*/
- if (conn->vfs_ops.sys_acl_get_permset(conn, the_entry, &the_permset) == -1) {
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to get permset on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -1956,7 +1900,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* ..and apply them to the entry.
*/
- if (conn->vfs_ops.sys_acl_set_permset(conn, the_entry, the_permset) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -1967,17 +1911,17 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
}
if (needs_mask && !got_mask_entry) {
- if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &mask_entry) == -1) {
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &mask_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) ));
goto done;
}
- if (conn->vfs_ops.sys_acl_set_tag_type(conn, mask_entry, SMB_ACL_MASK) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, mask_entry, SMB_ACL_MASK) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) ));
goto done;
}
- if (conn->vfs_ops.sys_acl_get_permset(conn, mask_entry, &mask_permset) == -1) {
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, mask_entry, &mask_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to get mask permset. (%s)\n", strerror(errno) ));
goto done;
}
@@ -1987,7 +1931,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
goto done;
}
- if (conn->vfs_ops.sys_acl_set_permset(conn, mask_entry, mask_permset) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, mask_entry, mask_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) ));
goto done;
}
@@ -1997,7 +1941,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Check if the ACL is valid.
*/
- if (conn->vfs_ops.sys_acl_valid(conn, the_acl) == -1) {
+ if (SMB_VFS_SYS_ACL_VALID(conn, the_acl) == -1) {
DEBUG(0,("set_canon_ace_list: ACL type (%s) is invalid for set (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
strerror(errno) ));
@@ -2009,7 +1953,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if(default_ace || fsp->is_directory || fsp->fd == -1) {
- if (conn->vfs_ops.sys_acl_set_file(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
* when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
@@ -2028,7 +1972,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
goto done;
}
} else {
- if (conn->vfs_ops.sys_acl_set_fd(fsp, fsp->fd, the_acl) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
* when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
@@ -2052,7 +1996,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
done:
if (the_acl != NULL)
- conn->vfs_ops.sys_acl_free_acl(conn, the_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
return ret;
}
@@ -2083,8 +2027,8 @@ SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl)
if (!the_acl)
return NULL;
- if (conn->vfs_ops.sys_acl_get_entry(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
- conn->vfs_ops.sys_acl_free_acl(conn, the_acl);
+ if (SMB_VFS_SYS_ACL_GET_ENTRY(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
return NULL;
}
return the_acl;
@@ -2221,7 +2165,7 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
the UNIX style get ACL.
****************************************************************************/
-size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
+size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
{
extern DOM_SID global_sid_Builtin_Administrators;
extern DOM_SID global_sid_Builtin_Users;
@@ -2250,34 +2194,34 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
if(fsp->is_directory || fsp->fd == -1) {
/* Get the stat struct for the owner info. */
- if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
+ if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
return 0;
}
/*
* Get the ACL from the path.
*/
- posix_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
+ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
/*
* If it's a directory get the default POSIX ACL.
*/
if(fsp->is_directory) {
- dir_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
dir_acl = free_empty_sys_acl(conn, dir_acl);
}
} else {
/* Get the stat struct for the owner info. */
- if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
return 0;
}
/*
* Get the ACL from the fd.
*/
- posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd);
+ posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
}
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
@@ -2297,182 +2241,182 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
create_file_sids(&sbuf, &owner_sid, &group_sid);
}
- /*
- * In the optimum case Creator Owner and Creator Group would be used for
- * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
- * would lead to usability problems under Windows: The Creator entries
- * are only available in browse lists of directories and not for files;
- * additionally the identity of the owning group couldn't be determined.
- * We therefore use those identities only for Default ACLs.
- */
+ if (security_info & DACL_SECURITY_INFORMATION) {
- /* Create the canon_ace lists. */
- file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
+ /*
+ * In the optimum case Creator Owner and Creator Group would be used for
+ * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
+ * would lead to usability problems under Windows: The Creator entries
+ * are only available in browse lists of directories and not for files;
+ * additionally the identity of the owning group couldn't be determined.
+ * We therefore use those identities only for Default ACLs.
+ */
- /* We must have *some* ACLS. */
+ /* Create the canon_ace lists. */
+ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
- if (count_canon_ace_list(file_ace) == 0) {
- DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
- return 0;
- }
-
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
- &global_sid_Creator_Owner,
- &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
- }
+ /* We must have *some* ACLS. */
+
+ if (count_canon_ace_list(file_ace) == 0) {
+ DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
+ return 0;
+ }
- /*
- * Create the NT ACE list from the canonical ace lists.
- */
+ if (fsp->is_directory && dir_acl) {
+ dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ &global_sid_Creator_Owner,
+ &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
+ }
- {
- canon_ace *ace;
- int nt_acl_type;
- int i;
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
- if (nt4_compatible_acls() && dir_ace) {
- /*
- * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
- * but no non-INHERIT_ONLY entry for one SID. So we only
- * remove entries from the Access ACL if the
- * corresponding Default ACL entries have also been
- * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
- * are exceptions. We can do nothing
- * intelligent if the Default ACL contains entries that
- * are not also contained in the Access ACL, so this
- * case will still fail under NT 4.
- */
+ {
+ canon_ace *ace;
+ int nt_acl_type;
+ int i;
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
+ if (nt4_compatible_acls() && dir_ace) {
+ /*
+ * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
+ * but no non-INHERIT_ONLY entry for one SID. So we only
+ * remove entries from the Access ACL if the
+ * corresponding Default ACL entries have also been
+ * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
+ * are exceptions. We can do nothing
+ * intelligent if the Default ACL contains entries that
+ * are not also contained in the Access ACL, so this
+ * case will still fail under NT 4.
+ */
- ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
+ DLIST_REMOVE(dir_ace, ace);
SAFE_FREE(ace);
+
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
+ }
}
- }
- /*
- * WinNT doesn't usually have Creator Group
- * in browse lists, so we send this entry to
- * WinNT even if it contains no relevant
- * permissions. Once we can add
- * Creator Group to browse lists we can
- * re-enable this.
- */
+ /*
+ * WinNT doesn't usually have Creator Group
+ * in browse lists, so we send this entry to
+ * WinNT even if it contains no relevant
+ * permissions. Once we can add
+ * Creator Group to browse lists we can
+ * re-enable this.
+ */
#if 0
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
- }
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
+ }
#endif
- ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
- SAFE_FREE(ace);
- }
- } else {
-
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
- }
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
+ }
}
- }
-
- num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
- /* Allocate the ace list. */
- if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
- goto done;
- }
+ num_acls = count_canon_ace_list(file_ace);
+ num_dir_acls = count_canon_ace_list(dir_ace);
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
-
- /*
- * Create the NT ACE list from the canonical ace lists.
- */
-
- ace = file_ace;
+ /* Allocate the ace list. */
+ if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
+ goto done;
+ }
- for (i = 0; i < num_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
+ memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
+
+ ace = file_ace;
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
- }
+ for (i = 0; i < num_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
+ }
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
- }
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
- ace = dir_ace;
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
+ }
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
+ ace = dir_ace;
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
- }
+ for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
+
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY);
- }
-
- /*
- * Merge POSIX default ACLs and normal ACLs into one NT ACE.
- * Win2K needs this to get the inheritance correct when replacing ACLs
- * on a directory tree. Based on work by Jim @ IBM.
- */
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY);
+ }
- num_aces = merge_default_aces(nt_ace_list, num_aces);
+ /*
+ * Merge POSIX default ACLs and normal ACLs into one NT ACE.
+ * Win2K needs this to get the inheritance correct when replacing ACLs
+ * on a directory tree. Based on work by Jim @ IBM.
+ */
- /*
- * Sort to force deny entries to the front.
- */
+ num_aces = merge_default_aces(nt_ace_list, num_aces);
- if (num_aces)
- qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
- }
+ /*
+ * Sort to force deny entries to the front.
+ */
+
+ if (num_aces)
+ qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
+ }
- if (num_aces) {
- if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
- goto done;
+ if (num_aces) {
+ if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+ goto done;
+ }
}
- }
+ } /* security_info & DACL_SECURITY_INFORMATION */
- *ppdesc = make_standard_sec_desc( main_loop_talloc_get(), &owner_sid, &group_sid, psa, &sd_size);
+ *ppdesc = make_standard_sec_desc( main_loop_talloc_get(),
+ (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
+ (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
+ psa,
+ &sd_size);
if(!*ppdesc) {
DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
sd_size = 0;
} else {
+#if 1
+ /*
+ * JRA. Setting this flag causes W2K clients not to
+ * propagate ACL sets down a directory tree correctly.
+ */
/*
* Windows 2000: The DACL_PROTECTED flag in the security
* descriptor marks the ACL as non-inheriting, i.e., no
@@ -2483,14 +2427,15 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
* flag doesn't seem to bother Windows NT.
*/
(*ppdesc)->type |= SE_DESC_DACL_PROTECTED;
+#endif
}
done:
if (posix_acl)
- conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
if (dir_acl)
- conn->vfs_ops.sys_acl_free_acl(conn, dir_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
SAFE_FREE(nt_ace_list);
@@ -2514,14 +2459,14 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
SMB_STRUCT_STAT st;
/* try the direct way first */
- ret = vfs_chown(conn, fname, uid, gid);
+ ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
if (ret == 0)
return 0;
if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
return -1;
- if (vfs_stat(conn,fname,&st))
+ if (SMB_VFS_STAT(conn,fname,&st))
return -1;
fsp = open_file_fchmod(conn,fname,&st);
@@ -2536,7 +2481,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
become_root();
/* Keep the current file gid the same. */
- ret = vfswrap_fchown(fsp, fsp->fd, uid, (gid_t)-1);
+ ret = SMB_VFS_FCHOWN(fsp, fsp->fd, uid, (gid_t)-1);
unbecome_root();
close_file_fchmod(fsp);
@@ -2579,10 +2524,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
*/
if(fsp->is_directory || fsp->fd == -1) {
- if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0)
+ if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
return False;
} else {
- if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0)
+ if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0)
return False;
}
@@ -2628,7 +2573,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
*/
if(fsp->is_directory) {
- if(vfs_stat(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
+ if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
return False;
}
} else {
@@ -2636,9 +2581,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
int ret;
if(fsp->fd == -1)
- ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
else
- ret = vfs_fstat(fsp,fsp->fd,&sbuf);
+ ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf);
if(ret != 0)
return False;
@@ -2706,7 +2651,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* No default ACL - delete one if it exists.
*/
- if (conn->vfs_ops.sys_acl_delete_def_file(conn, fsp->fsp_name) == -1) {
+ if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) {
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);
@@ -2735,7 +2680,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
fsp->fsp_name, (unsigned int)posix_perms ));
- if(conn->vfs_ops.chmod(conn,fsp->fsp_name, posix_perms) == -1) {
+ if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) {
DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
free_canon_ace_list(file_ace_list);
@@ -2777,7 +2722,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
SMB_ACL_ENTRY_T entry;
int num_entries = 0;
- while ( conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1) {
+ while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
mode_t perms;
@@ -2786,10 +2731,10 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
if (entry_id == SMB_ACL_FIRST_ENTRY)
entry_id = SMB_ACL_NEXT_ENTRY;
- if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
return -1;
- if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
return -1;
num_entries++;
@@ -2820,7 +2765,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
if (map_acl_perms_to_permset(conn, perms, &permset) == -1)
return -1;
- if (conn->vfs_ops.sys_acl_set_permset(conn, entry, permset) == -1)
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) == -1)
return -1;
}
@@ -2846,17 +2791,17 @@ static int copy_access_acl(connection_struct *conn, const char *from, const char
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = conn->vfs_ops.sys_acl_get_file(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
+ if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
goto done;
- ret = conn->vfs_ops.sys_acl_set_file(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
+ ret = SMB_VFS_SYS_ACL_SET_FILE(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
done:
- conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
return ret;
}
@@ -2898,17 +2843,17 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fd)) == NULL)
+ if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fd)) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
goto done;
- ret = conn->vfs_ops.sys_acl_set_fd(fsp, fd, posix_acl);
+ ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fd, posix_acl);
done:
- conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
return ret;
}
@@ -2918,14 +2863,14 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
BOOL directory_has_default_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T dir_acl = conn->vfs_ops.sys_acl_get_file( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
BOOL has_acl = False;
SMB_ACL_ENTRY_T entry;
- if (dir_acl != NULL && (conn->vfs_ops.sys_acl_get_entry(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
+ if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
has_acl = True;
if (dir_acl)
- conn->vfs_ops.sys_acl_free_acl(conn, dir_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
return has_acl;
}
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index 5b843bd09a6..91c952aa902 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -27,6 +27,15 @@
#include "includes.h"
+#ifndef HAVE_SYS_QUOTAS
+
+/* just a quick hack because sysquotas.h is included before linux/quota.h */
+#ifdef QUOTABLOCK_SIZE
+#undef QUOTABLOCK_SIZE
+#endif
+
+#ifdef WITH_QUOTAS
+
#if defined(VXFS_QUOTA)
/*
@@ -1112,3 +1121,108 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
#endif /* SUNOS5 || ... */
#endif /* VXFS_QUOTA */
+
+#else /* WITH_QUOTAS */
+
+BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+{
+ (*bsize) = 512; /* This value should be ignored */
+
+ /* And just to be sure we set some values that hopefully */
+ /* will be larger that any possible real-world value */
+ (*dfree) = (SMB_BIG_UINT)-1;
+ (*dsize) = (SMB_BIG_UINT)-1;
+
+ /* As we have select not to use quotas, allways fail */
+ return False;
+}
+#endif /* WITH_QUOTAS */
+
+#else /* HAVE_SYS_QUOTAS */
+/* wrapper to the new sys_quota interface
+ this file should be removed later
+ */
+BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+{
+ int r;
+ SMB_DISK_QUOTA D;
+ unid_t id;
+
+ id.uid = geteuid();
+
+ r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D);
+
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ *bsize = D.bsize;
+ if (r == -1) {
+ if (errno == EDQUOT) {
+ *dfree =0;
+ *dsize =D.curblocks;
+ return (True);
+ } else {
+ goto try_group_quota;
+ }
+ }
+
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ if (
+ (D.softlimit && D.curblocks >= D.softlimit) ||
+ (D.hardlimit && D.curblocks >= D.hardlimit) ||
+ (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
+ (D.ihardlimit && D.curinodes>=D.ihardlimit)
+ ) {
+ *dfree = 0;
+ *dsize = D.curblocks;
+ } else if (D.softlimit==0 && D.hardlimit==0) {
+ goto try_group_quota;
+ } else {
+ if (D.softlimit == 0)
+ D.softlimit = D.hardlimit;
+ *dfree = D.softlimit - D.curblocks;
+ *dsize = D.softlimit;
+ }
+
+ return True;
+
+try_group_quota:
+#ifdef HAVE_GROUP_QUOTA
+ id.gid = getegid();
+
+ r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D);
+
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ *bsize = D.bsize;
+ if (r == -1) {
+ if (errno == EDQUOT) {
+ *dfree =0;
+ *dsize =D.curblocks;
+ return (True);
+ } else {
+ return False;
+ }
+ }
+
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ if (
+ (D.softlimit && D.curblocks >= D.softlimit) ||
+ (D.hardlimit && D.curblocks >= D.hardlimit) ||
+ (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
+ (D.ihardlimit && D.curinodes>=D.ihardlimit)
+ ) {
+ *dfree = 0;
+ *dsize = D.curblocks;
+ } else if (D.softlimit==0 && D.hardlimit==0) {
+ return False;
+ } else {
+ if (D.softlimit == 0)
+ D.softlimit = D.hardlimit;
+ *dfree = D.softlimit - D.curblocks;
+ *dsize = D.softlimit;
+ }
+
+ return (True);
+#else /* HAVE_GROUP_QUOTA */
+ return False;
+#endif /* HAVE_GROUP_QUOTA */
+}
+#endif /* HAVE_SYS_QUOTAS */
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index b2dab2fea25..be51a328911 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -148,7 +148,7 @@ int reply_tcon(connection_struct *conn,
const char *service;
pstring service_buf;
pstring password;
- fstring dev;
+ pstring dev;
int outsize = 0;
uint16 vuid = SVAL(inbuf,smb_uid);
int pwlen=0;
@@ -204,7 +204,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
{
fstring service;
DATA_BLOB password;
-
+
/* what the cleint thinks the device is */
fstring client_devicetype;
/* what the server tells the client the share represents */
@@ -283,15 +283,16 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
set_message_end(outbuf,p);
} else {
/* NT sets the fstype of IPC$ to the null string */
- const char *fsname = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
+ const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
set_message(outbuf,3,0,True);
-
- p = smb_buf(outbuf);
+
+ p = smb_buf(outbuf);
p += srvstr_push(outbuf, p, server_devicetype, -1,
- STR_TERMINATE|STR_ASCII);
- p += srvstr_push(outbuf, p, fsname, -1,
- STR_TERMINATE);
+ STR_TERMINATE|STR_ASCII);
+ p += srvstr_push(outbuf, p, fstype, -1,
+ STR_TERMINATE);
+
set_message_end(outbuf,p);
/* what does setting this bit do? It is set by NT4 and
@@ -398,7 +399,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
mode = SVAL(inbuf,smb_vwv0);
if (check_name(name,conn)) {
- if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0)
+ if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
if (!(ok = S_ISDIR(sbuf.st_mode)))
errno = ENOTDIR;
}
@@ -457,7 +458,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
} else {
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (check_name(fname,conn)) {
- if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0) {
+ if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
mode = dos_mode(conn,fname,&sbuf);
size = sbuf.st_size;
mtime = sbuf.st_mtime;
@@ -552,7 +553,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
SMB_BIG_UINT dfree,dsize,bsize;
START_PROFILE(SMBdskattr);
- conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
+ SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
outsize = set_message(outbuf,5,0,True);
@@ -1127,7 +1128,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- vfs_stat(conn,fname,&sbuf);
+ SMB_VFS_STAT(conn,fname,&sbuf);
/* Open file in dos compatibility share mode. */
/* We should fail if file does not exist. */
@@ -1226,7 +1227,7 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
if (!CAN_WRITE(conn))
return NT_STATUS_MEDIA_WRITE_PROTECTED;
- if (conn->vfs_ops.lstat(conn,fname,&sbuf) != 0)
+ if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0)
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
fmode = dos_mode(conn,fname,&sbuf);
@@ -1312,7 +1313,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
error = can_delete(directory,conn,dirtype);
if (!NT_STATUS_IS_OK(error)) return error;
- if (vfs_unlink(conn,directory) == 0) {
+ if (SMB_VFS_UNLINK(conn,directory) == 0) {
count++;
}
} else {
@@ -1342,7 +1343,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
error = can_delete(fname,conn,dirtype);
if (!NT_STATUS_IS_OK(error)) continue;
- if (vfs_unlink(conn,fname) == 0) count++;
+ if (SMB_VFS_UNLINK(conn,fname) == 0) count++;
DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
}
CloseDir(dirptr);
@@ -1428,7 +1429,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
header.length = 4;
header.free = NULL;
- if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
/*
* Special hack for broken Linux with no 64 bit clean sendfile. If we
* return ENOSYS then pretend we just got a normal read.
@@ -1463,6 +1464,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
+ extern struct current_user current_user;
ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
@@ -1552,7 +1554,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
if (size < sizeneeded) {
SMB_STRUCT_STAT st;
- if (vfs_fstat(fsp,fsp->fd,&st) == 0)
+ if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
size = st.st_size;
if (!fsp->can_write)
fsp->size = size;
@@ -1721,7 +1723,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
SMB_STRUCT_STAT sbuf;
DATA_BLOB header;
- if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1)
+ if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
if (startpos > sbuf.st_size)
@@ -1748,7 +1750,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
header.length = data - outbuf;
header.free = NULL;
- if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
/*
* Special hack for broken Linux with no 64 bit clean sendfile. If we
* return ENOSYS then pretend we just got a normal read.
@@ -2260,7 +2262,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
break;
}
- if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) {
+ if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
/*
* Check for the special case where a seek before the start
* of the file sets the offset to zero. Added in the CIFS spec,
@@ -2272,7 +2274,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if(umode == SEEK_CUR) {
- if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
+ if((current_pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
END_PROFILE(SMBlseek);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2283,7 +2285,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SMB_STRUCT_STAT sbuf;
- if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
+ if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
END_PROFILE(SMBlseek);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2292,7 +2294,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
if(current_pos < 0)
- res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
+ res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
}
if(res == -1) {
@@ -2360,6 +2362,7 @@ int reply_exit(connection_struct *conn,
int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
int dum_buffsize)
{
+ extern struct current_user current_user;
int outsize = 0;
time_t mtime;
int32 eclass = 0, err = 0;
@@ -2380,7 +2383,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
* We can only use CHECK_FSP if we know it's not a directory.
*/
- if(!fsp || (fsp->conn != conn)) {
+ if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
END_PROFILE(SMBclose);
return ERROR_DOS(ERRDOS,ERRbadfid);
}
@@ -2827,7 +2830,7 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
unix_convert(directory,conn,0,&bad_path,&sbuf);
if (check_name(directory, conn))
- ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
if (ret == -1) {
NTSTATUS nterr = set_bad_path_error(errno, bad_path);
@@ -2898,7 +2901,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
pstrcat(fullname, "/");
pstrcat(fullname, dname);
- if(conn->vfs_ops.lstat(conn,fullname, &st) != 0) {
+ if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
ret = True;
break;
}
@@ -2908,11 +2911,11 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
ret = True;
break;
}
- if(vfs_rmdir(conn,fullname) != 0) {
+ if(SMB_VFS_RMDIR(conn,fullname) != 0) {
ret = True;
break;
}
- } else if(vfs_unlink(conn,fullname) != 0) {
+ } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
ret = True;
break;
}
@@ -2929,7 +2932,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
{
BOOL ok;
- ok = (vfs_rmdir(conn,directory) == 0);
+ ok = (SMB_VFS_RMDIR(conn,directory) == 0);
if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
/*
* Check to see if the only thing in this directory are
@@ -2971,21 +2974,21 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
pstrcat(fullname, "/");
pstrcat(fullname, dname);
- if(conn->vfs_ops.lstat(conn,fullname, &st) != 0)
+ if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
break;
if(st.st_mode & S_IFDIR) {
if(lp_recursive_veto_delete(SNUM(conn))) {
if(recursive_rmdir(conn, fullname) != 0)
break;
}
- if(vfs_rmdir(conn,fullname) != 0)
+ if(SMB_VFS_RMDIR(conn,fullname) != 0)
break;
- } else if(vfs_unlink(conn,fullname) != 0)
+ } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
break;
}
CloseDir(dirptr);
/* Retry the rmdir */
- ok = (vfs_rmdir(conn,directory) == 0);
+ ok = (SMB_VFS_RMDIR(conn,directory) == 0);
} else {
CloseDir(dirptr);
}
@@ -3104,7 +3107,7 @@ static BOOL resolve_wildcards(const char *name1, char *name2)
if (ext2[0]) {
snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
} else {
- StrnCpy(pname2, root2, available_space - 1);
+ pstrcpy_base(pname2, root2, name2);
}
return(True);
@@ -3281,7 +3284,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- if(conn->vfs_ops.rename(conn,directory, newname) == 0) {
+ if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
directory,newname));
return NT_STATUS_OK;
@@ -3348,7 +3351,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
continue;
}
- if (!conn->vfs_ops.rename(conn,fname,destname))
+ if (!SMB_VFS_RENAME(conn,fname,destname))
count++;
DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
}
@@ -3442,7 +3445,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
if (!target_is_directory && count)
ofun = FILE_EXISTS_OPEN;
- if (vfs_stat(conn,dest,&sbuf2) == -1)
+ if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
ZERO_STRUCTP(&sbuf2);
fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
@@ -3454,7 +3457,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
}
if ((ofun&3) == 1) {
- if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
+ if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
/*
* Stop the copy from occurring.
@@ -3938,7 +3941,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
/* Setup the timeout in seconds. */
- lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
+ lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+499)/500);
/* Now do any requested locks */
data += ((large_file_format ? 20 : 10)*num_ulocks);
@@ -4382,8 +4385,9 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
SIVAL(outbuf,smb_vwv6,0);
SIVAL(outbuf,smb_vwv8,0);
} else {
+ uint32 allocation_size = get_allocation_size(fsp, &sbuf);
SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
- SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
+ SIVAL(outbuf,smb_vwv8,allocation_size);
}
SSVAL(outbuf,smb_vwv10, mode);
diff --git a/source/smbd/server.c b/source/smbd/server.c
index c24fc5134de..07723cc20e7 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -634,6 +634,12 @@ static BOOL init_structs(void )
main program.
****************************************************************************/
+/* Declare prototype for build_options() to avoid having to run it through
+ mkproto.h. Mixing $(builddir) and $(srcdir) source files in the current
+ prototype generation system is too complicated. */
+
+void build_options(BOOL screen);
+
int main(int argc,const char *argv[])
{
/* shall I run as a daemon */
@@ -877,10 +883,6 @@ static BOOL init_structs(void )
if (!init_change_notify())
exit(1);
- /* Setup privileges database */
- if (!privilege_init())
- exit(1);
-
/* re-initialise the timezone */
TimeInit();
diff --git a/source/smbd/service.c b/source/smbd/service.c
index c9f53305514..31bb343474b 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -704,14 +704,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/* Invoke VFS make connection hook */
- if (conn->vfs_ops.connect) {
- if (conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) {
- DEBUG(0,("make_connection: VFS make connection failed!\n"));
- change_to_root_user();
- conn_free(conn);
- *status = NT_STATUS_UNSUCCESSFUL;
- return NULL;
- }
+ if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
+ DEBUG(0,("make_connection: VFS make connection failed!\n"));
+ change_to_root_user();
+ conn_free(conn);
+ *status = NT_STATUS_UNSUCCESSFUL;
+ return NULL;
}
/* we've finished with the user stuff - go back to root */
@@ -872,13 +870,8 @@ void close_cnum(connection_struct *conn, uint16 vuid)
get_remote_machine_name(),conn->client_address,
lp_servicename(SNUM(conn))));
- if (conn->vfs_ops.disconnect != NULL) {
-
- /* Call VFS disconnect hook */
-
- conn->vfs_ops.disconnect(conn);
-
- }
+ /* Call VFS disconnect hook */
+ SMB_VFS_DISCONNECT(conn);
yield_connection(conn, lp_servicename(SNUM(conn)));
diff --git a/source/smbd/session.c b/source/smbd/session.c
index 07a95042340..b7f3bc43e75 100644
--- a/source/smbd/session.c
+++ b/source/smbd/session.c
@@ -33,6 +33,8 @@ BOOL session_claim(user_struct *vuser)
{
int i = 0;
TDB_DATA data;
+ struct sockaddr sa;
+ struct in_addr *client_ip;
struct sessionid sessionid;
uint32 pid = (uint32)sys_getpid();
TDB_DATA key;
@@ -117,6 +119,8 @@ BOOL session_claim(user_struct *vuser)
fstrcpy(sessionid.remote_machine, get_remote_machine_name());
fstrcpy(sessionid.ip_addr, client_addr());
+ client_ip = client_inaddr(&sa);
+
if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) {
DEBUG(1,("pam_session rejected the session for %s [%s]\n",
sessionid.username, sessionid.id_str));
@@ -136,6 +140,7 @@ BOOL session_claim(user_struct *vuser)
#if WITH_UTMP
if (lp_utmp()) {
sys_utmp_claim(sessionid.username, sessionid.hostname,
+ client_ip,
sessionid.id_str, sessionid.id_num);
}
#endif
@@ -153,7 +158,8 @@ void session_yield(user_struct *vuser)
{
TDB_DATA dbuf;
struct sessionid sessionid;
- TDB_DATA key;
+ struct in_addr *client_ip;
+ TDB_DATA key;
if (!tdb) return;
@@ -171,11 +177,14 @@ void session_yield(user_struct *vuser)
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
+ client_ip = interpret_addr2(sessionid.ip_addr);
+
SAFE_FREE(dbuf.dptr);
#if WITH_UTMP
if (lp_utmp()) {
sys_utmp_yield(sessionid.username, sessionid.hostname,
+ client_ip,
sessionid.id_str, sessionid.id_num);
}
#endif
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index 44bae48990c..79758bcfe2e 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -242,7 +242,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
} else {
scp = (stat_cache_entry *)(hash_elem->value);
DO_PROFILE_INC(statcache_hits);
- if(vfs_stat(conn,scp->translated_path, pst) != 0) {
+ if(SMB_VFS_STAT(conn,scp->translated_path, pst) != 0) {
/* Discard this entry - it doesn't exist in the filesystem. */
hash_remove(&stat_cache, hash_elem);
return False;
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index de598d67139..2bf250a980f 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-2001
+ Copyright (C) Jeremy Allison 1994-2001
+ Copyright (C) Stefan (metze) Metzmacher 2003
Extensively modified by Andrew Tridgell, 1995
@@ -28,6 +29,7 @@ extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
extern uint32 global_client_caps;
+extern struct current_user current_user;
#define get_file_size(sbuf) ((sbuf).st_size)
@@ -549,12 +551,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcat(pathreal,dname);
if (INFO_LEVEL_IS_UNIX(info_level)) {
- if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
+ if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
continue;
}
- } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
+ } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as
* directories */
@@ -647,8 +649,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,l2_cbList,0); /* No extended attributes */
p += l2_achName;
nameptr = p;
- p += align_string(outbuf, p, 0);
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
SCVAL(nameptr, -1, len-2);
else
@@ -680,14 +681,14 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(mangled_name, fname);
mangle_map(mangled_name,True,True,SNUM(conn));
mangled_name[12] = 0;
- len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
+ len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
SSVAL(p, 0, len);
} else {
SSVAL(p,0,0);
*(p+2) = 0;
}
p += 2 + 24;
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(q,0,len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -708,7 +709,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
p += 4;
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(p, -4, len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -727,13 +728,13 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SOFF_T(p,0,file_size);
SOFF_T(p,8,allocation_size);
p += 16;
- SIVAL(p,0,nt_extmode); p += 4;
+ SIVAL(p,0,nt_extmode);
p += 4;
- SIVAL(p,0,0); p += 4;
- len = srvstr_push(outbuf, p, fname, -1, 0);
- SIVAL(p, -4, len);
- p += len;
+ SIVAL(p,4,0); /* ea size */
+ len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII);
+ SIVAL(p, 0, len);
+ p += 8 + len;
len = PTR_DIFF(p, pdata);
len = (len + 3) & ~3;
@@ -747,7 +748,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p += 4;
/* this must *not* be null terminated or w2k gets in a loop trying to set an
acl on a dir (tridge) */
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(p, -4, len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -1318,10 +1319,11 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
+ int quota_flag = 0;
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
- if(vfs_stat(conn,".",&st)!=0) {
+ if(SMB_VFS_STAT(conn,".",&st)!=0) {
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
@@ -1338,7 +1340,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
SIVAL(pdata,l1_idFileSystem,st.st_dev);
SIVAL(pdata,l1_cSectorUnit,bsize/512);
SIVAL(pdata,l1_cUnit,dsize);
@@ -1357,7 +1359,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
* the called hostname and the service name.
*/
SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
- len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 0);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
@@ -1367,19 +1369,26 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
+
+#if defined(HAVE_SYS_QUOTAS)
+ quota_flag = FILE_VOLUME_QUOTAS;
+#endif
+
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
+ (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
+ quota_flag); /* FS ATTRIBUTES */
+
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(outbuf, pdata+12, fstype, -1, 0);
+ len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
SIVAL(pdata,8,len);
data_len = 12 + len;
break;
case SMB_QUERY_FS_LABEL_INFO:
case SMB_FS_LABEL_INFORMATION:
- len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
data_len = 4 + len;
SIVAL(pdata,0,len);
break;
@@ -1394,7 +1403,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
(str_checksum(local_machine)<<16));
- len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+18, vname, -1, 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",
@@ -1406,7 +1415,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
@@ -1436,7 +1445,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
@@ -1470,6 +1479,78 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
SIVAL(pdata,4,0); /* characteristics */
break;
+#ifdef HAVE_SYS_QUOTAS
+ case SMB_FS_QUOTA_INFORMATION:
+ /*
+ * what we have to send --metze:
+ *
+ * Unknown1: 24 NULL bytes
+ * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
+ * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
+ * Quota Flags: 2 byte :
+ * Unknown3: 6 NULL bytes
+ *
+ * 48 bytes total
+ *
+ * details for Quota Flags:
+ *
+ * 0x0020 Log Limit: log if the user exceeds his Hard Quota
+ * 0x0010 Log Warn: log if the user exceeds his Soft Quota
+ * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
+ * 0x0001 Enable Quotas: enable quota for this fs
+ *
+ */
+ {
+ /* we need to fake up a fsp here,
+ * because its not send in this call
+ */
+ files_struct fsp;
+ SMB_NTQUOTA_STRUCT quotas;
+
+ ZERO_STRUCT(fsp);
+ ZERO_STRUCT(quotas);
+
+ fsp.conn = conn;
+ fsp.fnum = -1;
+ fsp.fd = -1;
+
+ /* access check */
+ if (conn->admin_user != True) {
+ DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ 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))));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ data_len = 48;
+
+ DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
+
+ /* Unknown1 24 NULL bytes*/
+ SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
+ SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
+ SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
+
+ /* Default Soft Quota 8 bytes */
+ SBIG_UINT(pdata,24,quotas.softlim);
+
+ /* Default Hard Quota 8 bytes */
+ SBIG_UINT(pdata,32,quotas.hardlim);
+
+ /* Quota flag 2 bytes */
+ SSVAL(pdata,40,quotas.qflags);
+
+ /* Unknown3 6 NULL bytes */
+ SSVAL(pdata,42,0);
+ SIVAL(pdata,44,0);
+
+ break;
+ }
+#endif /* HAVE_SYS_QUOTAS */
case SMB_FS_OBJECTID_INFORMATION:
data_len = 64;
break;
@@ -1511,6 +1592,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return -1;
}
+#ifdef HAVE_SYS_QUOTAS
/****************************************************************************
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
@@ -1519,18 +1601,110 @@ static int call_trans2setfsinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length, int bufsize,
char **pparams, int total_params, char **ppdata, int total_data)
{
- /* Just say yes we did it - there is nothing that
- can be set here so it doesn't matter. */
+ char *pdata = *ppdata;
+ char *params = *pparams;
+ files_struct *fsp = NULL;
+ uint16 info_level;
int outsize;
- DEBUG(3,("call_trans2setfsinfo\n"));
+ SMB_NTQUOTA_STRUCT quotas;
+
+ ZERO_STRUCT(quotas);
- if (!CAN_WRITE(conn))
+ DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
+
+ /* access check */
+ if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
+ DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+
+ /* */
+ if (total_params < 4) {
+ DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
+ total_params));
+ return ERROR_DOS(ERRDOS,ERRinvalidparam);
+ }
+
+ fsp = file_fsp(params,0);
+
+ if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
+ DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+ info_level = SVAL(params,2);
+
+ switch(info_level) {
+ case SMB_FS_QUOTA_INFORMATION:
+ /* note: normaly there're 48 bytes,
+ * but we didn't use the last 6 bytes for now
+ * --metze
+ */
+ if (total_data < 42) {
+ DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
+ total_data));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ /* unknown_1 24 NULL bytes in pdata*/
+
+ /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
+ quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
+#ifdef LARGE_SMB_OFF_T
+ quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,28) != 0)&&
+ ((quotas.softlim != 0xFFFFFFFF)||
+ (IVAL(pdata,28)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
+ quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
+#ifdef LARGE_SMB_OFF_T
+ quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,36) != 0)&&
+ ((quotas.hardlim != 0xFFFFFFFF)||
+ (IVAL(pdata,36)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* quota_flags 2 bytes **/
+ quotas.qflags = SVAL(pdata,40);
+
+ /* unknown_2 6 NULL bytes follow*/
+
+ /* 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))));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ break;
+ default:
+ DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
+ info_level));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ break;
+ }
+
+ /*
+ * sending this reply works fine,
+ * but I'm not sure it's the same
+ * like windows do...
+ * --metze
+ */
outsize = set_message(outbuf,10,0,True);
return outsize;
}
+#endif /* HAVE_SYS_QUOTAS */
/****************************************************************************
* Utility function to set bad path error.
@@ -1589,7 +1763,20 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
- if(fsp && (fsp->is_directory || fsp->fd == -1)) {
+ if(fsp && (fsp->fake_file_handle)) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ pstrcpy(fname, fsp->fsp_name);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn)) {
+ DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
@@ -1605,13 +1792,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (vfs_lstat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1624,11 +1811,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
CHECK_FSP(fsp,conn);
pstrcpy(fname, fsp->fsp_name);
- if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
+ if((pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
delete_pending = fsp->delete_on_close;
@@ -1655,13 +1842,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (vfs_lstat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1733,9 +1920,17 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,l1_cbFile,(uint32)file_size);
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
- SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
+ SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */
break;
+ case SMB_INFO_IS_NAME_VALID:
+ if (tran_call == TRANSACT2_QFILEINFO) {
+ /* os/2 needs this ? really ?*/
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+ }
+ data_size = 0;
+ break;
+
case SMB_INFO_QUERY_EAS_FROM_LIST:
data_size = 24;
put_dos_date2(pdata,0,c_time);
@@ -1748,12 +1943,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_INFO_QUERY_ALL_EAS:
data_size = 4;
- SIVAL(pdata,0,data_size);
+ SIVAL(pdata,0,0); /* ea size */
break;
- case 6:
- return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
-
case SMB_FILE_BASIC_INFORMATION:
case SMB_QUERY_FILE_BASIC_INFO:
@@ -1836,6 +2028,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_QUERY_FILE_ALL_INFO:
+ case SMB_FILE_ALL_INFORMATION:
put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
@@ -1848,20 +2041,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
pdata += 24;
- SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
- pdata += 8; /* index number */
pdata += 4; /* EA info */
- if (mode & aRONLY)
- SIVAL(pdata,0,0xA9);
- else
- SIVAL(pdata,0,0xd01BF);
- pdata += 4;
- SOFF_T(pdata,0,pos); /* current offset */
- pdata += 8;
- SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
- pdata += 4;
- pdata += 4; /* alignment */
- len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
SIVAL(pdata,0,len);
pdata += 4 + len;
data_size = PTR_DIFF(pdata,(*ppdata));
@@ -1915,28 +2096,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
#if 0
- /* Not yet finished... JRA */
- case 1018:
- {
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
- SIVAL(pdata,36,0); /* ??? */
- SIVAL(pdata,40,0x20); /* ??? */
- SIVAL(pdata,44,0); /* ??? */
- SOFF_T(pdata,48,size);
- SIVAL(pdata,56,0x1); /* ??? */
- SIVAL(pdata,60,0); /* ??? */
- SIVAL(pdata,64,0); /* ??? */
- SIVAL(pdata,68,length); /* Following string length in bytes. */
- dos_PutUniCode(pdata+72,,False);
- break;
- }
-#endif
-
-#if 0
/*
* NT4 server just returns "invalid query" to this - if we try to answer
* it then NTws gets a BSOD! (tridge).
@@ -1958,8 +2117,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
break;
+ case SMB_QUERY_COMPRESSION_INFO:
case SMB_FILE_COMPRESSION_INFORMATION:
- SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,0,file_size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
@@ -2054,7 +2214,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
#else
return(UNIXERROR(ERRDOS,ERRbadlink));
#endif
- len = conn->vfs_ops.readlink(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
+ len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
if (len == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
buffer[len] = 0;
@@ -2178,7 +2338,7 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
pstrcpy(link_dest, "./");
}
- if (conn->vfs_ops.realpath(conn,link_dest,resolved_name) == NULL)
+ if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
return -1;
pstrcpy(link_dest, resolved_name);
@@ -2229,7 +2389,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
mode_t unixmode = 0;
+ if (!params)
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+
if (tran_call == TRANSACT2_SETFILEINFO) {
+ if (total_params < 4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
@@ -2269,7 +2435,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
pstrcpy(fname, fsp->fsp_name);
fd = fsp->fd;
- if (vfs_fstat(fsp,fd,&sbuf) != 0) {
+ if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
@@ -2461,7 +2627,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath));
ret = vfs_allocate_file_space(new_fsp, allocation_size);
- if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
+ if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
new_fsp->fnum, strerror(errno)));
ret = -1;
@@ -2469,7 +2635,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
close_file(new_fsp,True);
} else {
ret = vfs_allocate_file_space(fsp, allocation_size);
- if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
+ if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
fsp->fnum, strerror(errno)));
ret = -1;
@@ -2609,7 +2775,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
0%o for file %s\n", (double)dev, unixmode, fname ));
/* Ok - do the mknod. */
- if (conn->vfs_ops.mknod(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
+ if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
inherit_access_acl(conn, fname, unixmode);
@@ -2628,7 +2794,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (raw_unixmode != SMB_MODE_NO_CHANGE) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
(unsigned int)unixmode, fname ));
- if (vfs_chmod(conn,fname,unixmode) != 0)
+ if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2639,7 +2805,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0)
+ if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2650,7 +2816,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0)
+ if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
break;
@@ -2677,7 +2843,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
fname, link_dest ));
- if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0)
+ if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -2702,7 +2868,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
fname, link_dest ));
- if (conn->vfs_ops.link(conn,link_dest,fname) != 0)
+ if (SMB_VFS_LINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -2854,7 +3020,7 @@ static int call_trans2mkdir(connection_struct *conn,
unix_convert(directory,conn,0,&bad_path,&sbuf);
if (check_name(directory,conn))
- ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
if(ret < 0) {
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
@@ -3298,13 +3464,14 @@ int reply_trans2(connection_struct *conn,
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
+#ifdef HAVE_SYS_QUOTAS
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
&params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
-
+#endif
case TRANSACT2_QPATHINFO:
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);
diff --git a/source/smbd/utmp.c b/source/smbd/utmp.c
index 6c12cfac626..2c5a1abc824 100644
--- a/source/smbd/utmp.c
+++ b/source/smbd/utmp.c
@@ -81,11 +81,11 @@ lastlog:
Notes:
Each connection requires a small number (starting at 0, working up)
- to represent the line (unum). This must be unique within and across
- all smbd processes.
+ to represent the line. This must be unique within and across all
+ smbd processes. It is the 'id_num' from Samba's session.c code.
The 4 byte 'ut_id' component is vital to distinguish connections,
- of which there could be several hundered or even thousand.
+ of which there could be several hundred or even thousand.
Entries seem to be printable characters, with optional NULL pads.
We need to be distinct from other entries in utmp/wtmp.
@@ -105,11 +105,8 @@ Notes:
Arbitrarily I have chosen to use a distinctive 'SM' for the
first two bytes.
- The remaining two encode the "unum" (see above).
-
- For "utmp consolidate" the suggestion was made to encode the pid into
- those remaining two bytes (16 bits). But recent UNIX (e.g Solaris 8)
- is migrating to pids > 16 bits, so we ought not to do this.
+ The remaining two bytes encode the session 'id_num' (see above).
+ Our caller (session.c) should note our 16-bit limitation.
****************************************************************************/
@@ -126,33 +123,6 @@ Notes:
#endif
/****************************************************************************
- Obtain/release a small number (0 upwards) unique within and across smbds.
-****************************************************************************/
-/*
- * Need a "small" number to represent this connection, unique within this
- * smbd and across all smbds.
- *
- * claim:
- * Start at 0, hunt up for free, unique number "unum" by attempting to
- * store it as a key in a tdb database:
- * key: unum data: pid+conn
- * Also store its inverse, ready for yield function:
- * key: pid+conn data: unum
- *
- * yield:
- * Find key: pid+conn; data is unum; delete record
- * Find key: unum ; delete record.
- *
- * Comment:
- * The claim algorithm (a "for" loop attempting to store numbers in a tdb
- * database) will be increasingly inefficient with larger numbers of
- * connections. Is it possible to write a suitable primitive within tdb?
- *
- * However, by also storing the inverse key/data pair, we at least make
- * the yield algorithm efficient.
- */
-
-/****************************************************************************
Default paths to various {u,w}tmp{,x} files.
****************************************************************************/
@@ -484,6 +454,7 @@ static int ut_id_encode(int i, char *fourbyte)
*/
static BOOL sys_utmp_fill(struct utmp *u,
const char *username, const char *hostname,
+ struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct timeval timeval;
@@ -503,10 +474,6 @@ static BOOL sys_utmp_fill(struct utmp *u,
/*
* ut_line:
* If size limit proves troublesome, then perhaps use "ut_id_encode()".
- *
- * Temporary variable "line_tmp" avoids trouble:
- * o with unwanted trailing NULL if ut_line full;
- * o with overflow if ut_line would be more than full.
*/
if (strlen(id_str) > sizeof(u->ut_line)) {
DEBUG(1,("id_str [%s] is too long for %d char utmp field\n",
@@ -538,8 +505,9 @@ static BOOL sys_utmp_fill(struct utmp *u,
#if defined(HAVE_UT_UT_HOST)
utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
#endif
-
#if defined(HAVE_UT_UT_ADDR)
+ if (ipaddr)
+ u->ut_addr = ipaddr->s_addr;
/*
* "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20.
* Volunteer to implement, please ...
@@ -561,6 +529,7 @@ static BOOL sys_utmp_fill(struct utmp *u,
****************************************************************************/
void sys_utmp_yield(const char *username, const char *hostname,
+ struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct utmp u;
@@ -576,7 +545,7 @@ void sys_utmp_yield(const char *username, const char *hostname,
u.ut_type = DEAD_PROCESS;
#endif
- if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return;
+ if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
sys_utmp_update(&u, NULL, False);
}
@@ -586,6 +555,7 @@ void sys_utmp_yield(const char *username, const char *hostname,
****************************************************************************/
void sys_utmp_claim(const char *username, const char *hostname,
+ struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct utmp u;
@@ -596,7 +566,7 @@ void sys_utmp_claim(const char *username, const char *hostname,
u.ut_type = USER_PROCESS;
#endif
- if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return;
+ if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
sys_utmp_update(&u, hostname, True);
}
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 491fa70e687..8d44a1a0fa1 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -30,18 +30,18 @@
is sure to try and execute them. These stubs are used to prevent
this possibility. */
-int vfswrap_dummy_connect(connection_struct *conn, const char *service, const char *user)
+int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
{
return 0; /* Return >= 0 for success */
}
-void vfswrap_dummy_disconnect(connection_struct *conn)
+void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn)
{
}
/* Disk operations */
-SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
SMB_BIG_UINT result;
@@ -52,7 +52,7 @@ SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL s
/* Directory operations */
-DIR *vfswrap_opendir(connection_struct *conn, const char *fname)
+DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
{
DIR *result;
@@ -62,7 +62,7 @@ DIR *vfswrap_opendir(connection_struct *conn, const char *fname)
return result;
}
-struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
+struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
struct dirent *result;
@@ -72,7 +72,7 @@ struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
return result;
}
-int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode)
+int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
int result;
BOOL has_dacl = False;
@@ -93,17 +93,15 @@ int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode)
* mess up any inherited ACL bits that were set. JRA.
*/
int saved_errno = errno; /* We may get ENOSYS */
- if (conn->vfs_ops.chmod_acl != NULL) {
- if ((conn->vfs_ops.chmod_acl(conn, path, mode) == -1) && (errno == ENOSYS))
- errno = saved_errno;
- }
+ if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS))
+ errno = saved_errno;
}
END_PROFILE(syscall_mkdir);
return result;
}
-int vfswrap_rmdir(connection_struct *conn, const char *path)
+int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
int result;
@@ -113,7 +111,7 @@ int vfswrap_rmdir(connection_struct *conn, const char *path)
return result;
}
-int vfswrap_closedir(connection_struct *conn, DIR *dirp)
+int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
int result;
@@ -125,7 +123,7 @@ int vfswrap_closedir(connection_struct *conn, DIR *dirp)
/* File operations */
-int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t mode)
+int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
{
int result;
@@ -135,7 +133,7 @@ int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t m
return result;
}
-int vfswrap_close(files_struct *fsp, int fd)
+int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
{
int result;
@@ -146,7 +144,7 @@ int vfswrap_close(files_struct *fsp, int fd)
return result;
}
-ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n)
+ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
{
ssize_t result;
@@ -156,7 +154,7 @@ ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n)
return result;
}
-ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n)
+ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
{
ssize_t result;
@@ -166,7 +164,7 @@ ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n)
return result;
}
-SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
+SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
{
SMB_OFF_T result = 0;
@@ -192,7 +190,7 @@ SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int wh
return result;
}
-ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
+ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
SMB_OFF_T offset, size_t n)
{
ssize_t result;
@@ -203,7 +201,7 @@ ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const D
return result;
}
-int vfswrap_rename(connection_struct *conn, const char *old, const char *new)
+int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
{
int result;
@@ -213,7 +211,7 @@ int vfswrap_rename(connection_struct *conn, const char *old, const char *new)
return result;
}
-int vfswrap_fsync(files_struct *fsp, int fd)
+int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
{
#ifdef HAVE_FSYNC
int result;
@@ -228,7 +226,7 @@ int vfswrap_fsync(files_struct *fsp, int fd)
#endif
}
-int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
{
int result;
@@ -238,7 +236,7 @@ int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sb
return result;
}
-int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
{
int result;
@@ -248,7 +246,7 @@ int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
return result;
}
-int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
+int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
{
int result;
@@ -258,7 +256,7 @@ int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sb
return result;
}
-int vfswrap_unlink(connection_struct *conn, const char *path)
+int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
int result;
@@ -268,7 +266,7 @@ int vfswrap_unlink(connection_struct *conn, const char *path)
return result;
}
-int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode)
+int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
int result;
@@ -281,9 +279,9 @@ int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode)
*/
- if (conn->vfs_ops.chmod_acl != NULL) {
+ {
int saved_errno = errno; /* We might get ENOSYS */
- if ((result = conn->vfs_ops.chmod_acl(conn, path, mode)) == 0) {
+ if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) {
END_PROFILE(syscall_chmod);
return result;
}
@@ -296,10 +294,9 @@ int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode)
return result;
}
-int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode)
+int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
int result;
- struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
START_PROFILE(syscall_fchmod);
@@ -309,9 +306,9 @@ int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode)
* group owner bits directly. JRA.
*/
- if (vfs_ops->fchmod_acl != NULL) {
+ {
int saved_errno = errno; /* We might get ENOSYS */
- if ((result = vfs_ops->fchmod_acl(fsp, fd, mode)) == 0) {
+ if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
END_PROFILE(syscall_chmod);
return result;
}
@@ -330,7 +327,7 @@ int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode)
return result;
}
-int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
{
int result;
@@ -340,7 +337,7 @@ int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gi
return result;
}
-int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid)
+int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
{
#ifdef HAVE_FCHOWN
int result;
@@ -356,7 +353,7 @@ int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid)
#endif
}
-int vfswrap_chdir(connection_struct *conn, const char *path)
+int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
int result;
@@ -366,7 +363,7 @@ int vfswrap_chdir(connection_struct *conn, const char *path)
return result;
}
-char *vfswrap_getwd(connection_struct *conn, char *path)
+char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path)
{
char *result;
@@ -376,7 +373,7 @@ char *vfswrap_getwd(connection_struct *conn, char *path)
return result;
}
-int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *times)
+int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
{
int result;
@@ -391,18 +388,17 @@ int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *tim
allocate is set.
**********************************************************************/
-static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
+static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
{
- struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
SMB_STRUCT_STAT st;
- SMB_OFF_T currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
+ SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
unsigned char zero_space[4096];
SMB_OFF_T space_to_write;
if (currpos == -1)
return -1;
- if (vfs_ops->fstat(fsp, fd, &st) == -1)
+ if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
return -1;
space_to_write = len - st.st_size;
@@ -420,7 +416,7 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
return sys_ftruncate(fd, len);
/* Write out the real space on disk. */
- if (vfs_ops->lseek(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
+ if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
return -1;
space_to_write = len - st.st_size;
@@ -430,7 +426,7 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
SMB_OFF_T retlen;
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
- retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
+ retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
if (retlen <= 0)
return -1;
@@ -438,16 +434,15 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
}
/* Seek to where we were */
- if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
+ if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
return -1;
return 0;
}
-int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
+int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
{
int result = -1;
- struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
SMB_STRUCT_STAT st;
char c = 0;
SMB_OFF_T currpos;
@@ -455,7 +450,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
START_PROFILE(syscall_ftruncate);
if (lp_strict_allocate(SNUM(fsp->conn))) {
- result = strict_allocate_ftruncate(fsp, fd, len);
+ result = strict_allocate_ftruncate(handle, fsp, fd, len);
END_PROFILE(syscall_ftruncate);
return result;
}
@@ -473,7 +468,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate. Provide alternate implementation
for this */
- currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
+ currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
if (currpos == -1) {
goto done;
}
@@ -482,7 +477,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
size in which case the ftruncate above should have
succeeded or shorter, in which case seek to len - 1 and
write 1 byte of zero */
- if (vfs_ops->fstat(fsp, fd, &st) == -1) {
+ if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
goto done;
}
@@ -503,14 +498,14 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
goto done;
}
- if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1)
+ if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
goto done;
- if (vfs_ops->write(fsp, fd, &c, 1)!=1)
+ if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
goto done;
/* Seek to where we were */
- if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
+ if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
goto done;
result = 0;
@@ -520,7 +515,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
return result;
}
-BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
BOOL result;
@@ -531,7 +526,7 @@ BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T
return result;
}
-int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath)
+int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
{
int result;
@@ -541,7 +536,7 @@ int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *ne
return result;
}
-int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz)
+int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
{
int result;
@@ -551,7 +546,7 @@ int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_
return result;
}
-int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath)
+int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
{
int result;
@@ -561,7 +556,7 @@ int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpa
return result;
}
-int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
+int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
{
int result;
@@ -571,7 +566,7 @@ int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SM
return result;
}
-char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path)
+char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
{
char *result;
@@ -581,27 +576,27 @@ char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved
return result;
}
-size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc)
+size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(fget_nt_acl);
- result = get_nt_acl(fsp, ppdesc);
+ result = get_nt_acl(fsp, security_info, ppdesc);
END_PROFILE(fget_nt_acl);
return result;
}
-size_t vfswrap_get_nt_acl(files_struct *fsp, const char *name, SEC_DESC **ppdesc)
+size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(get_nt_acl);
- result = get_nt_acl(fsp, ppdesc);
+ result = get_nt_acl(fsp, security_info, ppdesc);
END_PROFILE(get_nt_acl);
return result;
}
-BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
{
BOOL result;
@@ -611,7 +606,7 @@ BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, S
return result;
}
-BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
{
BOOL result;
@@ -621,132 +616,236 @@ BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_inf
return result;
}
-int vfswrap_chmod_acl(connection_struct *conn, const char *name, mode_t mode)
+int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
{
+#ifdef HAVE_NO_ACL
+ errno = ENOSYS;
+ return -1;
+#else
int result;
START_PROFILE(chmod_acl);
result = chmod_acl(conn, name, mode);
END_PROFILE(chmod_acl);
return result;
+#endif
}
-int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode)
+int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
{
+#ifdef HAVE_NO_ACL
+ errno = ENOSYS;
+ return -1;
+#else
int result;
START_PROFILE(fchmod_acl);
result = fchmod_acl(fsp, fd, mode);
END_PROFILE(fchmod_acl);
return result;
+#endif
}
-int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
{
return sys_acl_get_entry(theacl, entry_id, entry_p);
}
-int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
{
return sys_acl_get_tag_type(entry_d, tag_type_p);
}
-int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
{
return sys_acl_get_permset(entry_d, permset_p);
}
-void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
+void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
{
return sys_acl_get_qualifier(entry_d);
}
-SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
+SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
{
return sys_acl_get_file(path_p, type);
}
-SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd)
+SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
{
return sys_acl_get_fd(fd);
}
-int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset)
+int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
{
return sys_acl_clear_perms(permset);
}
-int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
{
return sys_acl_add_perm(permset, perm);
}
-char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
+char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
{
return sys_acl_to_text(theacl, plen);
}
-SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count)
+SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
{
return sys_acl_init(count);
}
-int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
{
return sys_acl_create_entry(pacl, pentry);
}
-int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
{
return sys_acl_set_tag_type(entry, tagtype);
}
-int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
+int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
{
return sys_acl_set_qualifier(entry, qual);
}
-int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
{
return sys_acl_set_permset(entry, permset);
}
-int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl )
+int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
{
return sys_acl_valid(theacl );
}
-int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
{
return sys_acl_set_file(name, acltype, theacl);
}
-int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
+int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
{
return sys_acl_set_fd(fd, theacl);
}
-int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path)
+int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
return sys_acl_delete_def_file(path);
}
-int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
{
return sys_acl_get_perm(permset, perm);
}
-int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text)
+int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
{
return sys_acl_free_text(text);
}
-int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl)
+int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
{
return sys_acl_free_acl(posix_acl);
}
-int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
+int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
{
return sys_acl_free_qualifier(qualifier, tagtype);
}
+
+int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_get_quota);
+ result = sys_get_quota(conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_get_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_set_quota);
+ result = sys_set_quota(conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_set_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+/****************************************************************
+ Extended attribute operations.
+*****************************************************************/
+
+ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
+{
+ return sys_getxattr(path, name, value, size);
+}
+
+ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
+{
+ return sys_lgetxattr(path, name, value, size);
+}
+
+ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
+{
+ return sys_fgetxattr(fd, name, value, size);
+}
+
+ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
+{
+ return sys_listxattr(path, list, size);
+}
+
+ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
+{
+ return sys_llistxattr(path, list, size);
+}
+
+ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
+{
+ return sys_flistxattr(fd, list, size);
+}
+
+int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
+{
+ return sys_removexattr(path, name);
+}
+
+int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
+{
+ return sys_lremovexattr(path, name);
+}
+
+int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
+{
+ return sys_fremovexattr(fd, name);
+}
+
+int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_setxattr(path, name, value, size, flags);
+}
+
+int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_lsetxattr(path, name, value, size, flags);
+}
+
+int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_fsetxattr(fd, name, value, size, flags);
+}
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 5fcf9a575e4..5f3abe7efea 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -28,9 +28,9 @@
#define DBGC_CLASS DBGC_VFS
struct vfs_init_function_entry {
- char *name;
- vfs_op_tuple *ops, *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *);
- struct vfs_init_function_entry *prev, *next;
+ char *name;
+ vfs_op_tuple *vfs_op_tuples;
+ struct vfs_init_function_entry *prev, *next;
};
static struct vfs_init_function_entry *backends = NULL;
@@ -42,96 +42,106 @@ struct vfs_syminfo {
void *fptr;
};
-/*
- Opaque (final) vfs operations. This is a combination of first-met opaque vfs operations
- across all currently processed modules. */
-
-static vfs_op_tuple vfs_opaque_ops[SMB_VFS_OP_LAST];
-
/* Default vfs hooks. WARNING: The order of these initialisers is
very important. They must be in the same order as defined in
vfs.h. Change at your own peril. */
-static struct vfs_ops default_vfs_ops = {
-
- /* Disk operations */
-
- vfswrap_dummy_connect,
- vfswrap_dummy_disconnect,
- vfswrap_disk_free,
-
- /* Directory operations */
-
- vfswrap_opendir,
- vfswrap_readdir,
- vfswrap_mkdir,
- vfswrap_rmdir,
- vfswrap_closedir,
-
- /* File operations */
-
- vfswrap_open,
- vfswrap_close,
- vfswrap_read,
- vfswrap_write,
- vfswrap_lseek,
- vfswrap_sendfile,
- vfswrap_rename,
- vfswrap_fsync,
- vfswrap_stat,
- vfswrap_fstat,
- vfswrap_lstat,
- vfswrap_unlink,
- vfswrap_chmod,
- vfswrap_fchmod,
- vfswrap_chown,
- vfswrap_fchown,
- vfswrap_chdir,
- vfswrap_getwd,
- vfswrap_utime,
- vfswrap_ftruncate,
- vfswrap_lock,
- vfswrap_symlink,
- vfswrap_readlink,
- vfswrap_link,
- vfswrap_mknod,
- vfswrap_realpath,
-
- vfswrap_fget_nt_acl,
- vfswrap_get_nt_acl,
- vfswrap_fset_nt_acl,
- vfswrap_set_nt_acl,
-
- /* POSIX ACL operations. */
-#if defined(HAVE_NO_ACLS)
- NULL,
- NULL,
-#else
- vfswrap_chmod_acl,
- vfswrap_fchmod_acl,
-#endif
- vfswrap_sys_acl_get_entry,
- vfswrap_sys_acl_get_tag_type,
- vfswrap_sys_acl_get_permset,
- vfswrap_sys_acl_get_qualifier,
- vfswrap_sys_acl_get_file,
- vfswrap_sys_acl_get_fd,
- vfswrap_sys_acl_clear_perms,
- vfswrap_sys_acl_add_perm,
- vfswrap_sys_acl_to_text,
- vfswrap_sys_acl_init,
- vfswrap_sys_acl_create_entry,
- vfswrap_sys_acl_set_tag_type,
- vfswrap_sys_acl_set_qualifier,
- vfswrap_sys_acl_set_permset,
- vfswrap_sys_acl_valid,
- vfswrap_sys_acl_set_file,
- vfswrap_sys_acl_set_fd,
- vfswrap_sys_acl_delete_def_file,
- vfswrap_sys_acl_get_perm,
- vfswrap_sys_acl_free_text,
- vfswrap_sys_acl_free_acl,
- vfswrap_sys_acl_free_qualifier
+static struct vfs_ops default_vfs = {
+
+ {
+ /* Disk operations */
+
+ vfswrap_dummy_connect,
+ vfswrap_dummy_disconnect,
+ vfswrap_disk_free,
+ vfswrap_get_quota,
+ vfswrap_set_quota,
+
+ /* Directory operations */
+
+ vfswrap_opendir,
+ vfswrap_readdir,
+ vfswrap_mkdir,
+ vfswrap_rmdir,
+ vfswrap_closedir,
+
+ /* File operations */
+
+ vfswrap_open,
+ vfswrap_close,
+ vfswrap_read,
+ vfswrap_write,
+ vfswrap_lseek,
+ vfswrap_sendfile,
+ vfswrap_rename,
+ vfswrap_fsync,
+ vfswrap_stat,
+ vfswrap_fstat,
+ vfswrap_lstat,
+ vfswrap_unlink,
+ vfswrap_chmod,
+ vfswrap_fchmod,
+ vfswrap_chown,
+ vfswrap_fchown,
+ vfswrap_chdir,
+ vfswrap_getwd,
+ vfswrap_utime,
+ vfswrap_ftruncate,
+ vfswrap_lock,
+ vfswrap_symlink,
+ vfswrap_readlink,
+ vfswrap_link,
+ vfswrap_mknod,
+ vfswrap_realpath,
+
+ /* Windows ACL operations. */
+ vfswrap_fget_nt_acl,
+ vfswrap_get_nt_acl,
+ vfswrap_fset_nt_acl,
+ vfswrap_set_nt_acl,
+
+ /* POSIX ACL operations. */
+ vfswrap_chmod_acl,
+ vfswrap_fchmod_acl,
+
+ vfswrap_sys_acl_get_entry,
+ vfswrap_sys_acl_get_tag_type,
+ vfswrap_sys_acl_get_permset,
+ vfswrap_sys_acl_get_qualifier,
+ vfswrap_sys_acl_get_file,
+ vfswrap_sys_acl_get_fd,
+ vfswrap_sys_acl_clear_perms,
+ vfswrap_sys_acl_add_perm,
+ vfswrap_sys_acl_to_text,
+ vfswrap_sys_acl_init,
+ vfswrap_sys_acl_create_entry,
+ vfswrap_sys_acl_set_tag_type,
+ vfswrap_sys_acl_set_qualifier,
+ vfswrap_sys_acl_set_permset,
+ vfswrap_sys_acl_valid,
+ vfswrap_sys_acl_set_file,
+ vfswrap_sys_acl_set_fd,
+ vfswrap_sys_acl_delete_def_file,
+ vfswrap_sys_acl_get_perm,
+ vfswrap_sys_acl_free_text,
+ vfswrap_sys_acl_free_acl,
+ vfswrap_sys_acl_free_qualifier,
+
+ /* EA operations. */
+ vfswrap_getxattr,
+ vfswrap_lgetxattr,
+ vfswrap_fgetxattr,
+ vfswrap_listxattr,
+ vfswrap_llistxattr,
+ vfswrap_flistxattr,
+ vfswrap_removexattr,
+ vfswrap_lremovexattr,
+ vfswrap_fremovexattr,
+ vfswrap_setxattr,
+ vfswrap_lsetxattr,
+ vfswrap_fsetxattr
+
+ }
};
/****************************************************************************
@@ -140,52 +150,46 @@ static struct vfs_ops default_vfs_ops = {
static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
{
- struct vfs_init_function_entry *entry = backends;
- pstring stripped;
-
- module_path_get_name(name, stripped);
-
- while(entry) {
- if (strequal(entry->name, stripped)) return entry;
- entry = entry->next;
- }
+ struct vfs_init_function_entry *entry = backends;
+
+ while(entry) {
+ if (strcmp(entry->name, name)==0) return entry;
+ entry = entry->next;
+ }
- return NULL;
+ return NULL;
}
-NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *))
+NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples)
{
- struct vfs_init_function_entry *entry = backends;
-
- if ((version < SMB_VFS_INTERFACE_CASCADED)) {
- DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
- version, SMB_VFS_INTERFACE_VERSION ));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if ((version < SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
- Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
- version, SMB_VFS_INTERFACE_VERSION, version ));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !init) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (vfs_find_backend_entry(name)) {
- DEBUG(0,("VFS module %s already loaded!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct vfs_init_function_entry));
- entry->name = smb_xstrdup(name);
- entry->init = init;
-
- DLIST_ADD(backends, entry);
- DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
- return NT_STATUS_OK;
+ struct vfs_init_function_entry *entry = backends;
+
+ if ((version != SMB_VFS_INTERFACE_VERSION)) {
+ DEBUG(0, ("Failed to register vfs module.\n"
+ "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
+ "current SMB_VFS_INTERFACE_VERSION is %d.\n"
+ "Please recompile against the current Samba Version!\n",
+ version, SMB_VFS_INTERFACE_VERSION));
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!name || !name[0] || !vfs_op_tuples) {
+ DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vfs_find_backend_entry(name)) {
+ DEBUG(0,("VFS module %s already loaded!\n", name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ entry = smb_xmalloc(sizeof(struct vfs_init_function_entry));
+ entry->name = smb_xstrdup(name);
+ entry->vfs_op_tuples = vfs_op_tuples;
+
+ DLIST_ADD(backends, entry);
+ DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -196,62 +200,10 @@ static void vfs_init_default(connection_struct *conn)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
- memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
- conn->vfs_private = NULL;
-}
-
-/***************************************************************************
- Function to load old VFS modules. Should go away after a while.
- **************************************************************************/
-
-static vfs_op_tuple *vfs_load_old_plugin(connection_struct *conn, const char *vfs_object)
-{
- int vfs_version = -1;
- vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *);
- /* Open object file */
-
- if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
- DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
- return NULL;
- }
-
- /* Get handle on vfs_init() symbol */
-
- init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
-
- if (init_fptr == NULL) {
- DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
- sys_dlclose(conn->vfs_private->handle);
- return NULL;
- }
-
- /* Initialise vfs_ops structure */
- if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) {
- DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object));
- sys_dlclose(conn->vfs_private->handle);
- return NULL;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) {
- DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION ));
- sys_dlclose(conn->vfs_private->handle);
- return NULL;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
- Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version ));
- sys_dlclose(conn->vfs_private->handle);
- return NULL;
- }
-
- return ops;
+ memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops));
+ memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops));
}
-
-
/****************************************************************************
initialise custom vfs hooks
****************************************************************************/
@@ -259,51 +211,82 @@ static vfs_op_tuple *vfs_load_old_plugin(connection_struct *conn, const char *vf
BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
{
vfs_op_tuple *ops;
+ char *module_name = NULL;
+ char *module_param = NULL, *p;
int i;
+ vfs_handle_struct *handle;
struct vfs_init_function_entry *entry;
-
- DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object));
+
+ if (!conn||!vfs_object||!vfs_object[0]) {
+ DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n"));
+ return False;
+ }
if(!backends) static_init_vfs;
+ DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
+
+ module_name = smb_xstrdup(vfs_object);
+
+ p = strchr(module_name, ':');
+
+ if (p) {
+ *p = 0;
+ module_param = p+1;
+ trim_string(module_param, " ", " ");
+ }
+
+ trim_string(module_name, " ", " ");
+
/* First, try to load the module with the new module system */
- if((entry = vfs_find_backend_entry(vfs_object)) ||
- (NT_STATUS_IS_OK(smb_probe_module("vfs", vfs_object)) &&
- (entry = vfs_find_backend_entry(vfs_object)))) {
+ if((entry = vfs_find_backend_entry(module_name)) ||
+ (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) &&
+ (entry = vfs_find_backend_entry(module_name)))) {
- DEBUG(3,("Successfully loaded %s with the new modules system\n", vfs_object));
+ DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
- if ((ops = entry->init(&conn->vfs_ops, conn->vfs_private)) == NULL) {
- DEBUG(0, ("vfs init function from %s failed\n", vfs_object));
- return False;
- }
+ if ((ops = entry->vfs_op_tuples) == NULL) {
+ DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object));
+ SAFE_FREE(module_name);
+ return False;
+ }
} else {
- /* If that doesn't work, fall back to the old system
- * (This part should go away after a while, it's only here
- * for backwards compatibility) */
- DEBUG(2, ("Can't load module %s with new modules system, falling back to compatibility\n",
- vfs_object));
- if ((ops = vfs_load_old_plugin(conn, vfs_object)) == NULL) {
- DEBUG(0, ("vfs init function from %s failed\n", vfs_object));
- return False;
- }
+ DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
+ SAFE_FREE(module_name);
+ return False;
+ }
+
+ handle = (vfs_handle_struct *)talloc_zero(conn->mem_ctx,sizeof(vfs_handle_struct));
+ if (!handle) {
+ DEBUG(0,("talloc_zero() failed!\n"));
+ SAFE_FREE(module_name);
+ return False;
}
+ memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops));
+ handle->conn = conn;
+ if (module_param) {
+ handle->param = talloc_strdup(conn->mem_ctx, module_param);
+ }
+ DLIST_ADD(conn->vfs_handles, handle);
for(i=0; ops[i].op != NULL; i++) {
- DEBUG(3, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
+ DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
/* Check whether this operation was already made opaque by different module */
- if(vfs_opaque_ops[ops[i].type].op == ((void**)&default_vfs_ops)[ops[i].type]) {
+ if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) {
/* No, it isn't overloaded yet. Overload. */
- DEBUG(3, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
- vfs_opaque_ops[ops[i].type] = ops[i];
+ DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
+ ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op;
+ ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle;
}
}
/* Change current VFS disposition*/
- DEBUG(3, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs_ops)[ops[i].type] = ops[i].op;
+ DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
+ ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op;
+ ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle;
}
+ SAFE_FREE(module_name);
return True;
}
@@ -314,71 +297,31 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
BOOL smbd_vfs_init(connection_struct *conn)
{
const char **vfs_objects;
- char *vfs_module, *vfs_path;
unsigned int i = 0;
int j = 0;
- struct smb_vfs_handle_struct *handle;
/* Normal share - initialise with disk access functions */
vfs_init_default(conn);
- vfs_objects = lp_vfsobj(SNUM(conn));
+ vfs_objects = lp_vfs_objects(SNUM(conn));
/* Override VFS functions if 'vfs object' was not specified*/
if (!vfs_objects || !vfs_objects[0])
return True;
-
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- vfs_opaque_ops[i].op = ((void**)&default_vfs_ops)[i];
- vfs_opaque_ops[i].type = i;
- vfs_opaque_ops[i].layer = SMB_VFS_LAYER_OPAQUE;
+
+ for (i=0; vfs_objects[i] ;) {
+ i++;
}
- vfs_path = lp_vfs_path(SNUM(conn));
-
- for (i=0; vfs_objects[i]; i++); /* count passed modules */
-
for (j=i-1; j >= 0; j--) {
- conn->vfs_private = NULL;
- handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct));
- /* Loadable object file */
- handle->handle = NULL;
- DLIST_ADD(conn->vfs_private, handle);
- vfs_module = NULL;
- if (vfs_path && *vfs_path) {
- asprintf(&vfs_module, "%s/%s", vfs_path, vfs_objects[j]);
- } else {
- asprintf(&vfs_module, "%s", vfs_objects[j]);
- }
- if (!vfs_init_custom(conn, vfs_module)) {
- DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_module));
- SAFE_FREE(vfs_module);
- DLIST_REMOVE(conn->vfs_private, handle);
- SAFE_FREE(handle);
+ if (!vfs_init_custom(conn, vfs_objects[j])) {
+ DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
return False;
}
- SAFE_FREE(vfs_module);
}
return True;
}
/*******************************************************************
- Create vfs_ops reflecting current vfs_opaque_ops
-*******************************************************************/
-
-struct vfs_ops *smb_vfs_get_opaque_ops(void)
-{
- int i;
- struct vfs_ops *ops;
-
- ops = smb_xmalloc(sizeof(struct vfs_ops));
-
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- ((void**)ops)[i] = vfs_opaque_ops[i].op;
- }
- return ops;
-}
-
-/*******************************************************************
Check if directory exists.
********************************************************************/
@@ -390,7 +333,7 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
if (!st)
st = &st2;
- if (vfs_stat(conn,dname,st) != 0)
+ if (SMB_VFS_STAT(conn,dname,st) != 0)
return(False);
ret = S_ISDIR(st->st_mode);
@@ -401,24 +344,15 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
}
/*******************************************************************
- vfs getwd wrapper
-********************************************************************/
-
-static char *vfs_getwd(connection_struct *conn, char *path)
-{
- return conn->vfs_ops.getwd(conn,path);
-}
-
-/*******************************************************************
vfs mkdir wrapper
********************************************************************/
-int vfs_mkdir(connection_struct *conn, const char *name, mode_t mode)
+int vfs_MkDir(connection_struct *conn, const char *name, mode_t mode)
{
int ret;
SMB_STRUCT_STAT sbuf;
- if(!(ret=conn->vfs_ops.mkdir(conn,name,mode))) {
+ if(!(ret=SMB_VFS_MKDIR(conn, name, mode))) {
inherit_access_acl(conn, name, mode);
@@ -428,8 +362,8 @@ int vfs_mkdir(connection_struct *conn, const char *name, mode_t mode)
* Consider bits automagically set by UNIX, i.e. SGID bit from parent dir.
*/
if(mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
- !vfs_stat(conn,name,&sbuf) && (mode & ~sbuf.st_mode))
- vfs_chmod(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode));
+ !SMB_VFS_STAT(conn,name,&sbuf) && (mode & ~sbuf.st_mode))
+ SMB_VFS_CHMOD(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode));
}
return ret;
}
@@ -447,7 +381,7 @@ BOOL vfs_object_exist(connection_struct *conn,const char *fname,SMB_STRUCT_STAT
ZERO_STRUCTP(sbuf);
- if (vfs_stat(conn,fname,sbuf) == -1)
+ if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
return(False);
return True;
}
@@ -465,7 +399,7 @@ BOOL vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *
ZERO_STRUCTP(sbuf);
- if (vfs_stat(conn,fname,sbuf) == -1)
+ if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
return False;
return(S_ISREG(sbuf->st_mode));
}
@@ -480,7 +414,7 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
while (total < byte_count)
{
- ssize_t ret = fsp->conn->vfs_ops.read(fsp, fsp->fd, buf + total,
+ ssize_t ret = SMB_VFS_READ(fsp, fsp->fd, buf + total,
byte_count - total);
if (ret == 0) return total;
@@ -505,7 +439,7 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
ssize_t ret;
while (total < N) {
- ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
+ ret = SMB_VFS_WRITE(fsp,fsp->fd,buffer + total,N - total);
if (ret == -1)
return -1;
@@ -528,7 +462,6 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
int ret;
SMB_STRUCT_STAT st;
connection_struct *conn = fsp->conn;
- struct vfs_ops *vfs_ops = &conn->vfs_ops;
SMB_BIG_UINT space_avail;
SMB_BIG_UINT bsize,dfree,dsize;
@@ -545,7 +478,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
return -1;
}
- ret = vfs_fstat(fsp,fsp->fd,&st);
+ ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
if (ret == -1)
return ret;
@@ -559,7 +492,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
fsp->fsp_name, (double)st.st_size ));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
- if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
+ if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
set_filelen_write_cache(fsp, len);
}
return ret;
@@ -572,7 +505,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
len -= st.st_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
- space_avail = conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
+ space_avail = SMB_VFS_DISK_FREE(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
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_size, (double)len, (double)space_avail ));
@@ -598,7 +531,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
release_level_2_oplocks_on_change(fsp);
DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
- if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1)
+ if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, len)) != -1)
set_filelen_write_cache(fsp, len);
return ret;
@@ -613,12 +546,12 @@ static files_struct *out_fsp;
static ssize_t read_fn(int fd, void *buf, size_t len)
{
- return in_fsp->conn->vfs_ops.read(in_fsp, fd, buf, len);
+ return SMB_VFS_READ(in_fsp, fd, buf, len);
}
static ssize_t write_fn(int fd, const void *buf, size_t len)
{
- return out_fsp->conn->vfs_ops.write(out_fsp, fd, buf, len);
+ return SMB_VFS_WRITE(out_fsp, fd, buf, len);
}
SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
@@ -635,13 +568,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
char *vfs_readdirname(connection_struct *conn, void *p)
{
- struct dirent *ptr;
+ struct dirent *ptr= NULL;
char *dname;
if (!p)
return(NULL);
- ptr = (struct dirent *)conn->vfs_ops.readdir(conn,p);
+ ptr = (struct dirent *)SMB_VFS_READDIR(conn,p);
if (!ptr)
return(NULL);
@@ -660,72 +593,6 @@ char *vfs_readdirname(connection_struct *conn, void *p)
return(dname);
}
-/* VFS options not quite working yet */
-
-#if 0
-
-/***************************************************************************
- handle the interpretation of the vfs option parameter
- *************************************************************************/
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
-{
- struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
- int i;
-
- /* Create new vfs option */
-
- new_option = (struct vfs_options *)malloc(sizeof(*new_option));
- if (new_option == NULL) {
- return False;
- }
-
- ZERO_STRUCTP(new_option);
-
- /* Get name and value */
-
- new_option->name = strtok(pszParmValue, "=");
-
- if (new_option->name == NULL) {
- return False;
- }
-
- while(isspace(*new_option->name)) {
- new_option->name++;
- }
-
- for (i = strlen(new_option->name); i > 0; i--) {
- if (!isspace(new_option->name[i - 1])) break;
- }
-
- new_option->name[i] = '\0';
- new_option->name = strdup(new_option->name);
-
- new_option->value = strtok(NULL, "=");
-
- if (new_option->value != NULL) {
-
- while(isspace(*new_option->value)) {
- new_option->value++;
- }
-
- for (i = strlen(new_option->value); i > 0; i--) {
- if (!isspace(new_option->value[i - 1])) break;
- }
-
- new_option->value[i] = '\0';
- new_option->value = strdup(new_option->value);
- }
-
- /* Add to list */
-
- DLIST_ADD(*options, new_option);
-
- return True;
-}
-
-#endif
-
-
/*******************************************************************
A wrapper for vfs_chdir().
********************************************************************/
@@ -741,9 +608,9 @@ int vfs_ChDir(connection_struct *conn, const char *path)
if (*path == '/' && strcsequal(LastDir,path))
return(0);
- DEBUG(3,("vfs_ChDir to %s\n",path));
+ DEBUG(4,("vfs_ChDir to %s\n",path));
- res = vfs_chdir(conn,path);
+ res = SMB_VFS_CHDIR(conn,path);
if (!res)
pstrcpy(LastDir,path);
return(res);
@@ -800,7 +667,7 @@ char *vfs_GetWd(connection_struct *conn, char *path)
*s = 0;
if (!use_getwd_cache)
- return(vfs_getwd(conn,path));
+ return(SMB_VFS_GETWD(conn,path));
/* init the cache */
if (!getwd_cache_init) {
@@ -814,9 +681,9 @@ char *vfs_GetWd(connection_struct *conn, char *path)
/* Get the inode of the current directory, if this doesn't work we're
in trouble :-) */
- if (vfs_stat(conn, ".",&st) == -1) {
+ if (SMB_VFS_STAT(conn, ".",&st) == -1) {
DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
- return(vfs_getwd(conn,path));
+ return(SMB_VFS_GETWD(conn,path));
}
@@ -830,7 +697,7 @@ char *vfs_GetWd(connection_struct *conn, char *path)
the same...) */
if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) {
- if (vfs_stat(conn,ino_list[i].dos_path,&st2) == 0) {
+ if (SMB_VFS_STAT(conn,ino_list[i].dos_path,&st2) == 0) {
if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev &&
(st2.st_mode & S_IFMT) == S_IFDIR) {
pstrcpy (path, ino_list[i].dos_path);
@@ -852,8 +719,8 @@ char *vfs_GetWd(connection_struct *conn, char *path)
The very slow getcwd, which spawns a process on some systems, or the
not quite so bad getwd. */
- if (!vfs_getwd(conn,s)) {
- DEBUG(0,("vfs_GetWd: vfs_getwd call failed, errno %s\n",strerror(errno)));
+ if (!SMB_VFS_GETWD(conn,s)) {
+ DEBUG(0,("vfs_GetWd: SMB_VFS_GETWD call failed, errno %s\n",strerror(errno)));
return (NULL);
}
@@ -909,7 +776,7 @@ static BOOL readlink_check(connection_struct *conn, const char *dir, char *name)
realdir[reallen] = 0;
}
- if (conn->vfs_ops.readlink(conn, name, flink, sizeof(pstring) -1) != -1) {
+ if (SMB_VFS_READLINK(conn, name, flink, sizeof(pstring) -1) != -1) {
DEBUG(3,("reduce_name: file path name %s is a symlink\nChecking it's path\n", name));
if (*flink == '/') {
pstrcpy(cleanlink, flink);
diff --git a/source/smbwrapper/shared.c b/source/smbwrapper/shared.c
index b4cfcf71486..ca8df5841d1 100644
--- a/source/smbwrapper/shared.c
+++ b/source/smbwrapper/shared.c
@@ -179,8 +179,8 @@ void smbw_setshared(const char *name, const char *val)
SSVAL(&variables[shared_size], 0, l1);
SSVAL(&variables[shared_size], 2, l2);
- pstrcpy(&variables[shared_size] + 4, name);
- pstrcpy(&variables[shared_size] + 4 + l1, val);
+ safe_strcpy(&variables[shared_size] + 4, name, l1-1);
+ safe_strcpy(&variables[shared_size] + 4 + l1, val, l2-1);
shared_size += l1+l2+4;
diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c
index 31d81a1e7ef..6d55c1d9da2 100644
--- a/source/smbwrapper/smbw_dir.c
+++ b/source/smbwrapper/smbw_dir.c
@@ -216,7 +216,7 @@ int smbw_dir_open(const char *fname)
smbw_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
smbw_server_add, NULL);
*p = '#';
- } else if (strcmp(srv->cli.dev,"IPC") == 0) {
+ } else if ((strcmp(srv->cli.dev,"IPC") == 0) || (strcasecmp(share,"IPC$") == 0)) {
DEBUG(4,("doing NetShareEnum\n"));
smbw_share_add(".",0,"", NULL);
smbw_share_add("..",0,"", NULL);
@@ -412,7 +412,8 @@ int smbw_chdir(const char *name)
goto failed;
}
- if (strncmp(srv->cli.dev,"IPC",3) &&
+ if (strncmp(srv->cli.dev,"IPC",3) &&
+ strcasecmp(share, "IPC$") &&
strncmp(srv->cli.dev,"LPT",3) &&
!smbw_getatr(srv, path,
&mode, NULL, NULL, NULL, NULL, NULL)) {
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
index b90c53e9fe3..f74fcedcf49 100644
--- a/source/torture/cmd_vfs.c
+++ b/source/torture/cmd_vfs.c
@@ -23,37 +23,28 @@
#include "includes.h"
#include "vfstest.h"
-static char *null_string = "";
+static const char *null_string = "";
-static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- struct smb_vfs_handle_struct *handle;
- char *path = lp_vfs_path(0);
- char name[PATH_MAX];
+ int i;
- if (argc != 2) {
- printf("Usage: load <module path>\n");
+ if (argc < 2) {
+ printf("Usage: load <modules>\n");
return NT_STATUS_OK;
}
- if (path != NULL && *path != '\0') {
- snprintf(name, PATH_MAX, "%s/%s", path, argv[1]);
- } else {
- snprintf(name, PATH_MAX, "%s", argv[1]);
- }
- vfs->conn->vfs_private = NULL;
- handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct));
- handle->handle = NULL;
- DLIST_ADD(vfs->conn->vfs_private, handle)
- if (!vfs_init_custom(vfs->conn, name)) {
- DEBUG(0, ("load: error=-1 (vfs_init_custom failed for %s)\n", argv[1]));
- return NT_STATUS_UNSUCCESSFUL;
+ for (i=argc-1;i>0;i--) {
+ if (!vfs_init_custom(vfs->conn, argv[i])) {
+ DEBUG(0, ("load: (vfs_init_custom failed for %s)\n", argv[i]));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
}
printf("load: ok\n");
return NT_STATUS_OK;
}
-static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
char c;
size_t size;
@@ -73,7 +64,7 @@ static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
return NT_STATUS_OK;
}
-static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
size_t offset;
size_t len;
@@ -101,19 +92,19 @@ static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
return NT_STATUS_OK;
}
-static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- vfs->conn->vfs_ops.connect(vfs->conn, lp_servicename(vfs->conn->service), "vfstest");
+ SMB_VFS_CONNECT(vfs->conn, lp_servicename(vfs->conn->service), "vfstest");
return NT_STATUS_OK;
}
-static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- vfs->conn->vfs_ops.disconnect(vfs->conn);
+ SMB_VFS_DISCONNECT(vfs->conn);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
SMB_BIG_UINT diskfree, bsize, dfree, dsize;
if (argc != 2) {
@@ -121,7 +112,7 @@ static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
return NT_STATUS_OK;
}
- diskfree = vfs->conn->vfs_ops.disk_free(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
+ diskfree = SMB_VFS_DISK_FREE(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n",
(unsigned long)diskfree,
(unsigned long)bsize,
@@ -131,14 +122,14 @@ static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
}
-static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc != 2) {
printf("Usage: opendir <fname>\n");
return NT_STATUS_OK;
}
- vfs->currentdir = vfs->conn->vfs_ops.opendir(vfs->conn, argv[1]);
+ vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1]);
if (vfs->currentdir == NULL) {
printf("opendir error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -149,7 +140,7 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
}
-static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
struct dirent *dent;
@@ -158,7 +149,7 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
return NT_STATUS_UNSUCCESSFUL;
}
- dent = vfs->conn->vfs_ops.readdir(vfs->conn, vfs->currentdir);
+ dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir);
if (dent == NULL) {
printf("readdir: NULL\n");
return NT_STATUS_OK;
@@ -169,14 +160,14 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
}
-static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc != 2) {
printf("Usage: mkdir <path>\n");
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.mkdir(vfs->conn, argv[1], 00755) == -1) {
+ if (SMB_VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) {
printf("mkdir error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -186,7 +177,7 @@ static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int ret;
@@ -195,7 +186,7 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
return NT_STATUS_UNSUCCESSFUL;
}
- ret = vfs->conn->vfs_ops.closedir(vfs->conn, vfs->currentdir);
+ ret = SMB_VFS_CLOSEDIR(vfs->conn, vfs->currentdir);
if (ret == -1) {
printf("closedir failure: %s\n", strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -207,11 +198,11 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
}
-static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int flags, fd;
mode_t mode;
- char *flagstr;
+ const char *flagstr;
mode = 00400;
@@ -287,7 +278,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
}
- fd = vfs->conn->vfs_ops.open(vfs->conn, argv[1], flags, mode);
+ fd = SMB_VFS_OPEN(vfs->conn, argv[1], flags, mode);
if (fd == -1) {
printf("open: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -302,7 +293,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
-static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int ret = -1;
@@ -312,11 +303,11 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
}
if (strcmp("rmdir", argv[0]) == 0 ) {
- ret = vfs->conn->vfs_ops.rmdir(vfs->conn, argv[1]);
+ ret = SMB_VFS_RMDIR(vfs->conn, argv[1]);
} else if (strcmp("unlink", argv[0]) == 0 ) {
- ret = vfs->conn->vfs_ops.unlink(vfs->conn, argv[1]);
+ ret = SMB_VFS_UNLINK(vfs->conn, argv[1]);
} else if (strcmp("chdir", argv[0]) == 0 ) {
- ret = vfs->conn->vfs_ops.chdir(vfs->conn, argv[1]);
+ ret = SMB_VFS_CHDIR(vfs->conn, argv[1]);
} else {
printf("%s: error=%d (invalid function name!)\n", argv[0], errno);
return NT_STATUS_UNSUCCESSFUL;
@@ -332,7 +323,7 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
}
-static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd, ret;
@@ -347,7 +338,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
- ret = vfs->conn->vfs_ops.close(vfs->files[fd], fd);
+ ret = SMB_VFS_CLOSE(vfs->files[fd], fd);
if (ret == -1 )
printf("close: error=%d (%s)\n", errno, strerror(errno));
else
@@ -360,7 +351,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd;
size_t size, rsize;
@@ -380,7 +371,7 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
vfs->data_size = size;
- rsize = vfs->conn->vfs_ops.read(vfs->files[fd], fd, vfs->data, size);
+ rsize = SMB_VFS_READ(vfs->files[fd], fd, vfs->data, size);
if (rsize == -1) {
printf("read: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -391,7 +382,7 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
-static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd, size, wsize;
@@ -413,7 +404,7 @@ static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- wsize = vfs->conn->vfs_ops.write(vfs->files[fd], fd, vfs->data, size);
+ wsize = SMB_VFS_WRITE(vfs->files[fd], fd, vfs->data, size);
if (wsize == -1) {
printf("write: error=%d (%s)\n", errno, strerror(errno));
@@ -425,7 +416,7 @@ static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd, offset, whence;
SMB_OFF_T pos;
@@ -444,7 +435,7 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
default: whence = SEEK_END;
}
- pos = vfs->conn->vfs_ops.lseek(vfs->files[fd], fd, offset, whence);
+ pos = SMB_VFS_LSEEK(vfs->files[fd], fd, offset, whence);
if (pos == (SMB_OFF_T)-1) {
printf("lseek: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -455,7 +446,7 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int ret;
if (argc != 3) {
@@ -463,7 +454,7 @@ static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
- ret = vfs->conn->vfs_ops.rename(vfs->conn, argv[1], argv[2]);
+ ret = SMB_VFS_RENAME(vfs->conn, argv[1], argv[2]);
if (ret == -1) {
printf("rename: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -474,7 +465,7 @@ static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int ret, fd;
if (argc != 2) {
@@ -483,7 +474,7 @@ static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
fd = atoi(argv[1]);
- ret = vfs->conn->vfs_ops.fsync(vfs->files[fd], fd);
+ ret = SMB_VFS_FSYNC(vfs->files[fd], fd);
if (ret == -1) {
printf("fsync: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
@@ -494,11 +485,11 @@ static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int ret;
- char *user;
- char *group;
+ const char *user;
+ const char *group;
struct passwd *pwd;
struct group *grp;
SMB_STRUCT_STAT st;
@@ -508,17 +499,17 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
return NT_STATUS_OK;
}
- ret = vfs->conn->vfs_ops.stat(vfs->conn, argv[1], &st);
+ ret = SMB_VFS_STAT(vfs->conn, argv[1], &st);
if (ret == -1) {
printf("stat: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = strdup(pwd->pw_name);
+ if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = strdup(grp->gr_name);
+ if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("stat: ok\n");
@@ -541,17 +532,17 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
- if (user != null_string) SAFE_FREE(user);
- if (group!= null_string) SAFE_FREE(group);
+ SAFE_FREE(pwd);
+ SAFE_FREE(grp);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd;
- char *user;
- char *group;
+ const char *user;
+ const char *group;
struct passwd *pwd;
struct group *grp;
SMB_STRUCT_STAT st;
@@ -572,16 +563,16 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.fstat(vfs->files[fd], fd, &st) == -1) {
+ if (SMB_VFS_FSTAT(vfs->files[fd], fd, &st) == -1) {
printf("fstat: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = strdup(pwd->pw_name);
+ if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = strdup(grp->gr_name);
+ if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("fstat: ok\n");
@@ -603,16 +594,16 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
- if (user != null_string) SAFE_FREE(user);
- if (group!= null_string) SAFE_FREE(group);
+ SAFE_FREE(pwd);
+ SAFE_FREE(grp);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- char *user;
- char *group;
+ const char *user;
+ const char *group;
struct passwd *pwd;
struct group *grp;
SMB_STRUCT_STAT st;
@@ -622,16 +613,16 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.lstat(vfs->conn, argv[1], &st) == -1) {
+ if (SMB_VFS_LSTAT(vfs->conn, argv[1], &st) == -1) {
printf("lstat: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = strdup(pwd->pw_name);
+ if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = strdup(grp->gr_name);
+ if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("lstat: ok\n");
@@ -653,13 +644,13 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
- if (user != null_string) SAFE_FREE(user);
- if (group!= null_string) SAFE_FREE(group);
+ SAFE_FREE(pwd);
+ SAFE_FREE(grp);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
mode_t mode;
if (argc != 3) {
@@ -668,7 +659,7 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
mode = atoi(argv[2]);
- if (vfs->conn->vfs_ops.chmod(vfs->conn, argv[1], mode) == -1) {
+ if (SMB_VFS_CHMOD(vfs->conn, argv[1], mode) == -1) {
printf("chmod: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -678,7 +669,7 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd;
mode_t mode;
@@ -698,7 +689,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.fchmod(vfs->files[fd], fd, mode) == -1) {
+ if (SMB_VFS_FCHMOD(vfs->files[fd], fd, mode) == -1) {
printf("fchmod: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -708,7 +699,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
uid_t uid;
gid_t gid;
@@ -719,7 +710,7 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
uid = atoi(argv[2]);
gid = atoi(argv[3]);
- if (vfs->conn->vfs_ops.chown(vfs->conn, argv[1], uid, gid) == -1) {
+ if (SMB_VFS_CHOWN(vfs->conn, argv[1], uid, gid) == -1) {
printf("chown: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -729,7 +720,7 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
uid_t uid;
gid_t gid;
@@ -750,7 +741,7 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
printf("fchown: error=%d (invalid file descriptor)\n", EBADF);
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.fchown(vfs->files[fd], fd, uid, gid) == -1) {
+ if (SMB_VFS_FCHOWN(vfs->files[fd], fd, uid, gid) == -1) {
printf("fchown error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -760,10 +751,10 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
-static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
char buf[PATH_MAX];
- if (vfs->conn->vfs_ops.getwd(vfs->conn, buf) == NULL) {
+ if (SMB_VFS_GETWD(vfs->conn, buf) == NULL) {
printf("getwd: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -772,7 +763,7 @@ static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
-static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
struct utimbuf times;
if (argc != 4) {
@@ -781,7 +772,7 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
times.actime = atoi(argv[2]);
times.modtime = atoi(argv[3]);
- if (vfs->conn->vfs_ops.utime(vfs->conn, argv[1], &times) != 0) {
+ if (SMB_VFS_UTIME(vfs->conn, argv[1], &times) != 0) {
printf("utime: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -790,7 +781,7 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
-static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
int fd;
SMB_OFF_T off;
@@ -810,7 +801,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.ftruncate(vfs->files[fd], fd, off) == -1) {
+ if (SMB_VFS_FTRUNCATE(vfs->files[fd], fd, off) == -1) {
printf("ftruncate: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -819,7 +810,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
return NT_STATUS_OK;
}
-static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
BOOL ret;
int fd;
@@ -827,7 +818,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
long offset;
long count;
int type;
- char *typestr;
+ const char *typestr;
if (argc != 6) {
printf("Usage: lock <fd> <op> <offset> <count> <type>\n");
@@ -893,7 +884,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type);
- if ((ret = vfs->conn->vfs_ops.lock(vfs->files[fd], fd, op, offset, count, type)) == False) {
+ if ((ret = SMB_VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) {
printf("lock: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -902,14 +893,14 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
return NT_STATUS_OK;
}
-static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc != 3) {
printf("Usage: symlink <path> <link>\n");
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.symlink(vfs->conn, argv[1], argv[2]) == -1) {
+ if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
printf("symlink: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -919,7 +910,7 @@ static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
}
-static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
char buffer[PATH_MAX];
int size;
@@ -929,7 +920,7 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
return NT_STATUS_OK;
}
- if ((size = vfs->conn->vfs_ops.readlink(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
+ if ((size = SMB_VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
printf("readlink: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -940,14 +931,14 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
}
-static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc != 3) {
printf("Usage: link <path> <link>\n");
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.link(vfs->conn, argv[1], argv[2]) == -1) {
+ if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) {
printf("link: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -956,7 +947,7 @@ static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
return NT_STATUS_OK;
}
-static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
mode_t mode;
unsigned int dev_val;
@@ -980,7 +971,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
}
dev = (SMB_DEV_T)dev_val;
- if (vfs->conn->vfs_ops.mknod(vfs->conn, argv[1], mode, dev) == -1) {
+ if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) {
printf("mknod: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -989,7 +980,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
-static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
char respath[PATH_MAX];
@@ -998,7 +989,7 @@ static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
return NT_STATUS_OK;
}
- if (vfs->conn->vfs_ops.realpath(vfs->conn, argv[1], respath) == NULL) {
+ if (SMB_VFS_REALPATH(vfs->conn, argv[1], respath) == NULL) {
printf("realpath: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c
index 3b28a3c496b..88fe3486493 100644
--- a/source/torture/vfstest.c
+++ b/source/torture/vfstest.c
@@ -106,7 +106,7 @@ static char* next_command(char** cmdstr)
/* Load specified configuration file */
static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
- int argc, char **argv)
+ int argc, const char **argv)
{
if (argc != 2) {
printf("Usage: %s <smb.conf>\n", argv[0]);
@@ -181,7 +181,7 @@ static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
}
/* Change the debug level */
-static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc > 2) {
printf("Usage: %s [debuglevel]\n", argv[0]);
@@ -197,7 +197,7 @@ static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a
return NT_STATUS_OK;
}
-static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
/* Cleanup */
talloc_destroy(mem_ctx);
@@ -207,7 +207,7 @@ static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
return NT_STATUS_OK;
}
-static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
/* Cleanup */
talloc_destroy(mem_ctx);
@@ -261,7 +261,8 @@ static void add_command_set(struct cmd_set *cmd_set)
static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
{
- char *p = cmd, **argv = NULL;
+ const char *p = cmd;
+ char **argv = NULL;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
pstring buf;
TALLOC_CTX *mem_ctx = NULL;
@@ -311,7 +312,7 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
}
/* Run command */
- result = cmd_entry->fn(vfs, mem_ctx, argc, argv);
+ result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv);
} else {
fprintf (stderr, "Invalid command\n");
@@ -338,7 +339,7 @@ static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd)
struct cmd_list *temp_list;
BOOL found = False;
pstring buf;
- char *p = cmd;
+ const char *p = cmd;
NTSTATUS result = NT_STATUS_OK;
int len = 0;
@@ -478,7 +479,7 @@ int main(int argc, char *argv[])
struct cmd_set **cmd_set;
static struct vfs_state vfs;
int i;
- static const char *filename = NULL;
+ static char *filename = NULL;
/* make sure the vars that get altered (4th field) are in
a fixed location or certain compilers complain */
@@ -520,9 +521,10 @@ int main(int argc, char *argv[])
}
/* some basic initialization stuff */
+ sec_init();
conn_init();
vfs.conn = conn_new();
- vfs.conn->user = "vfstest";
+ string_set(&vfs.conn->user,"vfstest");
for (i=0; i < 1024; i++)
vfs.files[i] = NULL;
diff --git a/source/torture/vfstest.h b/source/torture/vfstest.h
index 5910c5ce37b..1e030fad047 100644
--- a/source/torture/vfstest.h
+++ b/source/torture/vfstest.h
@@ -39,7 +39,7 @@ struct vfs_state {
struct cmd_set {
const char *name;
NTSTATUS (*fn)(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
- char **argv);
+ const char **argv);
const char *description;
const char *usage;
};
diff --git a/source/utils/editreg.c b/source/utils/editreg.c
index 54148fdcf8e..92a39c39e2a 100644
--- a/source/utils/editreg.c
+++ b/source/utils/editreg.c
@@ -412,16 +412,16 @@ typedef struct val_list_s {
#define MAXSUBAUTHS 15
#endif
-typedef struct sid_s {
+typedef struct dom_sid_s {
unsigned char ver, auths;
unsigned char auth[6];
unsigned int sub_auths[MAXSUBAUTHS];
-} sid_t;
+} DOM_SID;
typedef struct ace_struct_s {
unsigned char type, flags;
unsigned int perms; /* Perhaps a better def is in order */
- sid_t *trustee;
+ DOM_SID *trustee;
} ACE;
typedef struct acl_struct_s {
@@ -432,7 +432,7 @@ typedef struct acl_struct_s {
typedef struct sec_desc_s {
unsigned int rev, type;
- sid_t *owner, *group;
+ DOM_SID *owner, *group;
ACL *sacl, *dacl;
} SEC_DESC;
@@ -537,7 +537,7 @@ typedef struct ace_struct {
unsigned char flags;
unsigned short length;
unsigned int perms;
- sid_t trustee;
+ DOM_SID trustee;
} REG_ACE;
typedef struct acl_struct {
@@ -904,7 +904,7 @@ int nt_delete_key_by_name(REGF *regf, char *name)
}
static
-int nt_delete_sid(sid_t *sid)
+int nt_delete_sid(DOM_SID *sid)
{
if (sid) free(sid);
@@ -1173,15 +1173,15 @@ VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name)
* Convert a string of the form S-1-5-x[-y-z-r] to a SID
*/
static
-int sid_string_to_sid(sid_t **sid, const char *sid_str)
+int string_to_sid(DOM_SID **sid, const char *sid_str)
{
int i = 0, auth;
const char *lstr;
- *sid = (sid_t *)malloc(sizeof(sid_t));
+ *sid = (DOM_SID *)malloc(sizeof(DOM_SID));
if (!*sid) return 0;
- bzero(*sid, sizeof(sid_t));
+ bzero(*sid, sizeof(DOM_SID));
if (strncmp(sid_str, "S-1-5", 5)) {
fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str);
@@ -1226,7 +1226,7 @@ ACE *nt_create_ace(int type, int flags, unsigned int perms, const char *sid)
ace->type = type;
ace->flags = flags;
ace->perms = perms;
- if (!sid_string_to_sid(&ace->trustee, sid))
+ if (!string_to_sid(&ace->trustee, sid))
goto error;
return ace;
@@ -1287,8 +1287,8 @@ SEC_DESC *nt_create_def_sec_desc(REGF *regf)
tmp->rev = 1;
tmp->type = 0x8004;
- if (!sid_string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error;
- if (!sid_string_to_sid(&tmp->group, "S-1-5-18")) goto error;
+ if (!string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error;
+ if (!string_to_sid(&tmp->group, "S-1-5-18")) goto error;
tmp->sacl = NULL;
tmp->dacl = nt_create_default_acl(regf);
@@ -1829,9 +1829,9 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
* We could allocate the SID to be only the size needed, but I am too lazy.
*/
static
-sid_t *dup_sid(sid_t *sid)
+DOM_SID *dup_sid(DOM_SID *sid)
{
- sid_t *tmp = (sid_t *)malloc(sizeof(sid_t));
+ DOM_SID *tmp = (DOM_SID *)malloc(sizeof(DOM_SID));
int i;
if (!tmp) return NULL;
@@ -1916,12 +1916,12 @@ SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc)
IVAL(&sec_desc->group_off));
if (verbose) fprintf(stdout, "SEC_DESC DACL Off: %0X\n",
IVAL(&sec_desc->dacl_off));
- tmp->owner = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->owner_off)));
+ tmp->owner = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->owner_off)));
if (!tmp->owner) {
free(tmp);
return NULL;
}
- tmp->group = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->group_off)));
+ tmp->group = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->group_off)));
if (!tmp->group) {
free(tmp);
return NULL;
@@ -2618,7 +2618,7 @@ void *nt_alloc_regf_space(REGF *regf, int size, unsigned int *off)
* Compute the size of a SID stored ...
*/
static
-unsigned int sid_size(sid_t *sid)
+unsigned int sid_size(DOM_SID *sid)
{
unsigned int size;
@@ -2686,7 +2686,7 @@ unsigned int sec_desc_size(SEC_DESC *sd)
* Store a SID at the location provided
*/
static
-int nt_store_SID(REGF *regf, sid_t *sid, unsigned char *locn)
+int nt_store_SID(REGF *regf, DOM_SID *sid, unsigned char *locn)
{
int i;
unsigned char *p = locn;
@@ -3864,7 +3864,7 @@ void print_perms(int perms)
}
static
-void print_sid(sid_t *sid)
+void print_sid(DOM_SID *sid)
{
int i, comps = sid->auths;
fprintf(stdout, "S-%u-%u", sid->ver, sid->auth[5]);
@@ -3955,7 +3955,7 @@ int main(int argc, char *argv[])
char *cmd_file_name = NULL;
char *out_file_name = NULL;
CMD_FILE *cmd_file = NULL;
- sid_t *lsid;
+ DOM_SID *lsid;
if (argc < 2) {
usage();
@@ -3987,7 +3987,7 @@ int main(int argc, char *argv[])
case 'O':
def_owner_sid_str = strdup(optarg);
regf_opt += 2;
- if (!sid_string_to_sid(&lsid, def_owner_sid_str)) {
+ if (!string_to_sid(&lsid, def_owner_sid_str)) {
fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n",
def_owner_sid_str);
free(&def_owner_sid_str[0]);
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 203d849786b..5051f181881 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -109,6 +109,9 @@ static int net_ads_info(int argc, const char **argv)
d_printf("LDAP port: %d\n", ads->ldap_port);
d_printf("Server time: %s\n", http_timestring(ads->config.current_time));
+ d_printf("KDC server: %s\n", ads->auth.kdc_server );
+ d_printf("Server time offset: %d\n", ads->auth.time_offset );
+
return 0;
}
@@ -124,7 +127,7 @@ static ADS_STRUCT *ads_startup(void)
ADS_STATUS status;
BOOL need_password = False;
BOOL second_time = False;
- char *realm;
+ char *cp;
ads = ads_init(NULL, NULL, opt_host);
@@ -146,22 +149,24 @@ retry:
if (opt_password) {
use_in_memory_ccache();
- ads->auth.password = strdup(opt_password);
+ ads->auth.password = smb_xstrdup(opt_password);
}
- ads->auth.user_name = strdup(opt_user_name);
+ ads->auth.user_name = smb_xstrdup(opt_user_name);
- /*
- * If the username is of the form "name@realm",
- * extract the realm and convert to upper case.
- */
- if ((realm = strchr(ads->auth.user_name, '@'))) {
- *realm++ = '\0';
- ads->auth.realm = strdup(realm);
- strupper(ads->auth.realm);
- }
+ /*
+ * If the username is of the form "name@realm",
+ * extract the realm and convert to upper case.
+ * This is only used to establish the connection.
+ */
+ if ((cp = strchr(ads->auth.user_name, '@'))!=0) {
+ *cp++ = '\0';
+ ads->auth.realm = smb_xstrdup(cp);
+ strupper(ads->auth.realm);
+ }
status = ads_connect(ads);
+
if (!ADS_ERR_OK(status)) {
if (!need_password && !second_time) {
need_password = True;
@@ -230,7 +235,7 @@ static BOOL usergrp_display(char *field, void **values, void *data_area)
if (!field) { /* must be end of record */
if (!strchr_m(disp_fields[0], '$')) {
if (disp_fields[1])
- d_printf("%-21.21s %-50.50s\n",
+ d_printf("%-21.21s %s\n",
disp_fields[0], disp_fields[1]);
else
d_printf("%s\n", disp_fields[0]);
@@ -295,7 +300,8 @@ static int ads_user_add(int argc, const char **argv)
/* try setting the password */
asprintf(&upn, "%s@%s", argv[0], ads->config.realm);
- status = krb5_set_password(ads->auth.kdc_server, upn, argv[1], ads->auth.time_offset);
+ status = ads_krb5_set_password(ads->auth.kdc_server, upn, argv[1],
+ ads->auth.time_offset);
safe_free(upn);
if (ADS_ERR_OK(status)) {
d_printf("User %s added\n", argv[0]);
diff --git a/source/utils/net_ads_cldap.c b/source/utils/net_ads_cldap.c
index 86d5abea4be..e74e4b5a4cf 100644
--- a/source/utils/net_ads_cldap.c
+++ b/source/utils/net_ads_cldap.c
@@ -24,28 +24,28 @@
#ifdef HAVE_ADS
-struct netlogon_string {
- uint32 comp_len;
- char **component;
- uint8 extra_flag;
-};
+#define MAX_DNS_LABEL 255 + 1
struct cldap_netlogon_reply {
uint32 type;
uint32 flags;
GUID guid;
- struct netlogon_string forest;
- struct netlogon_string domain;
- struct netlogon_string hostname;
-
- struct netlogon_string netbios_domain;
- struct netlogon_string netbios_hostname;
+ char forest[MAX_DNS_LABEL];
+ char unk0[MAX_DNS_LABEL];
+ char domain[MAX_DNS_LABEL];
+ char hostname[MAX_DNS_LABEL];
- struct netlogon_string user_name;
- struct netlogon_string site_name;
+ char netbios_domain[MAX_DNS_LABEL];
+ char unk1[MAX_DNS_LABEL];
+ char netbios_hostname[MAX_DNS_LABEL];
- struct netlogon_string unk0;
+ char unk2[MAX_DNS_LABEL];
+ char user_name[MAX_DNS_LABEL];
+ char unk3[MAX_DNS_LABEL];
+ char site_name[MAX_DNS_LABEL];
+ char unk4[MAX_DNS_LABEL];
+ char site_name_2[MAX_DNS_LABEL];
uint32 version;
uint16 lmnt_token;
@@ -53,38 +53,69 @@ struct cldap_netlogon_reply {
};
/*
- These strings are rather interesting... They are composed of a series of
- length encoded strings, terminated by either 1) a zero length string or 2)
- a 0xc0 byte with what appears to be a one byte flags immediately following.
+ These seem to be strings as described in RFC1035 4.1.4 and can be:
+
+ - a sequence of labels ending in a zero octet
+ - a pointer
+ - a sequence of labels ending with a pointer
+
+ A label is a byte where the first two bits must be zero and the remaining
+ bits represent the length of the label followed by the label itself.
+ Therefore, the length of a label is at max 64 bytes. Under RFC1035, a
+ sequence of labels cannot exceed 255 bytes.
+
+ A pointer consists of a 14 bit offset from the beginning of the data.
+
+ struct ptr {
+ unsigned ident:2; // must be 11
+ unsigned offset:14; // from the beginning of data
+ };
+
+ This is used as a method to compress the packet by eliminated duplicate
+ domain components. Since a UDP packet should probably be < 512 bytes and a
+ DNS name can be up to 255 bytes, this actually makes a lot of sense.
*/
-static unsigned pull_netlogon_string(struct netlogon_string *ret,const char *d)
+static unsigned pull_netlogon_string(char *ret, const char *ptr,
+ const char *data)
{
- const char *p = (const char *)d;
-
- ZERO_STRUCTP(ret);
+ char *pret = ret;
+ int followed_ptr = 0;
+ unsigned ret_len = 0;
+ memset(pret, 0, MAX_DNS_LABEL);
do {
- unsigned len = (unsigned char)*p;
- p++;
-
- if (len > 0 && len != 0xc0) {
- ret->component = realloc(ret->component,
- ++ret->comp_len *
- sizeof(char *));
-
- ret->component[ret->comp_len - 1] =
- smb_xstrndup(p, len);
- p += len;
- } else {
- if (len == 0xc0) {
- ret->extra_flag = *p;
- p++;
- };
- break;
+ if ((*ptr & 0xc0) == 0xc0) {
+ uint16 len;
+
+ if (!followed_ptr) {
+ ret_len += 2;
+ followed_ptr = 1;
+ }
+ len = ((ptr[0] & 0x3f) << 8) | ptr[1];
+ ptr = data + len;
+ } else if (*ptr) {
+ uint8 len = (uint8)*(ptr++);
+
+ if ((pret - ret + len + 1) >= MAX_DNS_LABEL) {
+ d_printf("DC returning too long DNS name\n");
+ return 0;
+ }
+
+ if (pret != ret) {
+ *pret = '.';
+ pret++;
+ }
+ memcpy(pret, ptr, len);
+ pret += len;
+ ptr += len;
+
+ if (!followed_ptr) {
+ ret_len += (len + 1);
+ }
}
- } while (1);
+ } while (*ptr);
- return (p - d);
+ return ret_len ? ret_len : 1;
}
/*
@@ -95,7 +126,11 @@ static int send_cldap_netlogon(int sock, const char *domain,
{
ASN1_DATA data;
char ntver[4];
+#ifdef CLDAP_USER_QUERY
+ char aac[4];
+ SIVAL(aac, 0, 0x00000180);
+#endif
SIVAL(ntver, 0, ntversion);
memset(&data, 0, sizeof(data));
@@ -121,6 +156,18 @@ static int send_cldap_netlogon(int sock, const char *domain,
asn1_write_OctetString(&data, hostname, strlen(hostname));
asn1_pop_tag(&data);
+#ifdef CLDAP_USER_QUERY
+ asn1_push_tag(&data, ASN1_CONTEXT(3));
+ asn1_write_OctetString(&data, "User", 4);
+ asn1_write_OctetString(&data, "SAMBA$", 6);
+ asn1_pop_tag(&data);
+
+ asn1_push_tag(&data, ASN1_CONTEXT(3));
+ asn1_write_OctetString(&data, "AAC", 4);
+ asn1_write_OctetString(&data, aac, 4);
+ asn1_pop_tag(&data);
+#endif
+
asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_write_OctetString(&data, "NtVer", 5);
asn1_write_OctetString(&data, ntver, 4);
@@ -144,7 +191,6 @@ static int send_cldap_netlogon(int sock, const char *domain,
d_printf("failed to send cldap query (%s)\n", strerror(errno));
}
- file_save("cldap_query.dat", data.data, data.length);
asn1_free(&data);
return 0;
@@ -173,8 +219,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
}
blob.length = ret;
- file_save("cldap_reply.dat", blob.data, blob.length);
-
asn1_load(&data, blob);
asn1_start_tag(&data, ASN1_SEQUENCE(0));
asn1_read_Integer(&data, &i1);
@@ -196,8 +240,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
return -1;
}
- file_save("cldap_reply_core.dat", os3.data, os3.length);
-
p = os3.data;
reply->type = IVAL(p, 0); p += 4;
@@ -206,15 +248,25 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
memcpy(&reply->guid.info, p, GUID_SIZE);
p += GUID_SIZE;
- p += pull_netlogon_string(&reply->forest, p);
- p += pull_netlogon_string(&reply->domain, p);
- p += pull_netlogon_string(&reply->hostname, p);
- p += pull_netlogon_string(&reply->netbios_domain, p);
- p += pull_netlogon_string(&reply->netbios_hostname, p);
- p += pull_netlogon_string(&reply->user_name, p);
- p += pull_netlogon_string(&reply->site_name, p);
+ p += pull_netlogon_string(reply->forest, p, os3.data);
+ p += pull_netlogon_string(reply->unk0, p, os3.data);
+ p += pull_netlogon_string(reply->domain, p, os3.data);
+ p += pull_netlogon_string(reply->hostname, p, os3.data);
+ p += pull_netlogon_string(reply->netbios_domain, p, os3.data);
+ p += pull_netlogon_string(reply->unk1, p, os3.data);
+ p += pull_netlogon_string(reply->netbios_hostname, p, os3.data);
+ p += pull_netlogon_string(reply->unk2, p, os3.data);
+
+ if (reply->type == SAMLOGON_AD_R) {
+ p += pull_netlogon_string(reply->user_name, p, os3.data);
+ } else {
+ *reply->user_name = 0;
+ }
- p += pull_netlogon_string(&reply->unk0, p);
+ p += pull_netlogon_string(reply->unk3, p, os3.data);
+ p += pull_netlogon_string(reply->site_name, p, os3.data);
+ p += pull_netlogon_string(reply->unk4, p, os3.data);
+ p += pull_netlogon_string(reply->site_name_2, p, os3.data);
reply->version = IVAL(p, 0);
reply->lmnt_token = SVAL(p, 4);
@@ -229,52 +281,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
}
/*
- free a netlogon string
-*/
-static void netlogon_string_free(struct netlogon_string *str)
-{
- unsigned int i;
-
- for (i = 0; i < str->comp_len; ++i) {
- SAFE_FREE(str->component[i]);
- }
- SAFE_FREE(str->component);
-}
-
-/*
- free a cldap reply packet
-*/
-static void cldap_reply_free(struct cldap_netlogon_reply *reply)
-{
- netlogon_string_free(&reply->forest);
- netlogon_string_free(&reply->domain);
- netlogon_string_free(&reply->hostname);
- netlogon_string_free(&reply->netbios_domain);
- netlogon_string_free(&reply->netbios_hostname);
- netlogon_string_free(&reply->user_name);
- netlogon_string_free(&reply->site_name);
- netlogon_string_free(&reply->unk0);
-}
-
-static void d_print_netlogon_string(const char *label,
- struct netlogon_string *str)
-{
- unsigned int i;
-
- if (str->comp_len) {
- d_printf("%s", label);
- if (str->extra_flag) {
- d_printf("[%d]", str->extra_flag);
- }
- d_printf(": ");
- for (i = 0; i < str->comp_len; ++i) {
- d_printf("%s%s", (i ? "." : ""), str->component[i]);
- }
- d_printf("\n");
- }
-}
-
-/*
do a cldap netlogon query
*/
int ads_cldap_netlogon(ADS_STRUCT *ads)
@@ -289,6 +295,7 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
inet_ntoa(ads->ldap_ip),
ads->ldap_port);
return -1;
+
}
ret = send_cldap_netlogon(sock, ads->config.realm, global_myname(), 6);
@@ -305,7 +312,18 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
d_printf("Information for Domain Controller: %s\n\n",
ads->config.ldap_server_name);
- d_printf("Response Type: 0x%x\n", reply.type);
+ d_printf("Response Type: ");
+ switch (reply.type) {
+ case SAMLOGON_AD_UNK_R:
+ d_printf("SAMLOGON\n");
+ break;
+ case SAMLOGON_AD_R:
+ d_printf("SAMLOGON_USER\n");
+ break;
+ default:
+ d_printf("0x%x\n", reply.type);
+ break;
+ }
d_printf("GUID: ");
print_guid(&reply.guid);
d_printf("Flags:\n"
@@ -330,23 +348,27 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
(reply.flags & ADS_GOOD_TIMESERV) ? "yes" : "no",
(reply.flags & ADS_NDNC) ? "yes" : "no");
- d_print_netlogon_string("Forest", &reply.forest);
- d_print_netlogon_string("Domain", &reply.domain);
- d_print_netlogon_string("Hostname", &reply.hostname);
+ printf("Forest:\t\t\t%s\n", reply.forest);
+ if (*reply.unk0) printf("Unk0:\t\t\t%s\n", reply.unk0);
+ printf("Domain:\t\t\t%s\n", reply.domain);
+ printf("Domain Controller:\t%s\n", reply.hostname);
- d_print_netlogon_string("Pre-Win2k Domain", &reply.netbios_domain);
- d_print_netlogon_string("Pre-Win2k Hostname", &reply.netbios_hostname);
+ printf("Pre-Win2k Domain:\t%s\n", reply.netbios_domain);
+ if (*reply.unk1) printf("Unk1:\t\t\t%s\n", reply.unk1);
+ printf("Pre-Win2k Hostname:\t%s\n", reply.netbios_hostname);
- d_print_netlogon_string("User name", &reply.user_name);
- d_print_netlogon_string("Site Name", &reply.site_name);
- d_print_netlogon_string("Unknown Field", &reply.unk0);
+ if (*reply.unk2) printf("Unk2:\t\t\t%s\n", reply.unk2);
+ if (*reply.user_name) printf("User name:\t%s\n", reply.user_name);
+
+ if (*reply.unk3) printf("Unk3:\t\t\t%s\n", reply.unk3);
+ printf("Site Name:\t\t%s\n", reply.site_name);
+ if (*reply.unk4) printf("Unk4:\t\t\t%s\n", reply.unk4);
+ printf("Site Name (2):\t\t%s\n", reply.site_name_2);
d_printf("NT Version: %d\n", reply.version);
d_printf("LMNT Token: %.2x\n", reply.lmnt_token);
d_printf("LM20 Token: %.2x\n", reply.lm20_token);
- cldap_reply_free(&reply);
-
return ret;
}
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 3f5a3399489..544525b705a 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -74,7 +74,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
goto error;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = cli_lsa_open_policy(cli, mem_ctx, False,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -235,14 +235,25 @@ int net_rpc_changetrustpw(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_state *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv) {
fstring trust_passwd;
unsigned char orig_trust_passwd_hash[16];
NTSTATUS result;
+ uint32 sec_channel_type;
+ /*
+ check what type of join - if the user want's to join as
+ a BDC, the server must agree that we are a BDC.
+ */
+ if (argc >= 0) {
+ sec_channel_type = get_sec_channel_type(argv[0]);
+ } else {
+ sec_channel_type = get_sec_channel_type(NULL);
+ }
+
fstrcpy(trust_passwd, global_myname());
strlower(trust_passwd);
@@ -257,11 +268,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
orig_trust_passwd_hash,
- SEC_CHAN_WKSTA);
-
- /* SEC_CHAN_WKSTA specified specifically, as you cannot use this
- to join a BDC to the domain (MS won't allow it, and is *really*
- insecure) */
+ sec_channel_type);
if (NT_STATUS_IS_OK(result))
printf("Joined domain %s.\n",opt_target_workgroup);
@@ -285,40 +292,11 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
* @return A shell status integer (0 for success)
**/
-static int net_rpc_join_oldstyle(int argc, const char **argv)
-{
- uint32 sec_channel_type;
- /* check what type of join */
- if (argc >= 0) {
- sec_channel_type = get_sec_channel_type(argv[0]);
- } else {
- sec_channel_type = get_sec_channel_type(NULL);
- }
-
- if (sec_channel_type != SEC_CHAN_WKSTA)
- return 1;
-
- return run_rpc_command(NULL, PI_NETLOGON,
- NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_join_oldstyle_internals,
- argc, argv);
-}
-
-/**
- * Join a domain, the old way.
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
static int net_rpc_oldjoin(int argc, const char **argv)
{
return run_rpc_command(NULL, PI_NETLOGON,
NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_join_oldstyle_internals,
+ rpc_oldjoin_internals,
argc, argv);
}
@@ -351,13 +329,13 @@ static int rpc_join_usage(int argc, const char **argv)
*
* Main 'net_rpc_join()' (where the admain username/password is used) is
* in net_rpc_join.c
- * Assume if a -U is specified, it's the new style, otherwise it's the
- * old style. If 'oldstyle' is specfied explicity, do it and don't prompt.
+ * Try to just change the password, but if that doesn't work, use/prompt
+ * for a username/password.
**/
int net_rpc_join(int argc, const char **argv)
{
- if ((net_rpc_join_oldstyle(argc, argv) == 0))
+ if ((net_rpc_oldjoin(argc, argv) == 0))
return 0;
return net_rpc_join_newstyle(argc, argv);
@@ -862,11 +840,11 @@ rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
if (opt_long_list_entries)
- printf("%-21.21s %-50.50s\n", user, desc);
+ printf("%-21.21s %s\n", user, desc);
else
printf("%s\n", user);
}
- } while (!NT_STATUS_IS_OK(result));
+ } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
done:
return result;
@@ -977,7 +955,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
else
printf("%-21.21s\n", groups[i].acct_name);
}
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+ } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
/* query domain aliases */
do {
result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
@@ -992,7 +970,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
else
printf("%-21.21s\n", groups[i].acct_name);
}
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+ } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
cli_samr_close(cli, mem_ctx, &domain_pol);
/* Get builtin policy handle */
@@ -1016,7 +994,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
else
printf("%s\n", groups[i].acct_name);
}
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+ } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
done:
return result;
@@ -1576,8 +1554,8 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
uint16 acb_info;
uint32 unknown, user_rid;
- if (argc != 1) {
- d_printf("Usage: net rpc trustdom add <domain_name>\n");
+ if (argc != 2) {
+ d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1608,7 +1586,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
/* Create trusting domain's account */
acb_info = ACB_DOMTRUST;
- unknown = 0xe005000b; /* No idea what this is - a permission mask?
+ unknown = 0xe00500b0; /* No idea what this is - a permission mask?
mimir: yes, most probably it is */
result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
@@ -1618,6 +1596,37 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
goto done;
}
+ {
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_24 p24;
+ fstring ucs2_trust_password;
+ int ucs2_pw_len;
+ uchar pwbuf[516];
+
+ ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, argv[1],
+ sizeof(ucs2_trust_password), 0);
+
+ encode_pw_buffer((char *)pwbuf, ucs2_trust_password,
+ ucs2_pw_len);
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(p24);
+
+ init_sam_user_info24(&p24, (char *)pwbuf, 24);
+
+ ctr.switch_value = 24;
+ ctr.info.id24 = &p24;
+
+ result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
+ cli->user_session_key, &ctr);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("Could not set trust account password: %s\n",
+ nt_errstr(result)));
+ goto done;
+ }
+ }
+
done:
SAFE_FREE(acct_name);
return result;
@@ -1785,7 +1794,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
return -1;
}
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
+ nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
&connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
@@ -1804,6 +1813,9 @@ static int rpc_trustdom_establish(int argc, const char **argv)
return -1;
}
+
+
+
/* There should be actually query info level 3 (following nt serv behaviour),
but I still don't know if it's _really_ necessary */
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 42bb480844a..ae6f52ebc41 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -209,6 +209,11 @@ int rpc_samdump(int argc, const char **argv)
fstrcpy(cli->domain, lp_workgroup());
+ if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+ DEBUG(0,("Could not open connection to NETLOGON pipe\n"));
+ goto fail;
+ }
+
if (!secrets_fetch_trust_account_password(lp_workgroup(),
trust_password,
NULL, &sec_channel)) {
@@ -216,7 +221,8 @@ int rpc_samdump(int argc, const char **argv)
goto fail;
}
- if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) {
+ if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel,
+ trust_password))) {
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
goto fail;
}
@@ -929,11 +935,17 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
db_type, sync_context,
&num_deltas,
&hdr_deltas, &deltas);
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
- ret_creds);
- for (i = 0; i < num_deltas; i++) {
- fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
- }
+
+ if (NT_STATUS_IS_OK(result) ||
+ NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
+
+ clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
+ ret_creds);
+
+ for (i = 0; i < num_deltas; i++) {
+ fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
+ }
+ }
sync_context += 1;
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
@@ -947,7 +959,6 @@ int rpc_vampire(int argc, const char **argv)
struct cli_state *cli = NULL;
uchar trust_password[16];
DOM_CRED ret_creds;
- uint32 neg_flags = 0x000001ff;
DOM_SID dom_sid;
uint32 sec_channel;
@@ -971,8 +982,8 @@ int rpc_vampire(int argc, const char **argv)
goto fail;
}
- result = cli_nt_setup_creds(cli, sec_channel, trust_password,
- &neg_flags, 2);
+ result = cli_nt_establish_netlogon(cli, sec_channel, trust_password);
+
if (!NT_STATUS_IS_OK(result)) {
d_printf("Failed to setup BDC creds\n");
goto fail;
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 42490190f32..c619936f683 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -38,7 +38,6 @@ enum squid_mode {
extern int winbindd_fd;
-static const char *helper_protocol;
static const char *opt_username;
static const char *opt_domain;
static const char *opt_workstation;
@@ -48,7 +47,6 @@ static DATA_BLOB opt_lm_response;
static DATA_BLOB opt_nt_response;
static int request_lm_key;
static int request_nt_key;
-static int diagnostics;
static char winbind_separator(void)
@@ -184,7 +182,7 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
const DATA_BLOB *lm_response,
const DATA_BLOB *nt_response,
uint32 flags,
- uint8 lm_key[16],
+ uint8 lm_key[8],
uint8 nt_key[16],
char **error_string)
{
@@ -410,9 +408,10 @@ static BOOL check_auth_crap(void)
char *hex_lm_key;
char *hex_nt_key;
char *error_string;
-
static uint8 zeros[16];
+ x_setbuf(x_stdout, NULL);
+
if (request_lm_key)
flags |= WINBIND_PAM_LMKEY;
@@ -430,9 +429,9 @@ static BOOL check_auth_crap(void)
&error_string);
if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
+ x_fprintf(x_stdout, "%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
SAFE_FREE(error_string);
return False;
}
@@ -443,7 +442,7 @@ static BOOL check_auth_crap(void)
hex_encode(lm_key,
sizeof(lm_key),
&hex_lm_key);
- d_printf("LM_KEY: %s\n", hex_lm_key);
+ x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key);
SAFE_FREE(hex_lm_key);
}
if (request_nt_key
@@ -452,7 +451,7 @@ static BOOL check_auth_crap(void)
hex_encode(nt_key,
sizeof(nt_key),
&hex_nt_key);
- d_printf("NT_KEY: %s\n", hex_nt_key);
+ x_fprintf(x_stdout, "NT_KEY: %s\n", hex_nt_key);
SAFE_FREE(hex_nt_key);
}
@@ -476,6 +475,10 @@ static DATA_BLOB get_challenge(void)
return chal;
}
+/*
+ * Test LM authentication, no NT response supplied
+ */
+
static BOOL test_lm(void)
{
NTSTATUS nt_status;
@@ -483,13 +486,18 @@ static BOOL test_lm(void)
DATA_BLOB lm_response = data_blob(NULL, 24);
uchar lm_key[8];
+ uchar nt_key[16];
uchar lm_hash[16];
DATA_BLOB chall = get_challenge();
char *error_string;
+ ZERO_STRUCT(lm_key);
+ ZERO_STRUCT(nt_key);
+
flags |= WINBIND_PAM_LMKEY;
+ flags |= WINBIND_PAM_NTKEY;
- SMBencrypt(opt_password,chall.data,lm_response.data);
+ SMBencrypt(opt_password, chall.data, lm_response.data);
E_deshash(opt_password, lm_hash);
nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation,
@@ -498,7 +506,7 @@ static BOOL test_lm(void)
NULL,
flags,
lm_key,
- NULL,
+ nt_key,
&error_string);
data_blob_free(&lm_response);
@@ -518,9 +526,20 @@ static BOOL test_lm(void)
DEBUG(1, ("expected:\n"));
dump_data(1, lm_hash, 8);
}
+ if (memcmp(lm_hash, nt_key, 8) != 0) {
+ DEBUG(1, ("Session Key (first 8, lm hash) does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 8);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ }
return True;
}
+/*
+ * Test the normal 'LM and NTLM' combination
+ */
+
static BOOL test_lm_ntlm(void)
{
BOOL pass = True;
@@ -537,6 +556,9 @@ static BOOL test_lm_ntlm(void)
DATA_BLOB chall = get_challenge();
char *error_string;
+ ZERO_STRUCT(lm_key);
+ ZERO_STRUCT(nt_key);
+
flags |= WINBIND_PAM_LMKEY;
flags |= WINBIND_PAM_NTKEY;
@@ -589,6 +611,10 @@ static BOOL test_lm_ntlm(void)
return pass;
}
+/*
+ * Test the NTLM response only, no LM.
+ */
+
static BOOL test_ntlm(void)
{
BOOL pass = True;
@@ -597,24 +623,170 @@ static BOOL test_ntlm(void)
DATA_BLOB nt_response = data_blob(NULL, 24);
DATA_BLOB session_key = data_blob(NULL, 16);
+ char lm_key[8];
char nt_key[16];
+ char lm_hash[16];
char nt_hash[16];
DATA_BLOB chall = get_challenge();
char *error_string;
+ ZERO_STRUCT(lm_key);
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_LMKEY;
flags |= WINBIND_PAM_NTKEY;
SMBNTencrypt(opt_password,chall.data,nt_response.data);
E_md4hash(opt_password, nt_hash);
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ E_deshash(opt_password, lm_hash);
+
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
opt_workstation,
&chall,
NULL,
&nt_response,
flags,
+ lm_key,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&nt_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ if (memcmp(lm_hash, lm_key,
+ sizeof(lm_key)) != 0) {
+ DEBUG(1, ("LM Key does not match expectations!\n"));
+ DEBUG(1, ("lm_key:\n"));
+ dump_data(1, lm_key, 8);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ pass = False;
+ }
+ if (memcmp(session_key.data, nt_key,
+ sizeof(nt_key)) != 0) {
+ DEBUG(1, ("NT Session Key does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 16);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, session_key.data, session_key.length);
+ pass = False;
+ }
+ return pass;
+}
+
+/*
+ * Test the NTLM response only, but in the LM field.
+ */
+
+static BOOL test_ntlm_in_lm(void)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB nt_response = data_blob(NULL, 24);
+
+ uchar lm_key[8];
+ uchar lm_hash[16];
+ uchar nt_key[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_LMKEY;
+ flags |= WINBIND_PAM_NTKEY;
+
+ SMBNTencrypt(opt_password,chall.data,nt_response.data);
+
+ E_deshash(opt_password, lm_hash);
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &nt_response,
NULL,
+ flags,
+ lm_key,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&nt_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ if (memcmp(lm_hash, lm_key,
+ sizeof(lm_key)) != 0) {
+ DEBUG(1, ("LM Key does not match expectations!\n"));
+ DEBUG(1, ("lm_key:\n"));
+ dump_data(1, lm_key, 8);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ pass = False;
+ }
+ if (memcmp(lm_hash, nt_key, 8) != 0) {
+ DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 16);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ pass = False;
+ }
+ return pass;
+}
+
+/*
+ * Test the NTLM response only, but in the both the NT and LM fields.
+ */
+
+static BOOL test_ntlm_in_both(void)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB nt_response = data_blob(NULL, 24);
+ DATA_BLOB session_key = data_blob(NULL, 16);
+
+ char lm_key[8];
+ char lm_hash[16];
+ char nt_key[16];
+ char nt_hash[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(lm_key);
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_LMKEY;
+ flags |= WINBIND_PAM_NTKEY;
+
+ SMBNTencrypt(opt_password,chall.data,nt_response.data);
+ E_md4hash(opt_password, nt_hash);
+ SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+
+ E_deshash(opt_password, lm_hash);
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &nt_response,
+ &nt_response,
+ flags,
+ lm_key,
nt_key,
&error_string);
@@ -628,6 +800,267 @@ static BOOL test_ntlm(void)
return False;
}
+ if (memcmp(lm_hash, lm_key,
+ sizeof(lm_key)) != 0) {
+ DEBUG(1, ("LM Key does not match expectations!\n"));
+ DEBUG(1, ("lm_key:\n"));
+ dump_data(1, lm_key, 8);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ pass = False;
+ }
+ if (memcmp(session_key.data, nt_key,
+ sizeof(nt_key)) != 0) {
+ DEBUG(1, ("NT Session Key does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 16);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, session_key.data, session_key.length);
+ pass = False;
+ }
+
+
+ return pass;
+}
+
+/*
+ * Test the NTLMv2 response only
+ */
+
+static BOOL test_ntlmv2(void)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
+ DATA_BLOB nt_session_key = data_blob(NULL, 0);
+ DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain());
+
+ uchar nt_key[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_NTKEY;
+
+ if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
+ &names_blob,
+ NULL, &ntlmv2_response,
+ &nt_session_key)) {
+ data_blob_free(&names_blob);
+ return False;
+ }
+ data_blob_free(&names_blob);
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ NULL,
+ &ntlmv2_response,
+ flags,
+ NULL,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&ntlmv2_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ if (memcmp(nt_session_key.data, nt_key,
+ sizeof(nt_key)) != 0) {
+ DEBUG(1, ("NT Session Key does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 16);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, nt_session_key.data, nt_session_key.length);
+ pass = False;
+ }
+ return pass;
+}
+
+/*
+ * Test the NTLMv2 and LMv2 responses
+ */
+
+static BOOL test_lmv2_ntlmv2(void)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
+ DATA_BLOB lmv2_response = data_blob(NULL, 0);
+ DATA_BLOB nt_session_key = data_blob(NULL, 0);
+ DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain());
+
+ uchar nt_key[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_NTKEY;
+
+ if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
+ &names_blob,
+ &lmv2_response, &ntlmv2_response,
+ &nt_session_key)) {
+ data_blob_free(&names_blob);
+ return False;
+ }
+ data_blob_free(&names_blob);
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &lmv2_response,
+ &ntlmv2_response,
+ flags,
+ NULL,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&lmv2_response);
+ data_blob_free(&ntlmv2_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ if (memcmp(nt_session_key.data, nt_key,
+ sizeof(nt_key)) != 0) {
+ DEBUG(1, ("NT Session Key does not match expectations!\n"));
+ DEBUG(1, ("nt_key:\n"));
+ dump_data(1, nt_key, 16);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, nt_session_key.data, nt_session_key.length);
+ pass = False;
+ }
+ return pass;
+}
+
+/*
+ * Test the LMv2 response only
+ */
+
+static BOOL test_lmv2(void)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB lmv2_response = data_blob(NULL, 0);
+
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
+ NULL,
+ &lmv2_response, NULL,
+ NULL)) {
+ return False;
+ }
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &lmv2_response,
+ NULL,
+ flags,
+ NULL,
+ NULL,
+ &error_string);
+
+ data_blob_free(&lmv2_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ return pass;
+}
+
+/*
+ * Test the normal 'LM and NTLM' combination but deliberately break one
+ */
+
+static BOOL test_ntlm_broken(BOOL break_lm)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB lm_response = data_blob(NULL, 24);
+ DATA_BLOB nt_response = data_blob(NULL, 24);
+ DATA_BLOB session_key = data_blob(NULL, 16);
+
+ uchar lm_key[8];
+ uchar nt_key[16];
+ uchar lm_hash[16];
+ uchar nt_hash[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(lm_key);
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_LMKEY;
+ flags |= WINBIND_PAM_NTKEY;
+
+ SMBencrypt(opt_password,chall.data,lm_response.data);
+ E_deshash(opt_password, lm_hash);
+
+ SMBNTencrypt(opt_password,chall.data,nt_response.data);
+
+ E_md4hash(opt_password, nt_hash);
+ SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+
+ if (break_lm)
+ lm_response.data[0]++;
+ else
+ nt_response.data[0]++;
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &lm_response,
+ &nt_response,
+ flags,
+ lm_key,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&lm_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ if (memcmp(lm_hash, lm_key,
+ sizeof(lm_key)) != 0) {
+ DEBUG(1, ("LM Key does not match expectations!\n"));
+ DEBUG(1, ("lm_key:\n"));
+ dump_data(1, lm_key, 8);
+ DEBUG(1, ("expected:\n"));
+ dump_data(1, lm_hash, 8);
+ pass = False;
+ }
if (memcmp(session_key.data, nt_key,
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
@@ -640,12 +1073,92 @@ static BOOL test_ntlm(void)
return pass;
}
+static BOOL test_ntlm_lm_broken(void)
+{
+ return test_ntlm_broken(True);
+}
+
+static BOOL test_ntlm_ntlm_broken(void)
+{
+ return test_ntlm_broken(False);
+}
+
+static BOOL test_ntlmv2_broken(BOOL break_lmv2)
+{
+ BOOL pass = True;
+ NTSTATUS nt_status;
+ uint32 flags = 0;
+ DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
+ DATA_BLOB lmv2_response = data_blob(NULL, 0);
+ DATA_BLOB nt_session_key = data_blob(NULL, 0);
+ DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain());
+
+ uchar nt_key[16];
+ DATA_BLOB chall = get_challenge();
+ char *error_string;
+
+ ZERO_STRUCT(nt_key);
+
+ flags |= WINBIND_PAM_NTKEY;
+
+ if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
+ &names_blob,
+ &lmv2_response, &ntlmv2_response,
+ &nt_session_key)) {
+ data_blob_free(&names_blob);
+ return False;
+ }
+ data_blob_free(&names_blob);
+
+ /* Heh - this should break the appropriate password hash nicely! */
+
+ if (break_lmv2)
+ lmv2_response.data[0]++;
+ else
+ ntlmv2_response.data[0]++;
+
+ nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
+ opt_workstation,
+ &chall,
+ &lmv2_response,
+ &ntlmv2_response,
+ flags,
+ NULL,
+ nt_key,
+ &error_string);
+
+ data_blob_free(&lmv2_response);
+ data_blob_free(&ntlmv2_response);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ d_printf("%s (0x%x)\n",
+ error_string,
+ NT_STATUS_V(nt_status));
+ SAFE_FREE(error_string);
+ return False;
+ }
+
+ return pass;
+}
+
+static BOOL test_ntlmv2_lmv2_broken(void)
+{
+ return test_ntlmv2_broken(True);
+}
+
+static BOOL test_ntlmv2_ntlmv2_broken(void)
+{
+ return test_ntlmv2_broken(False);
+}
+
/*
Tests:
- LM only
- NT and LM
- NT
+ - NT in LM field
+ - NT in both fields
- NTLMv2
- NTLMv2 and LMv2
- LMv2
@@ -659,12 +1172,18 @@ struct ntlm_tests {
BOOL (*fn)(void);
const char *name;
} test_table[] = {
- {test_lm, "test LM"},
- {test_lm_ntlm, "test LM and NTLM"},
- {test_ntlm, "test NTLM"}
-/* {test_lm_ntlmv2, "test NTLMv2"}, */
-/* {test_lm_ntlmv2, "test NTLMv2 and LMv2"}, */
-/* {test_lm_ntlmv2, "test LMv2"} */
+ {test_lm, "LM"},
+ {test_lm_ntlm, "LM and NTLM"},
+ {test_ntlm, "NTLM"},
+ {test_ntlm_in_lm, "NTLM in LM"},
+ {test_ntlm_in_both, "NTLM in both"},
+ {test_ntlmv2, "NTLMv2"},
+ {test_lmv2_ntlmv2, "NTLMv2 and LMv2"},
+ {test_lmv2, "LMv2"},
+ {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken"},
+ {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken"},
+ {test_ntlm_lm_broken, "NTLM and LM, LM broken"},
+ {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken"}
};
static BOOL diagnose_ntlm_auth(void)
@@ -701,6 +1220,8 @@ enum {
int main(int argc, const char **argv)
{
int opt;
+ static const char *helper_protocol;
+ static int diagnostics;
static const char *hex_challenge;
static const char *hex_lm_response;
@@ -743,6 +1264,14 @@ enum {
dbf = x_stderr;
+ /* Samba client initialisation */
+
+ if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
+ d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
+ dyn_CONFIGFILE, strerror(errno));
+ exit(1);
+ }
+
/* Parse options */
pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0);
@@ -760,7 +1289,7 @@ enum {
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case OPT_CHALLENGE:
- challenge = smb_xmalloc((strlen(hex_challenge)+1)/2);
+ challenge = smb_xmalloc((strlen(hex_challenge))/2+1);
if ((challenge_len = strhex_to_str(challenge,
strlen(hex_challenge),
hex_challenge)) != 8) {
@@ -772,7 +1301,7 @@ enum {
SAFE_FREE(challenge);
break;
case OPT_LM:
- lm_response = smb_xmalloc((strlen(hex_lm_response)+1)/2);
+ lm_response = smb_xmalloc((strlen(hex_lm_response))/2+1);
lm_response_len = strhex_to_str(lm_response,
strlen(hex_lm_response),
hex_lm_response);
@@ -784,7 +1313,7 @@ enum {
SAFE_FREE(lm_response);
break;
case OPT_NT:
- nt_response = smb_xmalloc((strlen(hex_nt_response)+1)/2);
+ nt_response = smb_xmalloc((strlen(hex_nt_response)+2)/2+1);
nt_response_len = strhex_to_str(nt_response,
strlen(hex_nt_response),
hex_nt_response);
diff --git a/source/web/swat.c b/source/web/swat.c
index 7f9492933a5..d97278c4859 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -31,8 +31,6 @@
#include "includes.h"
#include "../web/swat_proto.h"
-#define GLOBALS_SNUM -1
-
static BOOL demo_mode = False;
static BOOL have_write_access = False;
static BOOL have_read_access = False;
@@ -579,7 +577,7 @@ static void wizard_params_page(void)
d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
if (cgi_variable("Commit")) {
- commit_parameters(GLOBALS_SNUM);
+ commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(0);
}
@@ -593,7 +591,7 @@ static void wizard_params_page(void)
d_printf("<p>\n");
d_printf("<table>\n");
- show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
+ show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
d_printf("</table>\n");
d_printf("</form>\n");
}
@@ -603,7 +601,7 @@ static void wizard_params_page(void)
****************************************************************************/
static void rewritecfg_file(void)
{
- commit_parameters(GLOBALS_SNUM);
+ commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(0);
d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
}
@@ -637,37 +635,37 @@ static void wizard_page(void)
HomeExpo = atoi(cgi_variable("HomeExpo"));
/* Plain text passwords are too badly broken - use encrypted passwords only */
- lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
switch ( SerType ){
case 0:
/* Stand-alone Server */
- lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
break;
case 1:
/* Domain Member */
- lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
break;
case 2:
/* Domain Controller */
- lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
break;
}
switch ( winstype ) {
case 0:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
break;
case 1:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
break;
case 2:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
+ lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
break;
}
@@ -677,7 +675,7 @@ static void wizard_page(void)
pstrcpy(unix_share,HOMES_NAME);
load_config(False);
- lp_copy_service(GLOBALS_SNUM, unix_share);
+ lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
iNumNonAutoPrintServices = lp_numservices();
have_home = lp_servicenumber(HOMES_NAME);
lp_do_parameter( have_home, "read only", "No");
@@ -692,7 +690,7 @@ static void wizard_page(void)
have_home = -1;
}
- commit_parameters(GLOBALS_SNUM);
+ commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(0);
}
else
@@ -778,7 +776,7 @@ static void globals_page(void)
d_printf("<H2>%s</H2>\n", _("Global Variables"));
if (cgi_variable("Commit")) {
- commit_parameters(GLOBALS_SNUM);
+ commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(0);
}
@@ -810,7 +808,7 @@ static void globals_page(void)
d_printf("<p>\n");
d_printf("<table>\n");
- show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
+ show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
d_printf("</table>\n");
d_printf("</form>\n");
}
@@ -847,7 +845,7 @@ static void shares_page(void)
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
load_config(False);
- lp_copy_service(GLOBALS_SNUM, share);
+ lp_copy_service(GLOBAL_SECTION_SNUM, share);
iNumNonAutoPrintServices = lp_numservices();
save_reload(0);
snum = lp_servicenumber(share);
@@ -1186,7 +1184,7 @@ static void printers_page(void)
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
load_config(False);
- lp_copy_service(GLOBALS_SNUM, share);
+ lp_copy_service(GLOBAL_SECTION_SNUM, share);
iNumNonAutoPrintServices = lp_numservices();
snum = lp_servicenumber(share);
lp_do_parameter(snum, "print ok", "Yes");