summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2007-05-21 21:17:21 +0000
committerGerald Carter <jerry@samba.org>2007-05-21 21:17:21 +0000
commit34059e63c8a644b10cf9a59cca5e67a45053d16e (patch)
treeb0751d47f93023938656df3c6173618dfef4f1e5
parentc3f0e56c057f6be60bd3721485f013ed63defa6a (diff)
downloadsamba-34059e63c8a644b10cf9a59cca5e67a45053d16e.tar.gz
r23052: sync with SAMBA_3_0_25 and start updating release notes
-rw-r--r--WHATSNEW.txt59
-rw-r--r--examples/libsmbclient/Makefile5
-rw-r--r--examples/libsmbclient/testacl2.c78
-rw-r--r--source/Makefile.in9
-rw-r--r--source/VERSION2
-rw-r--r--source/auth/auth_server.c11
-rwxr-xr-xsource/client/mount.cifs.c38
-rw-r--r--source/configure.in27
-rw-r--r--source/include/ads.h2
-rw-r--r--source/include/ads_cldap.h2
-rw-r--r--source/lib/replace/dlfcn.m413
-rw-r--r--source/lib/time.c43
-rw-r--r--source/libsmb/libsmbclient.c16
-rw-r--r--source/locking/brlock.c25
-rw-r--r--source/locking/locking.c6
-rw-r--r--source/modules/vfs_hpuxacl.c1193
-rw-r--r--source/modules/vfs_posixacl.c6
-rw-r--r--source/modules/vfs_tru64acl.c12
-rw-r--r--source/nsswitch/winbindd_group.c9
-rw-r--r--source/nsswitch/winbindd_pam.c10
-rw-r--r--source/nsswitch/winbindd_user.c14
-rw-r--r--source/passdb/lookup_sid.c42
-rw-r--r--source/passdb/passdb.c32
-rwxr-xr-xsource/python/setup.py2
-rw-r--r--source/rpc_parse/parse_srv.c4
-rw-r--r--source/rpc_server/srv_lsa_ds_nt.c14
-rw-r--r--source/script/tests/gdb_backtrace2
-rw-r--r--source/smbd/blocking.c26
-rw-r--r--source/smbd/close.c4
-rw-r--r--source/smbd/reply.c13
-rw-r--r--source/smbd/trans2.c8
-rw-r--r--source/smbd/uid.c22
-rw-r--r--source/utils/net_rap.c8
-rw-r--r--source/utils/net_rpc.c2
-rw-r--r--source/utils/pdbedit.c6
35 files changed, 1563 insertions, 202 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 073d76b459f..4ff966a0db6 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,12 +1,57 @@
+ ===============================
+ Release Notes for Samba 3.0.25a
+ May XX, 2007
+ ===============================
+
+This is the second production release of the Samba 3.0.25 code
+base and is the version that servers should be run for for all
+current bug fixes.
+
+Major bug fixes included in Samba 3.0.25a are:
+
+ o Missing supplementary Unix group membership when
+ using "force group"
+ o Premature expiration of domain user passwords when
+ using a Samba domain controller
+ o Failure to open the Windows object picker against server
+ configured to use "security = domain"
+
+
+Changes to MS-DFS Root Share Behavior
+=====================================
+
+Please be aware that the initial value for the "msdfs root" share
+parameter was changed in the 3.0.25 release series and this option
+is now disabled by default. Windows clients frequently require
+a reboot in order to clear any cached information help about MS-DFS
+root shares on a server and you may experience failures access
+file services on Samba 3.0.25 servers until the client reboot
+is performed. Alternately, you may explicitly re-enable the
+parameter in smb.conf. Please refer to the smb.conf(5) man page
+for more details.
+
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.25
+--------------------
+
+
+
+
+
+
+Release notes for older releases follow:
+
+ --------------------------------------------------
==============================
Release Notes for Samba 3.0.25
May 14, 2007
==============================
-This is the first production release of the Samba 3.0.25 code
-base and is the version that servers should be run for for all
-current bug fixes.
-
The 3.0.25 release is an upgrade release over the 3.0.23/3.0.24
series which means that a substantial amount of development has
occurred and many new features have been added since the last
@@ -142,6 +187,7 @@ smb.conf changes
kernel change notify Per share Yes
lock spin count Removed n/a
max stat cache size Modified 1024KB
+ msdfs root Modified no
printjob username New %U
winbind normalize names New no
@@ -706,8 +752,6 @@ o Martin Zielinski <mz@seh.de>
* Printing fixes for Windows Vista clients.
-Release notes for older releases follow:
-
--------------------------------------------------
==============================
Release Notes for Samba 3.0.24
@@ -746,9 +790,6 @@ o Volker Lendecke <vl@samba.org>
* Fix for CVE-2007-0452
-
-Release Notes for older release follow:
-
--------------------------------------------------
===============================
Release Notes for Samba 3.0.23d
diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile
index ee117c9fe92..d44df77b3fb 100644
--- a/examples/libsmbclient/Makefile
+++ b/examples/libsmbclient/Makefile
@@ -17,6 +17,7 @@ LIBSMBCLIENT = ../../source/bin/libsmbclient.a -ldl -lresolv
TESTS= testsmbc \
tree \
testacl \
+ testacl2 \
testbrowse \
testbrowse2 \
teststat \
@@ -39,6 +40,10 @@ testacl: testacl.o
@echo Linking testacl
$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ $< `gtk-config --libs` $(LIBSMBCLIENT) -lpopt
+testacl2: testacl2.o
+ @echo Linking testacl2
+ $(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ $< `gtk-config --libs` $(LIBSMBCLIENT) -lpopt
+
testbrowse: testbrowse.o
@echo Linking testbrowse
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt
diff --git a/examples/libsmbclient/testacl2.c b/examples/libsmbclient/testacl2.c
new file mode 100644
index 00000000000..df38fe208ed
--- /dev/null
+++ b/examples/libsmbclient/testacl2.c
@@ -0,0 +1,78 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <popt.h>
+#include "libsmbclient.h"
+#include "get_auth_data_fn.h"
+
+enum acl_mode
+{
+ SMB_ACL_GET,
+ SMB_ACL_SET,
+ SMB_ACL_DELETE,
+ SMB_ACL_MODIFY,
+ SMB_ACL_ADD,
+ SMB_ACL_CHOWN,
+ SMB_ACL_CHGRP
+};
+
+
+int main(int argc, const char *argv[])
+{
+ int i;
+ int opt;
+ int flags;
+ int debug = 0;
+ int numeric = 0;
+ int full_time_names = 0;
+ enum acl_mode mode = SMB_ACL_GET;
+ static char *the_acl = NULL;
+ int ret;
+ char *p;
+ char *debugstr;
+ char value[1024];
+
+ if (smbc_init(get_auth_data_fn, debug) != 0)
+ {
+ printf("Could not initialize smbc_ library\n");
+ return 1;
+ }
+
+ SMBCCTX *context = smbc_set_context(NULL);
+ smbc_option_set(context, "full_time_names", 1);
+
+ the_acl = strdup("system.nt_sec_desc.*");
+ ret = smbc_getxattr(argv[1], the_acl, value, sizeof(value));
+ if (ret < 0)
+ {
+ printf("Could not get attributes for [%s] %d: %s\n",
+ argv[1], errno, strerror(errno));
+ return 1;
+ }
+
+ printf("Attributes for [%s] are:\n%s\n", argv[1], value);
+
+ flags = 0;
+ debugstr = "set attributes (1st time)";
+
+ ret = smbc_setxattr(argv[1], the_acl, value, strlen(value), flags);
+ if (ret < 0)
+ {
+ printf("Could not %s for [%s] %d: %s\n",
+ debugstr, argv[1], errno, strerror(errno));
+ return 1;
+ }
+
+ flags = 0;
+ debugstr = "set attributes (2nd time)";
+
+ ret = smbc_setxattr(argv[1], the_acl, value, strlen(value), flags);
+ if (ret < 0)
+ {
+ printf("Could not %s for [%s] %d: %s\n",
+ debugstr, argv[1], errno, strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/source/Makefile.in b/source/Makefile.in
index 02396b56437..0da9a8bbc93 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -1349,11 +1349,16 @@ bin/rid.@SHLIBEXT@: proto_exists nsswitch/idmap_rid.o
@$(SHLD) $(LDSHFLAGS) -o $@ nsswitch/idmap_rid.o \
@SONAMEFLAG@`basename $@`
-bin/ad.@SHLIBEXT@: nsswitch/idmap_ad.o
+bin/ad.@SHLIBEXT@: proto_exists nsswitch/idmap_ad.o
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ nsswitch/idmap_ad.o \
@SONAMEFLAG@`basename $@`
+bin/ldap.@SHLIBEXT@: proto_exists nsswitch/idmap_ldap.o
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ nsswitch/idmap_ldap.o \
+ @SONAMEFLAG@`basename $@`
+
bin/weird.@SHLIBEXT@: proto_exists $(DEVEL_HELP_WEIRD_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ) \
@@ -1500,7 +1505,7 @@ bin/gpfs.@SHLIBEXT@: $(VFS_GPFS_OBJ)
bin/notify_fam.@SHLIBEXT@: $(VFS_NOTIFY_FAM_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_NOTIFY_FAM_OBJ) \
- @SONAMEFLAG@`basename $@`
+ @SONAMEFLAG@`basename $@` @SMB_FAM_LIBS@
bin/readahead.@SHLIBEXT@: $(VFS_READAHEAD_OBJ)
@echo "Building plugin $@"
diff --git a/source/VERSION b/source/VERSION
index 301986c5f1e..824f9d54a97 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -36,7 +36,7 @@ SAMBA_VERSION_RELEASE=25
# e.g. SAMBA_VERSION_REVISION=a #
# -> "2.2.8a" #
########################################################
-SAMBA_VERSION_REVISION=
+SAMBA_VERSION_REVISION=a
########################################################
# For 'pre' releases the version will be #
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index c7243e8468b..3e29c246491 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -230,17 +230,6 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
BOOL locally_made_cli = False;
- /*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
- */
-
- if(is_myname(user_info->domain)) {
- DEBUG(3,("check_smbserver_security: Requested domain was for this machine.\n"));
- return nt_status;
- }
-
cli = (struct cli_state *)my_private_data;
if (cli) {
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 009d2a6e73f..2e48a42aafe 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -621,6 +621,7 @@ static int parse_options(char ** optionsp, int * filesys_flags)
nocopy:
data = next_keyword;
}
+ free(*optionsp);
*optionsp = out;
return 0;
}
@@ -882,8 +883,8 @@ int main(int argc, char ** argv)
char * ipaddr = NULL;
char * uuid = NULL;
char * mountpoint = NULL;
- char * options;
- char * resolved_path;
+ char * options = NULL;
+ char * resolved_path = NULL;
char * temp;
int rc;
int rsize = 0;
@@ -1079,12 +1080,15 @@ int main(int argc, char ** argv)
get_password_from_file(0, getenv("PASSWD_FILE"));
}
- if (orgoptions && parse_options(&orgoptions, &flags))
- return -1;
+ if (orgoptions && parse_options(&orgoptions, &flags)) {
+ rc = -1;
+ goto mount_exit;
+ }
ipaddr = parse_server(&share_name);
if((ipaddr == NULL) && (got_ip == 0)) {
printf("No ip address specified and hostname not found\n");
- return -1;
+ rc = -1;
+ goto mount_exit;
}
/* BB save off path and pop after mount returns? */
@@ -1098,17 +1102,20 @@ int main(int argc, char ** argv)
}
if(chdir(mountpoint)) {
printf("mount error: can not change directory into mount target %s\n",mountpoint);
- return -1;
+ rc = -1;
+ goto mount_exit;
}
if(stat (".", &statbuf)) {
printf("mount error: mount point %s does not exist\n",mountpoint);
- return -1;
+ rc = -1;
+ goto mount_exit;
}
if (S_ISDIR(statbuf.st_mode) == 0) {
printf("mount error: mount point %s is not a directory\n",mountpoint);
- return -1;
+ rc = -1;
+ goto mount_exit;
}
if((getuid() != 0) && (geteuid() == 0)) {
@@ -1154,6 +1161,8 @@ mount_retry:
optlen += strlen(ipaddr) + 4;
if(mountpassword)
optlen += strlen(mountpassword) + 6;
+ if(options)
+ free(options);
options = (char *)malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */);
if(options == NULL) {
@@ -1236,14 +1245,11 @@ mount_retry:
}
}
default:
-
printf("mount error %d = %s\n",errno,strerror(errno));
}
printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
- if(mountpassword) {
- memset(mountpassword,0,64);
- }
- return -1;
+ rc = -1;
+ goto mount_exit;
} else {
pmntfile = setmntent(MOUNTED, "a+");
if(pmntfile) {
@@ -1273,7 +1279,7 @@ mount_retry:
strcat(mountent.mnt_opts,",user=");
strcat(mountent.mnt_opts,mount_user);
}
- free(mount_user);
+ /* free(mount_user); do not free static mem */
}
}
mountent.mnt_freq = 0;
@@ -1286,6 +1292,8 @@ mount_retry:
printf("could not update mount table\n");
}
}
+ rc = 0;
+mount_exit:
if(mountpassword) {
int len = strlen(mountpassword);
memset(mountpassword,0,len);
@@ -1308,6 +1316,6 @@ mount_retry:
if(free_share_name) {
free(share_name);
}
- return 0;
+ return rc;
}
diff --git a/source/configure.in b/source/configure.in
index fd728289d7b..f16766e0510 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -1936,6 +1936,14 @@ if test x"$samba_cv_compiler_supports_ll" = x"yes"; then
fi
+AC_CACHE_CHECK([for 64 bit time_t],samba_cv_SIZEOF_TIME_T,[
+AC_TRY_RUN([#include <time.h>
+main() { exit((sizeof(time_t) == 8) ? 0 : 1); }],
+samba_cv_SIZEOF_TIME_T=yes,samba_cv_SIZEOF_TIME_T=no,samba_cv_SIZEOF_TIME_T=cross)])
+if test x"$samba_cv_SIZEOF_TIME_T" = x"yes"; then
+ AC_DEFINE(SIZEOF_TIME_T,8,[The size of the 'time_t' type])
+fi
+
AC_CACHE_CHECK([for 64 bit off_t],samba_cv_SIZEOF_OFF_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
@@ -2107,13 +2115,13 @@ if test x"$samba_cv_HAVE_FUNCTION_MACRO" = x"yes"; then
fi
AC_CACHE_CHECK([if gettimeofday takes tz argument],samba_cv_HAVE_GETTIMEOFDAY_TZ,[
-AC_TRY_RUN([
+AC_TRY_LINK([
#include <sys/time.h>
-#include <unistd.h>
-main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
- samba_cv_HAVE_GETTIMEOFDAY_TZ=yes,samba_cv_HAVE_GETTIMEOFDAY_TZ=no,samba_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
+#include <unistd.h>], [struct timeval tv; return gettimeofday(&tv, NULL);],
+ samba_cv_HAVE_GETTIMEOFDAY_TZ=yes,
+ samba_cv_HAVE_GETTIMEOFDAY_TZ=no)])
if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
- AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday() is available])
+ AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday takes a tz argument])
fi
if test x"$samba_cv_WITH_PROFILE" = x"yes"; then
@@ -2538,13 +2546,13 @@ if test x$enable_fam != xno; then
# On IRIX, libfam requires libC, but other FAM implementations
# might not need it.
AC_CHECK_LIB(fam, FAMOpen2,
- [samba_cv_HAVE_LIBFAM=yes; samba_fam_libs="-lfam"],
+ [samba_cv_HAVE_LIBFAM=yes; SMB_FAM_LIBS="-lfam"],
[samba_cv_HAVE_LIBFAM=no])
if test x"$samba_cv_HAVE_LIBFAM" = x"no" ; then
samba_fam_xtra=-lC
AC_CHECK_LIB_EXT(fam, samba_fam_xtra, FAMOpen2,
- [samba_cv_HAVE_LIBFAM=yes; samba_fam_libs="-lfam -lC"],
+ [samba_cv_HAVE_LIBFAM=yes; SMB_FAM_LIBS="-lfam -lC"],
[samba_cv_HAVE_LIBFAM=no])
unset samba_fam_xtra
fi
@@ -2564,6 +2572,8 @@ if test x$enable_fam != xno; then
fi
fi
+AC_SUBST(SMB_FAM_LIBS)
+
#################################################
# Check for DMAPI interfaces in libdm/libjfsdm/libxsdm
@@ -5140,6 +5150,7 @@ AC_ARG_WITH(acl-support,
AC_MSG_RESULT(Using FreeBSD posix ACLs)
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])
+ default_static_modules="$default_static_modules vfs_posixacl"
;;
*linux*)
AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
@@ -6203,7 +6214,7 @@ AC_SUBST(builddir)
# Stuff the smbd-only libraries at the end of the smbd link
# path (if we have them).
-SMBD_LIBS="$samba_fam_libs $samba_dmapi_libs"
+SMBD_LIBS="$samba_dmapi_libs"
AC_SUBST(SMBD_LIBS)
AC_OUTPUT(include/stamp-h Makefile script/findsmb smbadduser script/gen-8bit-gap.sh script/installbin.sh script/uninstallbin.sh)
diff --git a/source/include/ads.h b/source/include/ads.h
index 29df0d2f353..40942d339f8 100644
--- a/source/include/ads.h
+++ b/source/include/ads.h
@@ -321,4 +321,4 @@ typedef struct {
int val;
int critical;
} ads_control;
-#endif
+#endif /* _INCLUDE_ADS_H_ */
diff --git a/source/include/ads_cldap.h b/source/include/ads_cldap.h
index fd227c895db..77ab19a5f2f 100644
--- a/source/include/ads_cldap.h
+++ b/source/include/ads_cldap.h
@@ -58,4 +58,4 @@ struct cldap_netlogon_reply {
#define ADS_GOOD_TIMESERV 0x00000200 /* DC has hardware clock (and running time) */
#define ADS_NDNC 0x00000400 /* DomainName is non-domain NC serviced by LDAP server */
-#endif /* _INCLUDE_CLDAP_H_ */
+#endif /* _INCLUDE_ADS_CLDAP_H_ */
diff --git a/source/lib/replace/dlfcn.m4 b/source/lib/replace/dlfcn.m4
index 2d5b2c5141a..d42409ac630 100644
--- a/source/lib/replace/dlfcn.m4
+++ b/source/lib/replace/dlfcn.m4
@@ -2,17 +2,18 @@ dnl dummies provided by dlfcn.c if not available
save_LIBS="$LIBS"
LIBS=""
+libreplace_cv_dlfcn=no
AC_SEARCH_LIBS(dlopen, dl)
-if test "$ac_cv_search_dlopen" != no; then
+if test x"${ac_cv_search_dlopen}" = x"no"; then
+ libreplace_cv_dlfcn=yes
+else
AC_CHECK_HEADERS(dlfcn.h)
-
- libreplace_cv_dlfcn=no
AC_CHECK_FUNCS([dlopen dlsym dlerror dlclose],[],[libreplace_cv_dlfcn=yes])
+fi
- if test x"${libreplace_cv_dlfcn}" = x"yes";then
- LIBREPLACEOBJ="${LIBREPLACEOBJ} dlfcn.o"
- fi
+if test x"${libreplace_cv_dlfcn}" = x"yes";then
+ LIBREPLACEOBJ="${LIBREPLACEOBJ} dlfcn.o"
fi
LIBDL="$LIBS"
diff --git a/source/lib/time.c b/source/lib/time.c
index e98f8232abc..ee44f5eb134 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -95,7 +95,13 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
if (t == (time_t)-1) {
*nt = (NTTIME)-1LL;
return;
- }
+ }
+
+ if (t == TIME_T_MAX) {
+ *nt = 0x7fffffffffffffffLL;
+ return;
+ }
+
if (t == 0) {
*nt = 0;
return;
@@ -301,7 +307,9 @@ char *http_timestring(time_t t)
static fstring buf;
struct tm *tm = localtime(&t);
- if (!tm) {
+ if (t == TIME_T_MAX) {
+ slprintf(buf,sizeof(buf)-1,"never");
+ } else if (!tm) {
slprintf(buf,sizeof(buf)-1,"%ld seconds since the Epoch",(long)t);
} else {
#ifndef HAVE_STRFTIME
@@ -554,6 +562,37 @@ NTTIME timeval_to_nttime(const struct timeval *tv)
((TIME_FIXUP_CONSTANT_INT + (uint64_t)tv->tv_sec) * 1000000));
}
+/**************************************************************
+ Handle conversions between time_t and uint32, taking care to
+ preserve the "special" values.
+**************************************************************/
+
+uint32 convert_time_t_to_uint32(time_t t)
+{
+#if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
+ /* time_t is 64-bit. */
+ if (t == 0x8000000000000000LL) {
+ return 0x80000000;
+ } else if (t == 0x7FFFFFFFFFFFFFFFLL) {
+ return 0x7FFFFFFF;
+ }
+#endif
+ return (uint32)t;
+}
+
+time_t convert_uint32_to_time_t(uint32 u)
+{
+#if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
+ /* time_t is 64-bit. */
+ if (u == 0x80000000) {
+ return (time_t)0x8000000000000000LL;
+ } else if (u == 0x7FFFFFFF) {
+ return (time_t)0x7FFFFFFFFFFFFFFFLL;
+ }
+#endif
+ return (time_t)u;
+}
+
/*******************************************************************
Yield the difference between *A and *B, in seconds, ignoring leap seconds.
********************************************************************/
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index e305409b87c..e04a6385a07 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -500,7 +500,7 @@ static int
smbc_check_server(SMBCCTX * context,
SMBCSRV * server)
{
- size_t size;
+ socklen_t size;
struct sockaddr addr;
/*
@@ -4556,7 +4556,7 @@ cacl_get(SMBCCTX *context,
return -1;
}
n = strlen(p);
- } else {
+ } else if (sidstr[0] != '\0') {
n = snprintf(buf, bufsize,
",OWNER:%s", sidstr);
}
@@ -4601,7 +4601,7 @@ cacl_get(SMBCCTX *context,
return -1;
}
n = strlen(p);
- } else {
+ } else if (sidstr[0] != '\0') {
n = snprintf(buf, bufsize,
",GROUP:%s", sidstr);
}
@@ -4709,7 +4709,7 @@ cacl_get(SMBCCTX *context,
ace->access_mask);
}
}
- if (n > bufsize) {
+ if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
}
@@ -5327,7 +5327,9 @@ smbc_setxattr_ctx(SMBCCTX *context,
ipc_srv = smbc_attr_server(context, server, share,
workgroup, user, password,
&pol);
- srv->no_nt_session = True;
+ if (! ipc_srv) {
+ srv->no_nt_session = True;
+ }
} else {
ipc_srv = NULL;
}
@@ -5752,7 +5754,9 @@ smbc_removexattr_ctx(SMBCCTX *context,
ipc_srv = smbc_attr_server(context, server, share,
workgroup, user, password,
&pol);
- srv->no_nt_session = True;
+ if (! ipc_srv) {
+ srv->no_nt_session = True;
+ }
} else {
ipc_srv = NULL;
}
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 5da76a1782d..e2afa968061 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -313,7 +313,7 @@ static int lock_compare(const struct lock_struct *lck1,
****************************************************************************/
static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
- const struct lock_struct *plock, BOOL blocking_lock)
+ struct lock_struct *plock, BOOL blocking_lock)
{
unsigned int i;
files_struct *fsp = br_lck->fsp;
@@ -322,6 +322,8 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
for (i=0; i < br_lck->num_locks; i++) {
/* Do any Windows or POSIX locks conflict ? */
if (brl_conflict(&locks[i], plock)) {
+ /* Remember who blocked us. */
+ plock->context.smbpid = locks[i].context.smbpid;
return brl_lock_failed(fsp,plock,blocking_lock);
}
#if ZERO_ZERO
@@ -346,6 +348,10 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
locks,
br_lck->num_locks,
&errno_ret)) {
+
+ /* We don't know who blocked us. */
+ plock->context.smbpid = 0xFFFFFFFF;
+
if (errno_ret == EACCES || errno_ret == EAGAIN) {
return NT_STATUS_FILE_LOCK_CONFLICT;
} else {
@@ -585,7 +591,7 @@ OR
****************************************************************************/
static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
- const struct lock_struct *plock)
+ struct lock_struct *plock)
{
unsigned int i, count;
struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
@@ -629,6 +635,8 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
if (brl_conflict(curr_lock, plock)) {
/* No games with error messages. */
SAFE_FREE(tp);
+ /* Remember who blocked us. */
+ plock->context.smbpid = curr_lock->context.smbpid;
return NT_STATUS_FILE_LOCK_CONFLICT;
}
/* Just copy the Windows lock into the new array. */
@@ -640,6 +648,8 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
/* Can't block ourselves with POSIX locks. */
/* No games with error messages. */
SAFE_FREE(tp);
+ /* Remember who blocked us. */
+ plock->context.smbpid = curr_lock->context.smbpid;
return NT_STATUS_FILE_LOCK_CONFLICT;
}
@@ -669,6 +679,10 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
plock->size,
plock->lock_type,
&errno_ret)) {
+
+ /* We don't know who blocked us. */
+ plock->context.smbpid = 0xFFFFFFFF;
+
if (errno_ret == EACCES || errno_ret == EAGAIN) {
SAFE_FREE(tp);
return NT_STATUS_FILE_LOCK_CONFLICT;
@@ -729,7 +743,8 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- BOOL blocking_lock)
+ BOOL blocking_lock,
+ uint32 *psmbpid)
{
NTSTATUS ret;
struct lock_struct lock;
@@ -760,6 +775,10 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
qsort(br_lck->lock_data, (size_t)br_lck->num_locks, sizeof(lock), lock_compare);
#endif
+ /* If we're returning an error, return who blocked us. */
+ if (!NT_STATUS_IS_OK(ret) && psmbpid) {
+ *psmbpid = lock.context.smbpid;
+ }
return ret;
}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 2181fca4085..f304037bcce 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -187,7 +187,8 @@ struct byte_range_lock *do_lock(files_struct *fsp,
enum brl_type lock_type,
enum brl_flavour lock_flav,
BOOL blocking_lock,
- NTSTATUS *perr)
+ NTSTATUS *perr,
+ uint32 *plock_pid)
{
struct byte_range_lock *br_lck = NULL;
@@ -220,7 +221,8 @@ struct byte_range_lock *do_lock(files_struct *fsp,
count,
lock_type,
lock_flav,
- blocking_lock);
+ blocking_lock,
+ plock_pid);
/* blocking ie. pending, locks also count here,
* as this is an efficiency counter to avoid checking
diff --git a/source/modules/vfs_hpuxacl.c b/source/modules/vfs_hpuxacl.c
index aeb078c32dc..3885758523b 100644
--- a/source/modules/vfs_hpuxacl.c
+++ b/source/modules/vfs_hpuxacl.c
@@ -1,101 +1,1182 @@
/*
- Unix SMB/Netbios implementation.
- VFS module to get and set hpux acls
- Copyright (C) Michael Adam 2006
+ * Unix SMB/Netbios implementation.
+ * VFS module to get and set HP-UX ACLs
+ * Copyright (C) Michael Adam 2006
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
- 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 2 of the License, or
- (at your option) any later version.
+/*
+ * This module supports JFS (POSIX) ACLs on VxFS (Veritas * Filesystem).
+ * These are available on HP-UX 11.00 if JFS 3.3 is installed.
+ * On HP-UX 11i (11.11 and above) these ACLs are supported out of
+ * the box.
+ *
+ * There is another form of ACLs on HFS. These ACLs have a
+ * completely different API and their own set of userland tools.
+ * Since HFS seems to be considered deprecated, HFS acls
+ * are not supported. (They could be supported through a separate
+ * vfs-module if there is demand.)
+ */
- 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.
+/* =================================================================
+ * NOTE:
+ *
+ * The original hpux-acl code in lib/sysacls.c was based upon the
+ * solaris acl code in the same file. Now for the new modularized
+ * acl implementation, I have taken the code from vfs_solarisacls.c
+ * and did similar adaptations as were done before, essentially
+ * reusing the original internal aclsort functions.
+ * The check for the presence of the acl() call has been adopted, and
+ * a check for the presence of the aclsort() call has been added.
+ *
+ * Michael Adam <obnox@samba.org>
+ *
+ * ================================================================= */
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
#include "includes.h"
-/* prototypes for private functions first - for clarity */
+/*
+ * including standard header <sys/aclv.h>
+ *
+ * included here as a quick hack for the special HP-UX-situation:
+ *
+ * The problem is that, on HP-UX, jfs/posix acls are
+ * defined in <sys/aclv.h>, while the deprecated hfs acls
+ * are defined inside <sys/acl.h>.
+ *
+ */
+/* GROUP is defined somewhere else so undef it here... */
+#undef GROUP
+#include <sys/aclv.h>
+/* dl.h: needed to check for acl call via shl_findsym */
+#include <dl.h>
+
+typedef struct acl HPUX_ACE_T;
+typedef struct acl *HPUX_ACL_T;
+typedef int HPUX_ACL_TAG_T; /* the type of an ACL entry */
+typedef ushort HPUX_PERM_T;
+
+/* Structure to capture the count for each type of ACE.
+ * (for hpux_internal_aclsort */
+struct hpux_acl_types {
+ int n_user;
+ int n_def_user;
+ int n_user_obj;
+ int n_def_user_obj;
+
+ int n_group;
+ int n_def_group;
+ int n_group_obj;
+ int n_def_group_obj;
+
+ int n_other;
+ int n_other_obj;
+ int n_def_other_obj;
+
+ int n_class_obj;
+ int n_def_class_obj;
+
+ int n_illegal_obj;
+};
+
+/* for convenience: check if hpux acl entry is a default entry? */
+#define _IS_DEFAULT(ace) ((ace).a_type & ACL_DEFAULT)
+#define _IS_OF_TYPE(ace, type) ( \
+ (((type) == SMB_ACL_TYPE_ACCESS) && !_IS_DEFAULT(ace)) \
+ || \
+ (((type) == SMB_ACL_TYPE_DEFAULT) && _IS_DEFAULT(ace)) \
+)
+
+
+/* prototypes for private functions */
+
+static HPUX_ACL_T hpux_acl_init(int count);
+static BOOL smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
+ HPUX_ACL_T *solariacl, int *count,
+ SMB_ACL_TYPE_T type);
+static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpuxacl, int count,
+ SMB_ACL_TYPE_T type);
+static HPUX_ACL_TAG_T smb_tag_to_hpux_tag(SMB_ACL_TAG_T smb_tag);
+static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag);
+static BOOL hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
+ HPUX_ACL_T add_acl, int add_count, SMB_ACL_TYPE_T type);
+static BOOL hpux_acl_get_file(const char *name, HPUX_ACL_T *hpuxacl,
+ int *count);
+static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm);
+static HPUX_PERM_T smb_perm_to_hpux_perm(const SMB_ACL_PERM_T perm);
+#if 0
+static BOOL hpux_acl_check(HPUX_ACL_T hpux_acl, int count);
+#endif
+/* aclsort (internal) and helpers: */
+static BOOL hpux_acl_sort(HPUX_ACL_T acl, int count);
+static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp);
+static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp,
+ struct hpux_acl_types *acl_type_count);
+static void hpux_swap_acl_entries(HPUX_ACE_T *aclp0, HPUX_ACE_T *aclp1);
+static BOOL hpux_prohibited_duplicate_type(int acl_type);
+
+static BOOL hpux_acl_call_present(void);
+static BOOL hpux_aclsort_call_present(void);
+
/* public functions - the api */
SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle,
- const char *path_p,
- SMB_ACL_TYPE_T type)
+ const char *path_p,
+ SMB_ACL_TYPE_T type)
{
- errno = ENOTSUP;
- return NULL;
+ SMB_ACL_T result = NULL;
+ int count;
+ HPUX_ACL_T hpux_acl;
+
+ DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n",
+ path_p));
+
+ if(hpux_acl_call_present() == False) {
+ /* Looks like we don't have the acl() system call on HPUX.
+ * May be the system doesn't have the latest version of JFS.
+ */
+ goto done;
+ }
+
+ if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
+ DEBUG(10, ("invalid SMB_ACL_TYPE given (%d)\n", type));
+ errno = EINVAL;
+ goto done;
+ }
+
+ DEBUGADD(10, ("getting %s acl\n",
+ ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
+
+ if (!hpux_acl_get_file(path_p, &hpux_acl, &count)) {
+ goto done;
+ }
+ result = hpux_acl_to_smb_acl(hpux_acl, count, type);
+ if (result == NULL) {
+ DEBUG(10, ("conversion hpux_acl -> smb_acl failed (%s).\n",
+ strerror(errno)));
+ }
+
+ done:
+ DEBUG(10, ("hpuxacl_sys_acl_get_file %s.\n",
+ ((result == NULL) ? "failed" : "succeeded" )));
+ SAFE_FREE(hpux_acl);
+ return result;
}
+
+/*
+ * get the access ACL of a file referred to by a fd
+ */
SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
- files_struct *fsp,
- int fd)
+ files_struct *fsp,
+ int fd)
{
- errno = ENOTSUP;
- return NULL;
+ /*
+ * HPUX doesn't have the facl call. Fake it using the path.... JRA.
+ */
+ /* For all I see, the info should already be in the fsp
+ * parameter, but get it again to be safe --- necessary? */
+ files_struct *file_struct_p = file_find_fd(fd);
+ if (file_struct_p == NULL) {
+ errno = EBADF;
+ return NULL;
+ }
+ /*
+ * We know we're in the same conn context. So we
+ * can use the relative path.
+ */
+ DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to "
+ "hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n"));
+
+ return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name,
+ SMB_ACL_TYPE_ACCESS);
}
+
int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
- const char *name,
- SMB_ACL_TYPE_T type,
- SMB_ACL_T theacl)
+ const char *name,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
{
- errno = ENOTSUP;
- return -1;
+ int ret = -1;
+ SMB_STRUCT_STAT s;
+ HPUX_ACL_T hpux_acl;
+ int count;
+
+ DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
+ name));
+
+
+ if(hpux_acl_call_present() == False) {
+ /* Looks like we don't have the acl() system call on HPUX.
+ * May be the system doesn't have the latest version of JFS.
+ */
+ goto done;
+ }
+
+ if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT)) {
+ errno = EINVAL;
+ DEBUG(10, ("invalid smb acl type given (%d).\n", type));
+ goto done;
+ }
+ DEBUGADD(10, ("setting %s acl\n",
+ ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
+
+ if(!smb_acl_to_hpux_acl(theacl, &hpux_acl, &count, type)) {
+ DEBUG(10, ("conversion smb_acl -> hpux_acl failed (%s).\n",
+ strerror(errno)));
+ goto done;
+ }
+
+ /*
+ * if the file is a directory, there is extra work to do:
+ * since the hpux acl call stores both the access acl and
+ * the default acl as provided, we have to get the acl part
+ * that has _not_ been specified in "type" from the file first
+ * and concatenate it with the acl provided.
+ */
+ if (SMB_VFS_STAT(handle->conn, name, &s) != 0) {
+ DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
+ goto done;
+ }
+ if (S_ISDIR(s.st_mode)) {
+ HPUX_ACL_T other_acl;
+ int other_count;
+ SMB_ACL_TYPE_T other_type;
+
+ other_type = (type == SMB_ACL_TYPE_ACCESS)
+ ? SMB_ACL_TYPE_DEFAULT
+ : SMB_ACL_TYPE_ACCESS;
+ DEBUGADD(10, ("getting acl from filesystem\n"));
+ if (!hpux_acl_get_file(name, &other_acl, &other_count)) {
+ DEBUG(10, ("error getting acl from directory\n"));
+ goto done;
+ }
+ DEBUG(10, ("adding %s part of fs acl to given acl\n",
+ ((other_type == SMB_ACL_TYPE_ACCESS)
+ ? "access"
+ : "default")));
+ if (!hpux_add_to_acl(&hpux_acl, &count, other_acl,
+ other_count, other_type))
+ {
+ DEBUG(10, ("error adding other acl.\n"));
+ SAFE_FREE(other_acl);
+ goto done;
+ }
+ SAFE_FREE(other_acl);
+ }
+ else if (type != SMB_ACL_TYPE_ACCESS) {
+ errno = EINVAL;
+ goto done;
+ }
+
+ if (!hpux_acl_sort(hpux_acl, count)) {
+ DEBUG(10, ("resulting acl is not valid!\n"));
+ goto done;
+ }
+ DEBUG(10, ("resulting acl is valid.\n"));
+
+ ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl);
+ if (ret != 0) {
+ DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
+ }
+
+ done:
+ DEBUG(10, ("hpuxacl_sys_acl_set_file %s.\n",
+ ((ret != 0) ? "failed" : "succeeded")));
+ SAFE_FREE(hpux_acl);
+ return ret;
}
+/*
+ * set the access ACL on the file referred to by a fd
+ */
int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle,
- files_struct *fsp,
- int fd, SMB_ACL_T theacl)
+ files_struct *fsp,
+ int fd, SMB_ACL_T theacl)
{
- errno = ENOTSUP;
- return -1;
+ /*
+ * HPUX doesn't have the facl call. Fake it using the path.... JRA.
+ */
+ /* For all I see, the info should already be in the fsp
+ * parameter, but get it again to be safe --- necessary? */
+ files_struct *file_struct_p = file_find_fd(fd);
+ if (file_struct_p == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+ /*
+ * We know we're in the same conn context. So we
+ * can use the relative path.
+ */
+ DEBUG(10, ("redirecting call of hpuxacl_sys_acl_set_fd to "
+ "hpuxacl_sys_acl_set_file (no facl syscall on HPUX)\n"));
+
+ return hpuxacl_sys_acl_set_file(handle, file_struct_p->fsp_name,
+ SMB_ACL_TYPE_ACCESS, theacl);
}
+
+/*
+ * delete the default ACL of a directory
+ *
+ * This is achieved by fetching the access ACL and rewriting it
+ * directly, via the hpux system call: the ACL_SET call on
+ * directories writes both the access and the default ACL as provided.
+ *
+ * XXX: posix acl_delete_def_file returns an error if
+ * the file referred to by path is not a directory.
+ * this function does not complain but the actions
+ * have no effect on a file other than a directory.
+ * But sys_acl_delete_default_file is only called in
+ * smbd/posixacls.c after having checked that the file
+ * is a directory, anyways. So implementing the extra
+ * check is considered unnecessary. --- Agreed? XXX
+ */
int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
- const char *path)
+ const char *path)
+{
+ SMB_ACL_T smb_acl;
+ int ret = -1;
+ HPUX_ACL_T hpux_acl;
+ int count;
+
+ DEBUG(10, ("entering hpuxacl_sys_acl_delete_def_file.\n"));
+
+ smb_acl = hpuxacl_sys_acl_get_file(handle, path,
+ SMB_ACL_TYPE_ACCESS);
+ if (smb_acl == NULL) {
+ DEBUG(10, ("getting file acl failed!\n"));
+ goto done;
+ }
+ if (!smb_acl_to_hpux_acl(smb_acl, &hpux_acl, &count,
+ SMB_ACL_TYPE_ACCESS))
+ {
+ DEBUG(10, ("conversion smb_acl -> hpux_acl failed.\n"));
+ goto done;
+ }
+ if (!hpux_acl_sort(hpux_acl, count)) {
+ DEBUG(10, ("resulting acl is not valid!\n"));
+ goto done;
+ }
+ ret = acl(CONST_DISCARD(char *, path), ACL_SET, count, hpux_acl);
+ if (ret != 0) {
+ DEBUG(10, ("settinge file acl failed!\n"));
+ }
+
+ done:
+ DEBUG(10, ("hpuxacl_sys_acl_delete_def_file %s.\n",
+ ((ret != 0) ? "failed" : "succeeded" )));
+ SAFE_FREE(smb_acl);
+ return ret;
+}
+
+
+/*
+ * private functions
+ */
+
+static HPUX_ACL_T hpux_acl_init(int count)
{
- errno = ENOTSUP;
- return -1;
+ HPUX_ACL_T hpux_acl =
+ (HPUX_ACL_T)SMB_MALLOC(sizeof(HPUX_ACE_T) * count);
+ if (hpux_acl == NULL) {
+ errno = ENOMEM;
+ }
+ return hpux_acl;
}
-/* private functions */
+/*
+ * Convert the SMB acl to the ACCESS or DEFAULT part of a
+ * hpux ACL, as desired.
+ */
+static BOOL smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
+ HPUX_ACL_T *hpux_acl, int *count,
+ SMB_ACL_TYPE_T type)
+{
+ BOOL ret = False;
+ int i;
+ int check_which, check_rc;
+
+ DEBUG(10, ("entering smb_acl_to_hpux_acl\n"));
+
+ *hpux_acl = NULL;
+ *count = 0;
+
+ for (i = 0; i < smb_acl->count; i++) {
+ const struct smb_acl_entry *smb_entry = &(smb_acl->acl[i]);
+ HPUX_ACE_T hpux_entry;
+
+ ZERO_STRUCT(hpux_entry);
+
+ hpux_entry.a_type = smb_tag_to_hpux_tag(smb_entry->a_type);
+ if (hpux_entry.a_type == 0) {
+ DEBUG(10, ("smb_tag to hpux_tag failed\n"));
+ goto fail;
+ }
+ switch(hpux_entry.a_type) {
+ case USER:
+ DEBUG(10, ("got tag type USER with uid %d\n",
+ smb_entry->uid));
+ hpux_entry.a_id = (uid_t)smb_entry->uid;
+ break;
+ case GROUP:
+ DEBUG(10, ("got tag type GROUP with gid %d\n",
+ smb_entry->gid));
+ hpux_entry.a_id = (uid_t)smb_entry->gid;
+ break;
+ default:
+ break;
+ }
+ if (type == SMB_ACL_TYPE_DEFAULT) {
+ DEBUG(10, ("adding default bit to hpux ace\n"));
+ hpux_entry.a_type |= ACL_DEFAULT;
+ }
+
+ hpux_entry.a_perm =
+ smb_perm_to_hpux_perm(smb_entry->a_perm);
+ DEBUG(10, ("assembled the following hpux ace:\n"));
+ DEBUGADD(10, (" - type: 0x%04x\n", hpux_entry.a_type));
+ DEBUGADD(10, (" - id: %d\n", hpux_entry.a_id));
+ DEBUGADD(10, (" - perm: o%o\n", hpux_entry.a_perm));
+ if (!hpux_add_to_acl(hpux_acl, count, &hpux_entry,
+ 1, type))
+ {
+ DEBUG(10, ("error adding acl entry\n"));
+ goto fail;
+ }
+ DEBUG(10, ("count after adding: %d (i: %d)\n", *count, i));
+ DEBUG(10, ("test, if entry has been copied into acl:\n"));
+ DEBUGADD(10, (" - type: 0x%04x\n",
+ (*hpux_acl)[(*count)-1].a_type));
+ DEBUGADD(10, (" - id: %d\n",
+ (*hpux_acl)[(*count)-1].a_id));
+ DEBUGADD(10, (" - perm: o%o\n",
+ (*hpux_acl)[(*count)-1].a_perm));
+ }
+
+ ret = True;
+ goto done;
+
+ fail:
+ SAFE_FREE(*hpux_acl);
+ done:
+ DEBUG(10, ("smb_acl_to_hpux_acl %s\n",
+ ((ret == True) ? "succeeded" : "failed")));
+ return ret;
+}
+
+/*
+ * convert either the access or the default part of a
+ * soaris acl to the SMB_ACL format.
+ */
+static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count,
+ SMB_ACL_TYPE_T type)
+{
+ SMB_ACL_T result;
+ int i;
+
+ if ((result = sys_acl_init(0)) == NULL) {
+ DEBUG(10, ("error allocating memory for SMB_ACL\n"));
+ goto fail;
+ }
+ for (i = 0; i < count; i++) {
+ SMB_ACL_ENTRY_T smb_entry;
+ SMB_ACL_PERM_T smb_perm;
+
+ if (!_IS_OF_TYPE(hpux_acl[i], type)) {
+ continue;
+ }
+ result = SMB_REALLOC(result,
+ sizeof(struct smb_acl_t) +
+ (sizeof(struct smb_acl_entry) *
+ (result->count + 1)));
+ if (result == NULL) {
+ DEBUG(10, ("error reallocating memory for SMB_ACL\n"));
+ goto fail;
+ }
+ smb_entry = &result->acl[result->count];
+ if (sys_acl_set_tag_type(smb_entry,
+ hpux_tag_to_smb_tag(hpux_acl[i].a_type)) != 0)
+ {
+ DEBUG(10, ("invalid tag type given: 0x%04x\n",
+ hpux_acl[i].a_type));
+ goto fail;
+ }
+ /* intentionally not checking return code here: */
+ sys_acl_set_qualifier(smb_entry, (void *)&hpux_acl[i].a_id);
+ smb_perm = hpux_perm_to_smb_perm(hpux_acl[i].a_perm);
+ if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) {
+ DEBUG(10, ("invalid permset given: %d\n",
+ hpux_acl[i].a_perm));
+ goto fail;
+ }
+ result->count += 1;
+ }
+ goto done;
+
+ fail:
+ SAFE_FREE(result);
+ done:
+ DEBUG(10, ("hpux_acl_to_smb_acl %s\n",
+ ((result == NULL) ? "failed" : "succeeded")));
+ return result;
+}
+
+
+
+static HPUX_ACL_TAG_T smb_tag_to_hpux_tag(SMB_ACL_TAG_T smb_tag)
+{
+ HPUX_ACL_TAG_T hpux_tag = 0;
+
+ DEBUG(10, ("smb_tag_to_hpux_tag\n"));
+ DEBUGADD(10, (" --> got smb tag 0x%04x\n", smb_tag));
+
+ switch (smb_tag) {
+ case SMB_ACL_USER:
+ hpux_tag = USER;
+ break;
+ case SMB_ACL_USER_OBJ:
+ hpux_tag = USER_OBJ;
+ break;
+ case SMB_ACL_GROUP:
+ hpux_tag = GROUP;
+ break;
+ case SMB_ACL_GROUP_OBJ:
+ hpux_tag = GROUP_OBJ;
+ break;
+ case SMB_ACL_OTHER:
+ hpux_tag = OTHER_OBJ;
+ break;
+ case SMB_ACL_MASK:
+ hpux_tag = CLASS_OBJ;
+ break;
+ default:
+ DEBUGADD(10, (" !!! unknown smb tag type 0x%04x\n", smb_tag));
+ break;
+ }
+
+ DEBUGADD(10, (" --> determined hpux tag 0x%04x\n", hpux_tag));
+
+ return hpux_tag;
+}
+
+static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag)
+{
+ SMB_ACL_TAG_T smb_tag = 0;
+
+ DEBUG(10, ("hpux_tag_to_smb_tag:\n"));
+ DEBUGADD(10, (" --> got hpux tag 0x%04x\n", hpux_tag));
+
+ hpux_tag &= ~ACL_DEFAULT;
+
+ switch (hpux_tag) {
+ case USER:
+ smb_tag = SMB_ACL_USER;
+ break;
+ case USER_OBJ:
+ smb_tag = SMB_ACL_USER_OBJ;
+ break;
+ case GROUP:
+ smb_tag = SMB_ACL_GROUP;
+ break;
+ case GROUP_OBJ:
+ smb_tag = SMB_ACL_GROUP_OBJ;
+ break;
+ case OTHER_OBJ:
+ smb_tag = SMB_ACL_OTHER;
+ break;
+ case CLASS_OBJ:
+ smb_tag = SMB_ACL_MASK;
+ break;
+ default:
+ DEBUGADD(10, (" !!! unknown hpux tag type: 0x%04x\n",
+ hpux_tag));
+ break;
+ }
+
+ DEBUGADD(10, (" --> determined smb tag 0x%04x\n", smb_tag));
+
+ return smb_tag;
+}
+
+
+/*
+ * The permission bits used in the following two permission conversion
+ * functions are same, but the functions make us independent of the concrete
+ * permission data types.
+ */
+static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm)
+{
+ SMB_ACL_PERM_T smb_perm = 0;
+ smb_perm |= ((perm & SMB_ACL_READ) ? SMB_ACL_READ : 0);
+ smb_perm |= ((perm & SMB_ACL_WRITE) ? SMB_ACL_WRITE : 0);
+ smb_perm |= ((perm & SMB_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
+ return smb_perm;
+}
+
+
+static HPUX_PERM_T smb_perm_to_hpux_perm(const SMB_ACL_PERM_T perm)
+{
+ HPUX_PERM_T hpux_perm = 0;
+ hpux_perm |= ((perm & SMB_ACL_READ) ? SMB_ACL_READ : 0);
+ hpux_perm |= ((perm & SMB_ACL_WRITE) ? SMB_ACL_WRITE : 0);
+ hpux_perm |= ((perm & SMB_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
+ return hpux_perm;
+}
+
+
+static BOOL hpux_acl_get_file(const char *name, HPUX_ACL_T *hpux_acl,
+ int *count)
+{
+ BOOL result = False;
+ static HPUX_ACE_T dummy_ace;
+
+ DEBUG(10, ("hpux_acl_get_file called for file '%s'\n", name));
+
+ /*
+ * The original code tries some INITIAL_ACL_SIZE
+ * and only did the ACL_CNT call upon failure
+ * (for performance reasons).
+ * For the sake of simplicity, I skip this for now.
+ *
+ * NOTE: There is a catch here on HP-UX: acl with cmd parameter
+ * ACL_CNT fails with errno EINVAL when called with a NULL
+ * pointer as last argument. So we need to use a dummy acl
+ * struct here (we make it static so it does not need to be
+ * instantiated or malloced each time this function is
+ * called). Btw: the count parameter does not seem to matter...
+ */
+ *count = acl(CONST_DISCARD(char *, name), ACL_CNT, 0, &dummy_ace);
+ if (*count < 0) {
+ DEBUG(10, ("acl ACL_CNT failed: %s\n", strerror(errno)));
+ goto done;
+ }
+ *hpux_acl = hpux_acl_init(*count);
+ if (*hpux_acl == NULL) {
+ DEBUG(10, ("error allocating memory for hpux acl...\n"));
+ goto done;
+ }
+ *count = acl(CONST_DISCARD(char *, name), ACL_GET, *count, *hpux_acl);
+ if (*count < 0) {
+ DEBUG(10, ("acl ACL_GET failed: %s\n", strerror(errno)));
+ goto done;
+ }
+ result = True;
+
+ done:
+ DEBUG(10, ("hpux_acl_get_file %s.\n",
+ ((result == True) ? "succeeded" : "failed" )));
+ return result;
+}
+
+
+
+
+/*
+ * Add entries to a hpux ACL.
+ *
+ * Entries are directly added to the hpuxacl parameter.
+ * if memory allocation fails, this may result in hpuxacl
+ * being NULL. if the resulting acl is to be checked and is
+ * not valid, it is kept in hpuxacl but False is returned.
+ *
+ * The type of ACEs (access/default) to be added to the ACL can
+ * be selected via the type parameter.
+ * I use the SMB_ACL_TYPE_T type here. Since SMB_ACL_TYPE_ACCESS
+ * is defined as "0", this means that one can only add either
+ * access or default ACEs from the given ACL, not both at the same
+ * time. If it should become necessary to add all of an ACL, one
+ * would have to replace this parameter by another type.
+ */
+static BOOL hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
+ HPUX_ACL_T add_acl, int add_count,
+ SMB_ACL_TYPE_T type)
+{
+ int i;
+
+ if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
+ {
+ DEBUG(10, ("invalid acl type given: %d\n", type));
+ errno = EINVAL;
+ return False;
+ }
+ for (i = 0; i < add_count; i++) {
+ if (!_IS_OF_TYPE(add_acl[i], type)) {
+ continue;
+ }
+ ADD_TO_ARRAY(NULL, HPUX_ACE_T, add_acl[i],
+ hpux_acl, count);
+ if (hpux_acl == NULL) {
+ DEBUG(10, ("error enlarging acl.\n"));
+ errno = ENOMEM;
+ return False;
+ }
+ }
+ return True;
+}
+
+
+/*
+ * sort the ACL and check it for validity
+ *
+ * [original comment from lib/sysacls.c:]
+ *
+ * if it's a minimal ACL with only 4 entries then we
+ * need to recalculate the mask permissions to make
+ * sure that they are the same as the GROUP_OBJ
+ * permissions as required by the UnixWare acl() system call.
+ *
+ * (note: since POSIX allows minimal ACLs which only contain
+ * 3 entries - ie there is no mask entry - we should, in theory,
+ * check for this and add a mask entry if necessary - however
+ * we "know" that the caller of this interface always specifies
+ * a mask, so in practice "this never happens" (tm) - if it *does*
+ * happen aclsort() will fail and return an error and someone will
+ * have to fix it...)
+ */
+static BOOL hpux_acl_sort(HPUX_ACL_T hpux_acl, int count)
+{
+ int fixmask = (count <= 4);
+
+ if (hpux_internal_aclsort(count, fixmask, hpux_acl) != 0) {
+ errno = EINVAL;
+ return False;
+ }
+ return True;
+}
+
+
+/*
+ * Helpers for hpux_internal_aclsort:
+ * - hpux_count_obj
+ * - hpux_swap_acl_entries
+ * - hpux_prohibited_duplicate_type
+ * - hpux_get_needed_class_perm
+ */
+
+/* hpux_count_obj:
+ * Counts the different number of objects in a given array of ACL
+ * structures.
+ * Inputs:
+ *
+ * acl_count - Count of ACLs in the array of ACL strucutres.
+ * aclp - Array of ACL structures.
+ * acl_type_count - Pointer to acl_types structure. Should already be
+ * allocated.
+ * Output:
+ *
+ * acl_type_count - This structure is filled up with counts of various
+ * acl types.
+ */
+
+static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp, struct hpux_acl_types *acl_type_count)
+{
+ int i;
+
+ memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
+
+ for(i=0;i<acl_count;i++) {
+ switch(aclp[i].a_type) {
+ case USER:
+ acl_type_count->n_user++;
+ break;
+ case USER_OBJ:
+ acl_type_count->n_user_obj++;
+ break;
+ case DEF_USER_OBJ:
+ acl_type_count->n_def_user_obj++;
+ break;
+ case GROUP:
+ acl_type_count->n_group++;
+ break;
+ case GROUP_OBJ:
+ acl_type_count->n_group_obj++;
+ break;
+ case DEF_GROUP_OBJ:
+ acl_type_count->n_def_group_obj++;
+ break;
+ case OTHER_OBJ:
+ acl_type_count->n_other_obj++;
+ break;
+ case DEF_OTHER_OBJ:
+ acl_type_count->n_def_other_obj++;
+ break;
+ case CLASS_OBJ:
+ acl_type_count->n_class_obj++;
+ break;
+ case DEF_CLASS_OBJ:
+ acl_type_count->n_def_class_obj++;
+ break;
+ case DEF_USER:
+ acl_type_count->n_def_user++;
+ break;
+ case DEF_GROUP:
+ acl_type_count->n_def_group++;
+ break;
+ default:
+ acl_type_count->n_illegal_obj++;
+ break;
+ }
+ }
+}
+
+/* hpux_swap_acl_entries: Swaps two ACL entries.
+ *
+ * Inputs: aclp0, aclp1 - ACL entries to be swapped.
+ */
+
+static void hpux_swap_acl_entries(HPUX_ACE_T *aclp0, HPUX_ACE_T *aclp1)
+{
+ HPUX_ACE_T temp_acl;
+
+ temp_acl.a_type = aclp0->a_type;
+ temp_acl.a_id = aclp0->a_id;
+ temp_acl.a_perm = aclp0->a_perm;
+
+ aclp0->a_type = aclp1->a_type;
+ aclp0->a_id = aclp1->a_id;
+ aclp0->a_perm = aclp1->a_perm;
+
+ aclp1->a_type = temp_acl.a_type;
+ aclp1->a_id = temp_acl.a_id;
+ aclp1->a_perm = temp_acl.a_perm;
+}
+
+/* hpux_prohibited_duplicate_type
+ * Identifies if given ACL type can have duplicate entries or
+ * not.
+ *
+ * Inputs: acl_type - ACL Type.
+ *
+ * Outputs:
+ *
+ * Return..
+ *
+ * True - If the ACL type matches any of the prohibited types.
+ * False - If the ACL type doesn't match any of the prohibited types.
+ */
+
+static BOOL hpux_prohibited_duplicate_type(int acl_type)
+{
+ switch(acl_type) {
+ case USER:
+ case GROUP:
+ case DEF_USER:
+ case DEF_GROUP:
+ return True;
+ default:
+ return False;
+ }
+}
+
+/* hpux_get_needed_class_perm
+ * Returns the permissions of a ACL structure only if the ACL
+ * type matches one of the pre-determined types for computing
+ * CLASS_OBJ permissions.
+ *
+ * Inputs: aclp - Pointer to ACL structure.
+ */
+
+static int hpux_get_needed_class_perm(struct acl *aclp)
+{
+ switch(aclp->a_type) {
+ case USER:
+ case GROUP_OBJ:
+ case GROUP:
+ case DEF_USER_OBJ:
+ case DEF_USER:
+ case DEF_GROUP_OBJ:
+ case DEF_GROUP:
+ case DEF_CLASS_OBJ:
+ case DEF_OTHER_OBJ:
+ return aclp->a_perm;
+ default:
+ return 0;
+ }
+}
+
+/* hpux_internal_aclsort: aclsort for HPUX.
+ *
+ * -> The aclsort() system call is availabe on the latest HPUX General
+ * -> Patch Bundles. So for HPUX, we developed our version of aclsort
+ * -> function. Because, we don't want to update to a new
+ * -> HPUX GR bundle just for aclsort() call.
+ *
+ * aclsort sorts the array of ACL structures as per the description in
+ * aclsort man page. Refer to aclsort man page for more details
+ *
+ * Inputs:
+ *
+ * acl_count - Count of ACLs in the array of ACL structures.
+ * calclass - If this is not zero, then we compute the CLASS_OBJ
+ * permissions.
+ * aclp - Array of ACL structures.
+ *
+ * Outputs:
+ *
+ * aclp - Sorted array of ACL structures.
+ *
+ * Outputs:
+ *
+ * Returns 0 for success -1 for failure. Prints a message to the Samba
+ * debug log in case of failure.
+ */
+
+static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp)
+{
+ struct hpux_acl_types acl_obj_count;
+ int n_class_obj_perm = 0;
+ int i, j;
+
+ DEBUG(10,("Entering hpux_internal_aclsort. (calclass = %d)\n", calclass));
+
+ if (hpux_aclsort_call_present()) {
+ DEBUG(10, ("calling hpux aclsort\n"));
+ return aclsort(acl_count, calclass, aclp);
+ }
+
+ DEBUG(10, ("using internal aclsort\n"));
+
+ if(!acl_count) {
+ DEBUG(10,("Zero acl count passed. Returning Success\n"));
+ return 0;
+ }
+
+ if(aclp == NULL) {
+ DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
+ return -1;
+ }
+
+ /* Count different types of ACLs in the ACLs array */
+
+ hpux_count_obj(acl_count, aclp, &acl_obj_count);
+
+ /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
+ * CLASS_OBJ and OTHER_OBJ
+ */
+
+ if ( (acl_obj_count.n_user_obj != 1) ||
+ (acl_obj_count.n_group_obj != 1) ||
+ (acl_obj_count.n_class_obj != 1) ||
+ (acl_obj_count.n_other_obj != 1) )
+ {
+ DEBUG(0,("hpux_internal_aclsort: More than one entry or no entries for \
+USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
+ return -1;
+ }
+
+ /* If any of the default objects are present, there should be only
+ * one of them each.
+ */
+
+ if ( (acl_obj_count.n_def_user_obj > 1) ||
+ (acl_obj_count.n_def_group_obj > 1) ||
+ (acl_obj_count.n_def_other_obj > 1) ||
+ (acl_obj_count.n_def_class_obj > 1) )
+ {
+ DEBUG(0,("hpux_internal_aclsort: More than one entry for DEF_CLASS_OBJ \
+or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
+ return -1;
+ }
+
+ /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
+ * structures.
+ *
+ * Sorting crieteria - First sort by ACL type. If there are multiple entries of
+ * same ACL type, sort by ACL id.
+ *
+ * I am using the trival kind of sorting method here because, performance isn't
+ * really effected by the ACLs feature. More over there aren't going to be more
+ * than 17 entries on HPUX.
+ */
+
+ for(i=0; i<acl_count;i++) {
+ for (j=i+1; j<acl_count; j++) {
+ if( aclp[i].a_type > aclp[j].a_type ) {
+ /* ACL entries out of order, swap them */
+ hpux_swap_acl_entries((aclp+i), (aclp+j));
+ } else if ( aclp[i].a_type == aclp[j].a_type ) {
+ /* ACL entries of same type, sort by id */
+ if(aclp[i].a_id > aclp[j].a_id) {
+ hpux_swap_acl_entries((aclp+i), (aclp+j));
+ } else if (aclp[i].a_id == aclp[j].a_id) {
+ /* We have a duplicate entry. */
+ if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
+ DEBUG(0, ("hpux_internal_aclsort: Duplicate entry: Type(hex): %x Id: %d\n",
+ aclp[i].a_type, aclp[i].a_id));
+ return -1;
+ }
+ }
+ }
+ }
+ }
+
+ /* set the class obj permissions to the computed one. */
+ if(calclass) {
+ int n_class_obj_index = -1;
+
+ for(i=0;i<acl_count;i++) {
+ n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
+
+ if(aclp[i].a_type == CLASS_OBJ)
+ n_class_obj_index = i;
+ }
+ aclp[n_class_obj_index].a_perm = n_class_obj_perm;
+ }
+
+ return 0;
+}
+
+
+/*
+ * hpux_acl_call_present:
+ *
+ * This checks if the POSIX ACL system call is defined
+ * which basically corresponds to whether JFS 3.3 or
+ * higher is installed. If acl() was called when it
+ * isn't defined, it causes the process to core dump
+ * so it is important to check this and avoid acl()
+ * calls if it isn't there.
+ */
+
+static BOOL hpux_acl_call_present(void)
+{
+
+ shl_t handle = NULL;
+ void *value;
+ int ret_val=0;
+ static BOOL already_checked = False;
+
+ if(already_checked)
+ return True;
+
+ errno = 0;
+
+ ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
+
+ if(ret_val != 0) {
+ DEBUG(5, ("hpux_acl_call_present: shl_findsym() returned %d, errno = %d, error %s\n",
+ ret_val, errno, strerror(errno)));
+ DEBUG(5,("hpux_acl_call_present: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
+ errno = ENOSYS;
+ return False;
+ }
+
+ DEBUG(10,("hpux_acl_call_present: acl() system call is present. We have JFS 3.3 or above \n"));
+
+ already_checked = True;
+ return True;
+}
+
+/*
+ * runtime check for presence of aclsort library call.
+ * same code as for acl call. if there are more of these,
+ * a dispatcher function could be handy...
+ */
+
+static BOOL hpux_aclsort_call_present(void)
+{
+ shl_t handle = NULL;
+ void *value;
+ int ret_val = 0;
+ static BOOL already_checked = False;
+
+ if (already_checked) {
+ return True;
+ }
+
+ errno = 0;
+ ret_val = shl_findsym(&handle, "aclsort", TYPE_PROCEDURE, &value);
+ if (ret_val != 0) {
+ DEBUG(5, ("hpux_aclsort_call_present: shl_findsym "
+ "returned %d, errno = %d, error %s",
+ ret_val, errno, strerror(errno)));
+ DEBUG(5, ("hpux_aclsort_call_present: "
+ "aclsort() function not available.\n"));
+ return False;
+ }
+ DEBUG(10,("hpux_aclsort_call_present: aclsort() function present.\n"));
+ already_checked = True;
+ return True;
+}
+
+#if 0
+/*
+ * acl check function:
+ * unused at the moment but could be used to get more
+ * concrete error messages for debugging...
+ * (acl sort just says that the acl is invalid...)
+ */
+static BOOL hpux_acl_check(HPUX_ACL_T hpux_acl, int count)
+{
+ int check_rc;
+ int check_which;
+
+ check_rc = aclcheck(hpux_acl, count, &check_which);
+ if (check_rc != 0) {
+ DEBUG(10, ("acl is not valid:\n"));
+ DEBUGADD(10, (" - return code: %d\n", check_rc));
+ DEBUGADD(10, (" - which: %d\n", check_which));
+ if (check_which != -1) {
+ DEBUGADD(10, (" - invalid entry:\n"));
+ DEBUGADD(10, (" * type: %d:\n",
+ hpux_acl[check_which].a_type));
+ DEBUGADD(10, (" * id: %d\n",
+ hpux_acl[check_which].a_id));
+ DEBUGADD(10, (" * perm: 0o%o\n",
+ hpux_acl[check_which].a_perm));
+ }
+ return False;
+ }
+ return True;
+}
+#endif
/* VFS operations structure */
static vfs_op_tuple hpuxacl_op_tuples[] = {
/* Disk operations */
- {SMB_VFS_OP(hpuxacl_sys_acl_get_file),
- SMB_VFS_OP_SYS_ACL_GET_FILE,
- SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(hpuxacl_sys_acl_get_file),
+ SMB_VFS_OP_SYS_ACL_GET_FILE,
+ SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(hpuxacl_sys_acl_get_fd),
- SMB_VFS_OP_SYS_ACL_GET_FD,
- SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(hpuxacl_sys_acl_get_fd),
+ SMB_VFS_OP_SYS_ACL_GET_FD,
+ SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(hpuxacl_sys_acl_set_file),
- SMB_VFS_OP_SYS_ACL_SET_FILE,
- SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(hpuxacl_sys_acl_set_file),
+ SMB_VFS_OP_SYS_ACL_SET_FILE,
+ SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(hpuxacl_sys_acl_set_fd),
- SMB_VFS_OP_SYS_ACL_SET_FD,
- SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(hpuxacl_sys_acl_set_fd),
+ SMB_VFS_OP_SYS_ACL_SET_FD,
+ SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(hpuxacl_sys_acl_delete_def_file),
- SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
- SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(hpuxacl_sys_acl_delete_def_file),
+ SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
+ SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL),
- SMB_VFS_OP_NOOP,
- SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL),
+ SMB_VFS_OP_NOOP,
+ SMB_VFS_LAYER_NOOP}
};
-NTSTATUS vfs_hpuxacl_init(void);
NTSTATUS vfs_hpuxacl_init(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "hpuxacl",
diff --git a/source/modules/vfs_posixacl.c b/source/modules/vfs_posixacl.c
index 191c4a7cb0e..109c1e20b2e 100644
--- a/source/modules/vfs_posixacl.c
+++ b/source/modules/vfs_posixacl.c
@@ -200,9 +200,15 @@ static BOOL smb_ace_to_internal(acl_entry_t posix_ace,
return False;
}
ace->a_perm = 0;
+#ifdef HAVE_ACL_GET_PERM_NP
+ ace->a_perm |= (acl_get_perm_np(permset, ACL_READ) ? SMB_ACL_READ : 0);
+ ace->a_perm |= (acl_get_perm_np(permset, ACL_WRITE) ? SMB_ACL_WRITE : 0);
+ ace->a_perm |= (acl_get_perm_np(permset, ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
+#else
ace->a_perm |= (acl_get_perm(permset, ACL_READ) ? SMB_ACL_READ : 0);
ace->a_perm |= (acl_get_perm(permset, ACL_WRITE) ? SMB_ACL_WRITE : 0);
ace->a_perm |= (acl_get_perm(permset, ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
+#endif
return True;
}
diff --git a/source/modules/vfs_tru64acl.c b/source/modules/vfs_tru64acl.c
index 6aa9557c28c..0c2de36911f 100644
--- a/source/modules/vfs_tru64acl.c
+++ b/source/modules/vfs_tru64acl.c
@@ -28,8 +28,8 @@ static BOOL tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag);
-static acl_perm_t smb_permset_to_tru64(smb_acl_permset_t smb_permset);
-static smb_acl_permset_t tru64_permset_to_smb(const acl_perm_t tru64_permset);
+static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset);
+static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
/* public functions - the api */
@@ -201,7 +201,7 @@ static BOOL tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
acl_tag_t tru64_tag;
acl_permset_t permset;
SMB_ACL_TAG_T smb_tag_type;
- smb_acl_permset_t smb_permset;
+ SMB_ACL_PERM_T smb_permset;
void *qualifier;
if (acl_get_tag_type(tru64_ace, &tru64_tag) != 0) {
@@ -437,7 +437,7 @@ static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag)
return smb_tag_type;
}
-static acl_perm_t smb_permset_to_tru64(smb_acl_permset_t smb_permset)
+static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset)
{
/* originally, I thought that acl_clear_perm was the
* proper way to reset the permset to 0. but without
@@ -456,9 +456,9 @@ static acl_perm_t smb_permset_to_tru64(smb_acl_permset_t smb_permset)
return tru64_permset;
}
-static smb_acl_permset_t tru64_permset_to_smb(const acl_perm_t tru64_permset)
+static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset)
{
- smb_acl_permset_t smb_permset = 0;
+ SMB_ACL_PERM_T smb_permset = 0;
smb_permset |= ((tru64_permset & ACL_READ) ? SMB_ACL_READ : 0);
smb_permset |= ((tru64_permset & ACL_WRITE) ? SMB_ACL_WRITE : 0);
smb_permset |= ((tru64_permset & ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 1bd00869231..c7baecfbaa6 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -902,7 +902,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
{
struct getent_state *ent;
struct winbindd_gr *group_list = NULL;
- int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0;
+ int num_groups, group_list_ndx, gr_mem_list_len = 0;
char *gr_mem_list = NULL;
DEBUG(3, ("[%5lu]: getgrent\n", (unsigned long)state->pid));
@@ -916,6 +916,11 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries);
+ if (num_groups == 0) {
+ request_error(state);
+ return;
+ }
+
if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_gr, num_groups)) == NULL) {
request_error(state);
return;
@@ -938,7 +943,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
/* Start sending back groups */
- for (i = 0; i < num_groups; i++) {
+ for (group_list_ndx = 0; group_list_ndx < num_groups; ) {
struct acct_info *name_list = NULL;
fstring domain_group_name;
uint32 result;
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 6ee548292cc..589f4839e0b 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -288,7 +288,7 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
} else {
return domain;
}
- }
+ }
return find_our_domain();
}
@@ -579,6 +579,14 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
http_timestring(ticket_lifetime), (int)ticket_lifetime,
http_timestring(renewal_until), (int)renewal_until));
+ /* we cannot continue with krb5 when UF_DONT_REQUIRE_PREAUTH is set,
+ * in that case fallback to NTLM - gd */
+
+ if ((ticket_lifetime == 0) && (renewal_until == 0)) {
+ result = NT_STATUS_INVALID_LOGON_TYPE;
+ goto failed;
+ }
+
client_princ = talloc_strdup(state->mem_ctx, global_myname());
if (client_princ == NULL) {
result = NT_STATUS_NO_MEMORY;
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index ce677198fff..18797772dd4 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -631,7 +631,7 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
{
struct getent_state *ent;
struct winbindd_pw *user_list;
- int num_users, user_list_ndx = 0, i;
+ int num_users, user_list_ndx;
DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid));
@@ -645,6 +645,11 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
/* Allocate space for returning a chunk of users */
num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries);
+
+ if (num_users == 0) {
+ request_error(state);
+ return;
+ }
if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) {
request_error(state);
@@ -666,7 +671,7 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
/* Start sending back users */
- for (i = 0; i < num_users; i++) {
+ for (user_list_ndx = 0; user_list_ndx < num_users; ) {
struct getpwent_user *name_list = NULL;
uint32 result;
@@ -709,8 +714,6 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
name_list[ent->sam_entry_index].shell,
&user_list[user_list_ndx]);
- ent->sam_entry_index++;
-
/* Add user to return list */
if (result) {
@@ -723,6 +726,9 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
} else
DEBUG(1, ("could not lookup domain user %s\n",
name_list[ent->sam_entry_index].name));
+
+ ent->sam_entry_index++;
+
}
/* Out of domains */
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index 9025f287036..37285f01d23 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -1209,12 +1209,6 @@ static BOOL legacy_sid_to_uid(const DOM_SID *psid, uid_t *puid)
enum lsa_SidType type;
uint32 rid;
- if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
- uid_t uid = rid;
- *puid = uid;
- goto done;
- }
-
if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
union unid_t id;
BOOL ret;
@@ -1260,12 +1254,6 @@ static BOOL legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid)
union unid_t id;
enum lsa_SidType type;
- if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
- gid_t gid = rid;
- *pgid = gid;
- goto done;
- }
-
if ((sid_check_is_in_builtin(psid) ||
sid_check_is_in_wellknown_domain(psid))) {
BOOL ret;
@@ -1329,7 +1317,6 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
if (!winbind_uid_to_sid(psid, uid)) {
if (!winbind_ping()) {
- DEBUG(2, ("WARNING: Winbindd not running, mapping ids with legacy code\n"));
legacy_uid_to_sid(psid, uid);
return;
}
@@ -1359,7 +1346,6 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
if (!winbind_gid_to_sid(psid, gid)) {
if (!winbind_ping()) {
- DEBUG(2, ("WARNING: Winbindd not running, mapping ids with legacy code\n"));
legacy_gid_to_sid(psid, gid);
return;
}
@@ -1382,6 +1368,7 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
{
+ uint32 rid;
gid_t gid;
if (fetch_uid_from_cache(puid, psid))
@@ -1391,9 +1378,20 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
return False;
}
+ /* Optimize for the Unix Users Domain
+ * as the conversion is straightforward */
+ if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
+ uid_t uid = rid;
+ *puid = uid;
+
+ /* return here, don't cache */
+ DEBUG(10,("sid %s -> uid %u\n", sid_string_static(psid),
+ (unsigned int)*puid ));
+ return True;
+ }
+
if (!winbind_sid_to_uid(puid, psid)) {
if (!winbind_ping()) {
- DEBUG(2, ("WARNING: Winbindd not running, mapping ids with legacy code\n"));
return legacy_sid_to_uid(psid, puid);
}
@@ -1419,6 +1417,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
{
+ uint32 rid;
uid_t uid;
if (fetch_gid_from_cache(pgid, psid))
@@ -1427,12 +1426,23 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
if (fetch_uid_from_cache(&uid, psid))
return False;
+ /* Optimize for the Unix Groups Domain
+ * as the conversion is straightforward */
+ if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
+ gid_t gid = rid;
+ *pgid = gid;
+
+ /* return here, don't cache */
+ DEBUG(10,("sid %s -> gid %u\n", sid_string_static(psid),
+ (unsigned int)*pgid ));
+ return True;
+ }
+
/* Ask winbindd if it can map this sid to a gid.
* (Idmap will check it is a valid SID and of the right type) */
if ( !winbind_sid_to_gid(pgid, psid) ) {
if (!winbind_ping()) {
- DEBUG(2, ("WARNING: Winbindd not running, mapping ids with legacy code\n"));
return legacy_sid_to_gid(psid, pgid);
}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index be5d8e4ca64..c073cc9a40d 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -914,13 +914,13 @@ BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
goto done;
}
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+ pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET);
+ pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET);
+ pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET);
+ pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET);
+ pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET);
+ pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET);
+ pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET);
pdb_set_username(sampass, username, PDB_SET);
pdb_set_domain(sampass, domain, PDB_SET);
@@ -1102,13 +1102,13 @@ uint32 init_buffer_from_sam_v3 (uint8 **buf, struct samu *sampass, BOOL size_onl
*buf = NULL;
buflen = 0;
- logon_time = (uint32)pdb_get_logon_time(sampass);
- logoff_time = (uint32)pdb_get_logoff_time(sampass);
- kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
- bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
- pass_can_change_time = (uint32)pdb_get_pass_can_change_time_noncalc(sampass);
- pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
- pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
+ logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass));
+ logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass));
+ kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass));
+ bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass));
+ pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass));
+ pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass));
+ pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass));
user_rid = pdb_get_user_rid(sampass);
group_rid = pdb_get_group_rid(sampass);
@@ -1392,7 +1392,7 @@ BOOL pdb_update_bad_password_count(struct samu *sampass, BOOL *updated)
LastBadPassword = pdb_get_bad_password_time(sampass);
DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
(uint32) LastBadPassword, resettime, (uint32)time(NULL)));
- if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
+ if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){
pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
if (updated) {
@@ -1445,7 +1445,7 @@ bad password time. Leaving locked out.\n",
return True;
}
- if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
+ if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) {
pdb_set_acct_ctrl(sampass,
pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
PDB_CHANGED);
diff --git a/source/python/setup.py b/source/python/setup.py
index ce417710b30..1efe5938e11 100755
--- a/source/python/setup.py
+++ b/source/python/setup.py
@@ -67,6 +67,8 @@ for lib in string.split(samba_libs):
libraries.append(lib[2:])
elif lib[0:8] == ("-pthread"):
pass # Skip linker flags
+ elif lib[0:4] == ("-pie"):
+ pass # Skip linker flags
elif lib[0:2] == "-L":
library_dirs.append(lib[2:])
elif lib[0:2] in ("-W","-s"):
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 8ed67872430..f4e0e84d85a 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -2404,7 +2404,7 @@ static BOOL srv_io_file_info3(const char *desc, FILE_INFO_3 *fl3, prs_struct *ps
if(!prs_uint32("num_locks ", ps, depth, &fl3->num_locks))
return False;
- uni_p = fl3->path ? (uint32)fl3->path : 0;
+ uni_p = fl3->path ? 1 : 0;
if(!prs_uint32("ptr", ps, depth, &uni_p))
return False;
if (UNMARSHALLING(ps)) {
@@ -2413,7 +2413,7 @@ static BOOL srv_io_file_info3(const char *desc, FILE_INFO_3 *fl3, prs_struct *ps
}
}
- uni_p = fl3->user ? (uint32)fl3->user : 0;
+ uni_p = fl3->user ? 1 : 0;
if(!prs_uint32("ptr", ps, depth, &uni_p))
return False;
if (UNMARSHALLING(ps)) {
diff --git a/source/rpc_server/srv_lsa_ds_nt.c b/source/rpc_server/srv_lsa_ds_nt.c
index f387bec9b6d..17543a38ef6 100644
--- a/source/rpc_server/srv_lsa_ds_nt.c
+++ b/source/rpc_server/srv_lsa_ds_nt.c
@@ -84,16 +84,16 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN
basic->dnsname_ptr = 1;
init_unistr2( &basic->dns_domain, dnsdomain, UNI_STR_TERMINATE);
+
+ /* FIXME!! We really should fill in the correct forest
+ name. Should get this information from winbindd. */
basic->forestname_ptr = 1;
init_unistr2( &basic->forest_domain, dnsdomain, UNI_STR_TERMINATE);
} else {
- get_mydnsdomname(dnsdomain);
- strlower_m(dnsdomain);
-
- basic->dnsname_ptr = 1;
- init_unistr2( &basic->dns_domain, dnsdomain, UNI_FLAGS_NONE);
- basic->forestname_ptr = 1;
- init_unistr2( &basic->forest_domain, dnsdomain, UNI_FLAGS_NONE);
+ /* security = domain should not fill in the dns or
+ forest name */
+ basic->dnsname_ptr = 0;
+ basic->forestname_ptr = 0;
}
*info = basic;
diff --git a/source/script/tests/gdb_backtrace b/source/script/tests/gdb_backtrace
index b19a5b2f4b7..826381e9008 100644
--- a/source/script/tests/gdb_backtrace
+++ b/source/script/tests/gdb_backtrace
@@ -33,7 +33,7 @@ case "${UNAME}" in
esac
for DB in ${DB_LIST}; do
- DB_BIN=`which ${DB} 2>/dev/null`
+ DB_BIN=`which ${DB} 2>/dev/null | grep '^/'`
test x"${DB_BIN}" != x"" && {
break
}
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 70b2d30aaba..66baf4022a0 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -39,6 +39,7 @@ typedef struct _blocking_lock_record {
SMB_BIG_UINT offset;
SMB_BIG_UINT count;
uint32 lock_pid;
+ uint32 blocking_pid; /* PID that blocks us. */
enum brl_flavour lock_flav;
enum brl_type lock_type;
char *inbuf;
@@ -86,7 +87,9 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32 lock_pid,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- SMB_BIG_UINT offset, SMB_BIG_UINT count)
+ SMB_BIG_UINT offset,
+ SMB_BIG_UINT count,
+ uint32 blocking_pid)
{
static BOOL set_lock_msg;
blocking_lock_record *blr;
@@ -127,6 +130,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
}
blr->lock_num = lock_num;
blr->lock_pid = lock_pid;
+ blr->blocking_pid = blocking_pid;
blr->lock_flav = lock_flav;
blr->lock_type = lock_type;
blr->offset = offset;
@@ -142,7 +146,8 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
count,
lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
blr->lock_flav,
- lock_timeout ? True : False); /* blocking_lock. */
+ lock_timeout ? True : False, /* blocking_lock. */
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
@@ -380,7 +385,8 @@ static BOOL process_lockingX(blocking_lock_record *blr)
READ_LOCK : WRITE_LOCK),
WINDOWS_LOCK,
True,
- &status);
+ &status,
+ &blr->blocking_pid);
TALLOC_FREE(br_lck);
@@ -440,7 +446,8 @@ static BOOL process_trans2(blocking_lock_record *blr)
blr->lock_type,
blr->lock_flav,
True,
- &status);
+ &status,
+ &blr->blocking_pid);
TALLOC_FREE(br_lck);
if (!NT_STATUS_IS_OK(status)) {
@@ -598,7 +605,7 @@ unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms)
{
unsigned int timeout_ms = default_timeout_ms;
struct timeval tv_curr;
- SMB_BIG_INT min_tv_dif_us = 0x7FFFFFFF; /* A large +ve number. */
+ SMB_BIG_INT min_tv_dif_us = default_timeout_ms * 1000;
blocking_lock_record *blr = blocking_lock_queue;
/* note that we avoid the GetTimeOfDay() syscall if there are no blocking locks */
@@ -612,6 +619,15 @@ unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms)
SMB_BIG_INT tv_dif_us;
if (timeval_is_zero(&blr->expire_time)) {
+ /*
+ * If we're blocked on pid 0xFFFFFFFF this is
+ * a POSIX lock, so calculate a timeout of
+ * 10 seconds.
+ */
+ if (blr->blocking_pid == 0xFFFFFFFF) {
+ tv_dif_us = 10 * 1000 * 1000;
+ min_tv_dif_us = MIN(min_tv_dif_us, tv_dif_us);
+ }
continue; /* Never timeout. */
}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index a123a542fd2..6a496f16a6e 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -287,6 +287,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
status = map_nt_error_from_unix(errno);
}
+ notify_fname(conn, NOTIFY_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ fsp->fsp_name);
+
/* As we now have POSIX opens which can unlink
* with other open files we may have taken
* this code path with more than one share mode
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index b8d201328b5..37a49756e38 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -2421,7 +2421,8 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
WRITE_LOCK,
WINDOWS_LOCK,
False, /* Non-blocking lock. */
- &status);
+ &status,
+ NULL);
TALLOC_FREE(br_lck);
if (NT_STATUS_V(status)) {
@@ -3426,7 +3427,8 @@ int reply_lock(connection_struct *conn,
WRITE_LOCK,
WINDOWS_LOCK,
False, /* Non-blocking lock. */
- &status);
+ &status,
+ NULL);
TALLOC_FREE(br_lck);
@@ -5524,6 +5526,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
BOOL blocking_lock = lock_timeout ? True : False;
BOOL defer_lock = False;
struct byte_range_lock *br_lck;
+ uint32 block_smbpid;
br_lck = do_lock(fsp,
lock_pid,
@@ -5532,7 +5535,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
lock_type,
WINDOWS_LOCK,
blocking_lock,
- &status);
+ &status,
+ &block_smbpid);
if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/* Windows internal resolution for blocking locks seems
@@ -5569,7 +5573,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
lock_type,
WINDOWS_LOCK,
offset,
- count)) {
+ count,
+ block_smbpid)) {
TALLOC_FREE(br_lck);
END_PROFILE(SMBlockingX);
return -1;
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 2ac90beba98..952aff953d2 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -4671,6 +4671,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
offset,
POSIX_LOCK);
} else {
+ uint32 block_smbpid;
+
struct byte_range_lock *br_lck = do_lock(fsp,
lock_pid,
count,
@@ -4678,7 +4680,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
lock_type,
POSIX_LOCK,
blocking_lock,
- &status);
+ &status,
+ &block_smbpid);
if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/*
@@ -4695,7 +4698,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
lock_type,
POSIX_LOCK,
offset,
- count)) {
+ count,
+ block_smbpid)) {
TALLOC_FREE(br_lck);
return status;
}
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index 85885803222..c6d4e3329c8 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -156,7 +156,9 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
char group_c;
BOOL must_free_token = False;
NT_USER_TOKEN *token = NULL;
-
+ int num_groups = 0;
+ gid_t *group_list = NULL;
+
if (!conn) {
DEBUG(2,("change_to_user: Connection not open\n"));
return(False);
@@ -195,14 +197,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
if (conn->force_user) /* security = share sets this too */ {
uid = conn->uid;
gid = conn->gid;
- current_user.ut.groups = conn->groups;
- current_user.ut.ngroups = conn->ngroups;
+ group_list = conn->groups;
+ num_groups = conn->ngroups;
token = conn->nt_user_token;
} else if (vuser) {
uid = conn->admin_user ? 0 : vuser->uid;
gid = vuser->gid;
- current_user.ut.ngroups = vuser->n_groups;
- current_user.ut.groups = vuser->groups;
+ num_groups = vuser->n_groups;
+ group_list = vuser->groups;
token = vuser->nt_user_token;
} else {
DEBUG(2,("change_to_user: Invalid vuid used %d in accessing "
@@ -235,8 +237,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
*/
int i;
- for (i = 0; i < current_user.ut.ngroups; i++) {
- if (current_user.ut.groups[i] == conn->gid) {
+ for (i = 0; i < num_groups; i++) {
+ if (group_list[i] == conn->gid) {
gid = conn->gid;
gid_to_sid(&token->user_sids[1], gid);
break;
@@ -248,6 +250,12 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
}
}
+ /* Now set current_user since we will immediately also call
+ set_sec_ctx() */
+
+ current_user.ut.ngroups = num_groups;
+ current_user.ut.groups = group_list;
+
set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups,
token);
diff --git a/source/utils/net_rap.c b/source/utils/net_rap.c
index 9084122d680..54e59673b80 100644
--- a/source/utils/net_rap.c
+++ b/source/utils/net_rap.c
@@ -435,10 +435,14 @@ int net_rap_server(int argc, const char **argv)
int ret;
if (argc > 0) {
- if (!strequal(argv[0], "name")) {
+ if (strequal(argv[0], "name")) {
+ return net_rap_server_name(argc, argv);
+ }
+ /* smb4k uses 'net [rap|rpc] server domain' to query servers in a domain */
+ /* Fall through for 'domain', any other forms will cause to show usage message */
+ if (!strequal(argv[0], "domain")) {
return net_rap_server_usage(argc-1, argv+1);
}
- return net_rap_server_name(argc, argv);
}
if (!(cli = net_make_ipc_connection(0)))
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 56aee3be91a..c300a7171ce 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -3113,7 +3113,7 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
if (opt_long_list_entries) {
d_printf("%-12s %-8.8s %-50s\n",
- netname, share_type[info1->info_1.type], remark);
+ netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
} else {
d_printf("%s\n", netname);
}
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index d1a87260fa9..078eae71ac2 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -96,7 +96,7 @@ static int export_database (struct pdb_methods *in,
return 1;
}
- printf("Importing accout for %s...", user->username);
+ printf("Importing account for %s...", user->username);
if ( !NT_STATUS_IS_OK(out->getsampwnam( out, account, user->username )) ) {
status = out->add_sam_account(out, user);
} else {
@@ -285,14 +285,14 @@ static int print_sam_info (struct samu *sam_pwent, BOOL verbosity, BOOL smbpwdst
lm_passwd,
nt_passwd,
pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
- (uint32)pdb_get_pass_last_set_time(sam_pwent));
+ (uint32)convert_time_t_to_uint32(pdb_get_pass_last_set_time(sam_pwent)));
} else {
uid = nametouid(pdb_get_username(sam_pwent));
printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
pdb_get_fullname(sam_pwent));
}
- return 0;
+ return 0;
}
/*********************************************************