diff options
-rw-r--r-- | source4/build/make/rules.mk | 7 | ||||
-rw-r--r-- | source4/lib/replace/Makefile.in | 4 | ||||
-rw-r--r-- | source4/lib/replace/configure.ac | 2 | ||||
-rw-r--r-- | source4/lib/replace/getifaddrs.m4 | 3 | ||||
-rw-r--r-- | source4/lib/replace/libreplace.m4 | 1 | ||||
-rw-r--r-- | source4/lib/replace/replace.h | 10 | ||||
-rw-r--r-- | source4/lib/replace/socket.c | 35 | ||||
-rw-r--r-- | source4/lib/replace/socket.m4 | 40 | ||||
-rw-r--r-- | source4/lib/replace/system/network.h | 10 | ||||
-rw-r--r-- | source4/ntvfs/common/opendb_tdb.c | 11 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 26 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_qfileinfo.c | 2 | ||||
-rw-r--r-- | source4/pidl/idl.yp | 2 | ||||
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/IDL.pm | 2 | ||||
-rw-r--r-- | source4/torture/raw/oplock.c | 74 |
15 files changed, 215 insertions, 14 deletions
diff --git a/source4/build/make/rules.mk b/source4/build/make/rules.mk index 794eed0f66..44277fe3e2 100644 --- a/source4/build/make/rules.mk +++ b/source4/build/make/rules.mk @@ -81,6 +81,13 @@ check:: test unused_macros: $(srcdir)/script/find_unused_macros.pl `find . -name "*.[ch]"` | sort +# Create a static library +%.a: + @echo Linking $@ + @rm -f $@ + @mkdir -p $(@D) + @$(STLD) $(STLD_FLAGS) $@ $^ + ############################################################################### # Templates ############################################################################### diff --git a/source4/lib/replace/Makefile.in b/source4/lib/replace/Makefile.in index 30f39ac6cb..af9522f3a6 100644 --- a/source4/lib/replace/Makefile.in +++ b/source4/lib/replace/Makefile.in @@ -10,6 +10,7 @@ VPATH = @libreplacedir@ srcdir = @srcdir@ builddir = @builddir@ INSTALL = @INSTALL@ +LIBS = @LIBS@ .PHONY: test all showflags install installcheck clean distclean realdistclean @@ -25,6 +26,7 @@ showflags: @echo ' CC = $(CC)' @echo ' CFLAGS = $(CFLAGS)' @echo ' LDFLAGS= $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' install: all mkdir -p $(libdir) @@ -41,7 +43,7 @@ installcheck: install test TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o testsuite: libreplace.a $(TEST_OBJS) - $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) + $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS) .c.o: @echo Compiling $*.c diff --git a/source4/lib/replace/configure.ac b/source4/lib/replace/configure.ac index beeb77e152..f5e054f476 100644 --- a/source4/lib/replace/configure.ac +++ b/source4/lib/replace/configure.ac @@ -3,6 +3,8 @@ AC_INIT(replace.c) AC_CONFIG_SRCDIR([replace.c]) AC_CONFIG_HEADER(config.h) +CFLAGS="$CFLAGS -I$srcdir" + AC_LIBREPLACE_ALL_CHECKS if test "$ac_cv_prog_gcc" = yes; then diff --git a/source4/lib/replace/getifaddrs.m4 b/source4/lib/replace/getifaddrs.m4 index dd2a95cb81..767797e8d2 100644 --- a/source4/lib/replace/getifaddrs.m4 +++ b/source4/lib/replace/getifaddrs.m4 @@ -71,6 +71,7 @@ AC_TRY_RUN([ libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)]) if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available]) + old_LIBS="$old_LIBS $LIBS" fi fi @@ -87,6 +88,7 @@ AC_TRY_RUN([ libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)]) if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available]) + old_LIBS="$old_LIBS $LIBS" fi fi @@ -102,6 +104,7 @@ AC_TRY_RUN([ libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)]) if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available]) + old_LIBS="$old_LIBS $LIBS" fi fi diff --git a/source4/lib/replace/libreplace.m4 b/source4/lib/replace/libreplace.m4 index 2e0cd34f4a..e0cc57f4c8 100644 --- a/source4/lib/replace/libreplace.m4 +++ b/source4/lib/replace/libreplace.m4 @@ -344,6 +344,7 @@ m4_include(getpass.m4) m4_include(strptime.m4) m4_include(win32.m4) m4_include(timegm.m4) +m4_include(socket.m4) m4_include(inet_ntop.m4) m4_include(inet_pton.m4) m4_include(getaddrinfo.m4) diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h index 3f91544e97..0d16f4ffd0 100644 --- a/source4/lib/replace/replace.h +++ b/source4/lib/replace/replace.h @@ -340,6 +340,16 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) /* prototype is in "system/network.h" */ #endif +#ifndef HAVE_CONNECT +#define connect rep_connect +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETHOSTBYNAME +#define gethostbyname rep_gethostbyname +/* prototype is in "system/network.h" */ +#endif + #ifndef HAVE_GETIFADDRS #define getifaddrs rep_getifaddrs /* prototype is in "system/network.h" */ diff --git a/source4/lib/replace/socket.c b/source4/lib/replace/socket.c new file mode 100644 index 0000000000..35e975fce7 --- /dev/null +++ b/source4/lib/replace/socket.c @@ -0,0 +1,35 @@ +/* + * Unix SMB/CIFS implementation. + * + * Dummy replacements for socket functions. + * + * Copyright (C) Michael Adam <obnox@samba.org> 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "replace.h" +#include "system/network.h" + +int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + errno = ENOSYS; + return -1; +} + +struct hostent *rep_gethostbyname(const char *name) +{ + errno = ENOSYS; + return NULL; +} diff --git a/source4/lib/replace/socket.m4 b/source4/lib/replace/socket.m4 new file mode 100644 index 0000000000..c0c8f93e81 --- /dev/null +++ b/source4/lib/replace/socket.m4 @@ -0,0 +1,40 @@ +dnl The following test is roughl taken from the cvs sources. +dnl +dnl If we can't find connect, try looking in -lsocket, -lnsl, and -linet. +dnl The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has +dnl libsocket.so which has a bad implementation of gethostbyname (it +dnl only looks in /etc/hosts), so we only look for -lsocket if we need +dnl it. +AC_CHECK_FUNCS(connect) +if test x"$ac_cv_func_connect" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect) + dnl We can't just call AC_CHECK_FUNCS(connect) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" || + test x"$ac_cv_lib_ext_nsl_connect" = x"yes" || + test x"$ac_cv_lib_ext_socket_connect" = x"yes" || + test x"$ac_cv_lib_ext_inet_connect" = x"yes" + then + AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()]) + fi +fi + +AC_CHECK_FUNCS(gethostbyname) +if test x"$ac_cv_func_gethostbyname" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname) + dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_nsl_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_socket_gethostbyname" = x"yes" + then + AC_DEFINE(HAVE_GETHOSTBYNAME,1, + [Whether the system has gethostbyname()]) + fi +fi + diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h index a84b22e5d0..410c6d7cca 100644 --- a/source4/lib/replace/system/network.h +++ b/source4/lib/replace/system/network.h @@ -103,6 +103,16 @@ int rep_inet_pton(int af, const char *src, void *dst); const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif +#ifndef HAVE_CONNECT +/* define is in "replace.h" */ +int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif + +#ifndef HAVE_GETHOSTBYNAME +/* define is in "replace.h" */ +struct hostent *rep_gethostbyname(const char *name); +#endif + #ifdef HAVE_IFADDRS_H #include <ifaddrs.h> #endif diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 73c04b7c4f..fe5a0a8864 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -288,7 +288,8 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, } static bool access_attributes_only(uint32_t access_mask, - uint32_t open_disposition) + uint32_t open_disposition, + bool break_to_none) { switch (open_disposition) { case NTCREATEX_DISP_SUPERSEDE: @@ -298,6 +299,11 @@ static bool access_attributes_only(uint32_t access_mask, default: break; } + + if (break_to_none) { + return false; + } + #define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0)) return CHECK_MASK(access_mask, SEC_STD_SYNCHRONIZE | @@ -326,7 +332,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, * but we'll not grant the oplock below */ attrs_only = access_attributes_only(access_mask, - open_disposition); + open_disposition, + break_to_none); if (attrs_only) { break; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 12b70c00fd..a01352f60c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1530,7 +1530,7 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); if (NT_STATUS_IS_OK(status)) { status = pvfs_access_check_simple(pvfs, req, name, access_mask); @@ -1594,7 +1594,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); /* * if it's a sharing violation or we got no oplock @@ -1648,15 +1648,25 @@ NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - /* TODO: this may needs some more flags */ - share_access = NTCREATEX_SHARE_ACCESS_WRITE; - access_mask = 0; + share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + /* + * I would have thought that we would need to pass + * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too + * + * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions + * to set the filesize. + * + * --metze + */ + access_mask = SEC_FILE_WRITE_ATTRIBUTE; delete_on_close = false; break_to_none = true; status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, break_to_none); + NTCREATEX_DISP_OPEN, break_to_none); /* * if it's a sharing violation or we got no oplock @@ -1710,12 +1720,12 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - access_mask = 0; + access_mask = SEC_FILE_READ_ATTRIBUTE; delete_on_close = false; status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 2f01c08fb0..8d23d707a4 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -330,7 +330,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, status = pvfs_can_stat(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_DELETE_PENDING; + return status; } status = pvfs_access_check_simple(pvfs, req, name, diff --git a/source4/pidl/idl.yp b/source4/pidl/idl.yp index 028b628e18..c7ca0c7604 100644 --- a/source4/pidl/idl.yp +++ b/source4/pidl/idl.yp @@ -391,7 +391,7 @@ sub _Error { error($_[0]->YYData, $_[0]->YYData->{ERRMSG}); delete $_[0]->YYData->{ERRMSG}; return; - }; + } my $last_token = $_[0]->YYData->{LAST_TOKEN}; error($_[0]->YYData, "Syntax error near '$last_token'"); diff --git a/source4/pidl/lib/Parse/Pidl/IDL.pm b/source4/pidl/lib/Parse/Pidl/IDL.pm index aeee69e306..4adb4dcea8 100644 --- a/source4/pidl/lib/Parse/Pidl/IDL.pm +++ b/source4/pidl/lib/Parse/Pidl/IDL.pm @@ -2408,7 +2408,7 @@ sub _Error { error($_[0]->YYData, $_[0]->YYData->{ERRMSG}); delete $_[0]->YYData->{ERRMSG}; return; - }; + } my $last_token = $_[0]->YYData->{LAST_TOKEN}; error($_[0]->YYData, "Syntax error near '$last_token'"); diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index 3edd0c6820..e81b634161 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -1279,6 +1279,79 @@ done: return ret; } +static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2) +{ + const char *fname = BASEDIR "\\test_batch15.dat"; + NTSTATUS status; + bool ret = true; + union smb_open io; + union smb_fileinfo qfi; + uint16_t fnum=0; + + if (!torture_setup_dir(cli1, BASEDIR)) { + return false; + } + + /* cleanup */ + smbcli_unlink(cli1->tree, fname); + + smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree); + + /* + base ntcreatex parms + */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname; + + /* Test if a qpathinfo all info on pathname breaks a batch oplock. */ + torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n"); + + ZERO_STRUCT(break_info); + smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree); + + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | + NTCREATEX_FLAGS_REQUEST_OPLOCK | + NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + status = smb_raw_open(cli1->tree, tctx, &io); + CHECK_STATUS(tctx, status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + CHECK_VAL(break_info.count, 0); + CHECK_VAL(break_info.failures, 0); + CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN); + + ZERO_STRUCT(qfi); + qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION; + qfi.generic.in.file.path = fname; + + status = smb_raw_pathinfo(cli2->tree, tctx, &qfi); + + CHECK_STATUS(tctx, status, NT_STATUS_OK); + CHECK_VAL(break_info.count, 0); + + smbcli_close(cli1->tree, fnum); + +done: + smb_raw_exit(cli1->session); + smb_raw_exit(cli2->session); + smbcli_deltree(cli1->tree, BASEDIR); + return ret; +} + /* basic testing of oplocks */ @@ -1301,6 +1374,7 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx) torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12); torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13); torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14); + torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15); return suite; } |