summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/build/make/rules.mk7
-rw-r--r--source4/lib/replace/Makefile.in4
-rw-r--r--source4/lib/replace/configure.ac2
-rw-r--r--source4/lib/replace/getifaddrs.m43
-rw-r--r--source4/lib/replace/libreplace.m41
-rw-r--r--source4/lib/replace/replace.h10
-rw-r--r--source4/lib/replace/socket.c35
-rw-r--r--source4/lib/replace/socket.m440
-rw-r--r--source4/lib/replace/system/network.h10
-rw-r--r--source4/ntvfs/common/opendb_tdb.c11
-rw-r--r--source4/ntvfs/posix/pvfs_open.c26
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c2
-rw-r--r--source4/pidl/idl.yp2
-rw-r--r--source4/pidl/lib/Parse/Pidl/IDL.pm2
-rw-r--r--source4/torture/raw/oplock.c74
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;
}