summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-12-23 18:45:36 +0000
committerGerald Carter <jerry@samba.org>2004-12-23 18:45:36 +0000
commitb262548fec09659f46839dcf4c079176775f0871 (patch)
tree2f44f7f1cdce6d71d868626caea49fdfb82e1249
parent8d91e07ef22ad3ed484b04bc4968380a24940696 (diff)
downloadsamba-b262548fec09659f46839dcf4c079176775f0871.tar.gz
samba-b262548fec09659f46839dcf4c079176775f0871.tar.xz
samba-b262548fec09659f46839dcf4c079176775f0871.zip
r4348: syncing up for 3.0.11pre1
-rwxr-xr-xexamples/VFS/autogen.sh39
-rw-r--r--examples/VFS/skel_opaque.c20
-rw-r--r--examples/VFS/skel_transparent.c20
-rw-r--r--packaging/Solaris/makepkg.sh34
-rw-r--r--source/Makefile.in9
-rw-r--r--source/VERSION4
-rw-r--r--source/auth/auth_util.c104
-rw-r--r--source/auth/auth_winbind.c6
-rw-r--r--source/auth/pampass.c2
-rw-r--r--source/client/client.c183
-rw-r--r--source/client/tree.c2
-rwxr-xr-xsource/config.guess186
-rwxr-xr-xsource/config.sub326
-rw-r--r--source/configure.in39
-rw-r--r--source/groupdb/mapping.c35
-rw-r--r--source/include/client.h2
-rw-r--r--source/include/includes.h9
-rw-r--r--source/include/passdb.h20
-rw-r--r--source/include/rpc_misc.h9
-rw-r--r--source/include/rpc_netlogon.h51
-rw-r--r--source/include/rpc_samr.h19
-rw-r--r--source/include/smbldap.h1
-rw-r--r--source/include/smbprofile.h8
-rw-r--r--source/include/trans2.h84
-rw-r--r--source/include/vfs.h16
-rw-r--r--source/include/vfs_macros.h10
-rw-r--r--source/lib/account_pol.c2
-rw-r--r--source/lib/afs.c16
-rw-r--r--source/lib/afs_settoken.c4
-rw-r--r--source/lib/charcnv.c15
-rw-r--r--source/lib/module.c5
-rw-r--r--source/lib/ms_fnmatch.c13
-rw-r--r--source/lib/replace.c11
-rw-r--r--source/lib/sendfile.c86
-rw-r--r--source/lib/smbldap.c5
-rw-r--r--source/lib/sysacls.c61
-rw-r--r--source/lib/sysquotas.c12
-rw-r--r--source/lib/system.c65
-rw-r--r--source/lib/system_smbd.c90
-rw-r--r--source/lib/util.c5
-rw-r--r--source/lib/util_pw.c43
-rw-r--r--source/lib/util_smbd.c16
-rw-r--r--source/lib/util_sock.c150
-rw-r--r--source/lib/util_str.c8
-rw-r--r--source/lib/util_unistr.c10
-rw-r--r--source/libads/ads_status.c7
-rw-r--r--source/libads/kerberos.c3
-rw-r--r--source/libads/ldap.c51
-rw-r--r--source/libads/util.c1
-rw-r--r--source/libsmb/cliconnect.c15
-rw-r--r--source/libsmb/clifile.c49
-rw-r--r--source/libsmb/clifsinfo.c58
-rw-r--r--source/libsmb/clikrb5.c7
-rw-r--r--source/libsmb/clireadwrite.c19
-rw-r--r--source/libsmb/libsmbclient.c8
-rw-r--r--source/libsmb/namequery.c6
-rw-r--r--source/libsmb/ntlmssp_sign.c6
-rw-r--r--source/libsmb/samlogon_cache.c2
-rw-r--r--source/locking/brlock.c17
-rw-r--r--source/locking/locking.c42
-rw-r--r--source/modules/vfs_afsacl.c55
-rw-r--r--source/modules/vfs_cap.c4
-rw-r--r--source/modules/vfs_full_audit.c48
-rw-r--r--source/modules/vfs_netatalk.c4
-rw-r--r--source/modules/vfs_shadow_copy.c12
-rw-r--r--source/nmbd/nmbd_packets.c12
-rw-r--r--source/nsswitch/pam_winbind.c2
-rw-r--r--source/nsswitch/winbindd.h4
-rw-r--r--source/nsswitch/winbindd_cm.c584
-rw-r--r--source/nsswitch/winbindd_group.c25
-rw-r--r--source/nsswitch/winbindd_nss.h17
-rw-r--r--source/nsswitch/winbindd_pam.c2
-rw-r--r--source/nsswitch/winbindd_rpc.c23
-rw-r--r--source/nsswitch/winbindd_util.c2
-rw-r--r--source/nsswitch/winbindd_wins.c6
-rw-r--r--source/param/loadparm.c51
-rw-r--r--source/passdb/lookup_sid.c9
-rw-r--r--source/passdb/passdb.c30
-rw-r--r--source/passdb/pdb_interface.c75
-rw-r--r--source/passdb/pdb_ldap.c190
-rw-r--r--source/passdb/pdb_mysql.c10
-rw-r--r--source/passdb/pdb_pgsql.c5
-rw-r--r--source/passdb/pdb_sql.c3
-rw-r--r--source/passdb/pdb_xml.c2
-rw-r--r--source/passdb/secrets.c2
-rw-r--r--source/passdb/util_sam_sid.c13
-rw-r--r--source/po/de.msg106
-rw-r--r--source/printing/nt_printing.c40
-rw-r--r--source/printing/print_cups.c26
-rw-r--r--source/printing/print_svid.c4
-rw-r--r--source/printing/printing.c293
-rw-r--r--source/profile/profile.c2
-rw-r--r--source/python/py_common.c14
-rw-r--r--source/rpc_client/cli_ds.c2
-rw-r--r--source/rpc_client/cli_netlogon.c12
-rw-r--r--source/rpc_parse/parse_misc.c64
-rw-r--r--source/rpc_parse/parse_net.c72
-rw-r--r--source/rpc_parse/parse_samr.c80
-rw-r--r--source/rpc_parse/parse_srv.c2
-rw-r--r--source/rpc_server/srv_lsa_nt.c4
-rw-r--r--source/rpc_server/srv_samr_nt.c152
-rw-r--r--source/rpc_server/srv_spoolss_nt.c48
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c11
-rw-r--r--source/rpc_server/srv_util.c234
-rw-r--r--source/rpcclient/cmd_samr.c34
-rw-r--r--source/rpcclient/cmd_spoolss.c2
-rw-r--r--source/sam/idmap_ldap.c2
-rw-r--r--source/sam/idmap_rid.c18
-rw-r--r--source/smbd/chgpasswd.c40
-rw-r--r--source/smbd/connection.c5
-rw-r--r--source/smbd/dosmode.c12
-rw-r--r--source/smbd/fileio.c16
-rw-r--r--source/smbd/ipc.c4
-rw-r--r--source/smbd/lanman.c108
-rw-r--r--source/smbd/negprot.c8
-rw-r--r--source/smbd/nttrans.c47
-rw-r--r--source/smbd/open.c8
-rw-r--r--source/smbd/pipes.c2
-rw-r--r--source/smbd/posix_acls.c410
-rw-r--r--source/smbd/process.c3
-rw-r--r--source/smbd/quotas.c4
-rw-r--r--source/smbd/reply.c152
-rw-r--r--source/smbd/server.c17
-rw-r--r--source/smbd/service.c16
-rw-r--r--source/smbd/sesssetup.c2
-rw-r--r--source/smbd/trans2.c404
-rw-r--r--source/smbd/vfs-wrap.c33
-rw-r--r--source/smbd/vfs.c10
-rw-r--r--source/smbwrapper/smbw.c20
-rw-r--r--source/smbwrapper/smbw_cache.c16
-rw-r--r--source/torture/cmd_vfs.c2
-rw-r--r--source/torture/torture.c4
-rw-r--r--source/utils/editreg.c111
-rw-r--r--source/utils/net_groupmap.c5
-rw-r--r--source/utils/net_help.c1
-rw-r--r--source/utils/net_idmap.c54
-rw-r--r--source/utils/net_rpc.c81
-rw-r--r--source/utils/net_rpc_printer.c9
-rw-r--r--source/utils/net_rpc_samsync.c131
-rw-r--r--source/utils/ntlm_auth.c2
-rw-r--r--source/utils/pdbedit.c89
-rw-r--r--source/utils/smbcacls.c12
-rw-r--r--source/utils/smbget.c8
-rw-r--r--source/utils/smbpasswd.c3
-rw-r--r--source/utils/status.c36
-rw-r--r--source/wrepld/server.c10
146 files changed, 4736 insertions, 1717 deletions
diff --git a/examples/VFS/autogen.sh b/examples/VFS/autogen.sh
index fcae16ec5c8..e8160d21731 100755
--- a/examples/VFS/autogen.sh
+++ b/examples/VFS/autogen.sh
@@ -1,28 +1,28 @@
#!/bin/sh
-# Run this script to build samba from CVS.
+# Run this script to build samba from SVN.
## insert all possible names (only works with
## autoconf 2.x
-#TESTAUTOHEADER="autoheader autoheader-2.53"
-TESTAUTOCONF="autoconf autoconf-2.53"
+TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50"
+TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50"
-#AUTOHEADERFOUND="0"
+AUTOHEADERFOUND="0"
AUTOCONFFOUND="0"
##
## Look for autoheader
##
-#for i in $TESTAUTOHEADER; do
-# if which $i > /dev/null 2>&1; then
-# if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
-# AUTOHEADER=$i
-# AUTOHEADERFOUND="1"
-# break
-# fi
-# fi
-#done
+for i in $TESTAUTOHEADER; do
+ if which $i > /dev/null 2>&1; then
+ if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then
+ AUTOHEADER=$i
+ AUTOHEADERFOUND="1"
+ break
+ fi
+ fi
+done
##
## Look for autoconf
@@ -30,7 +30,7 @@ AUTOCONFFOUND="0"
for i in $TESTAUTOCONF; do
if which $i > /dev/null 2>&1; then
- if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
+ if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then
AUTOCONF=$i
AUTOCONFFOUND="1"
break
@@ -43,18 +43,23 @@ done
## do we have it?
##
if [ "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0" ]; then
- echo "$0: need autoconf 2.53 or later to build samba from CVS" >&2
+ echo "$0: need autoconf 2.53 or later to build samba from SVN" >&2
exit 1
fi
+echo "$0: running script/mkversion.sh"
+./script/mkversion.sh || exit 1
+rm -rf autom4te*.cache
-#echo "$0: running $AUTOHEADER"
-#$AUTOHEADER || exit 1
+echo "$0: running $AUTOHEADER"
+$AUTOHEADER || exit 1
echo "$0: running $AUTOCONF"
$AUTOCONF || exit 1
+rm -rf autom4te*.cache
+
echo "Now run ./configure and then make."
exit 0
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 310d305cee3..c7e5295b007 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -76,11 +76,26 @@ static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, con
return vfswrap_opendir(NULL, conn, fname);
}
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
return vfswrap_readdir(NULL, conn, dirp);
}
+static void skel_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ return vfswrap_seekdir(NULL, conn, dirp, offset);
+}
+
+static long skel_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return vfswrap_telldir(NULL, conn, dirp);
+}
+
+static void skel_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return vfswrap_rewinddir(NULL, conn, dirp);
+}
+
static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
return vfswrap_mkdir(NULL, conn, path, mode);
@@ -489,6 +504,9 @@ static vfs_op_tuple skel_op_tuples[] = {
{SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_OPAQUE},
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 448390e72f4..b10161cde19 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -75,11 +75,26 @@ static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, con
return SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
}
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
return SMB_VFS_NEXT_READDIR(handle, conn, dirp);
}
+static void skel_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ return SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset);
+}
+
+static long skel_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return SMB_VFS_NEXT_TELLDIR(handle, conn, dirp);
+}
+
+static void skel_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp);
+}
+
static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
return SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
@@ -458,6 +473,9 @@ static vfs_op_tuple skel_op_tuples[] = {
{SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
diff --git a/packaging/Solaris/makepkg.sh b/packaging/Solaris/makepkg.sh
index 7f8c4b6d717..aaa176c4e77 100644
--- a/packaging/Solaris/makepkg.sh
+++ b/packaging/Solaris/makepkg.sh
@@ -48,9 +48,11 @@ add_dynamic_entries()
echo f none lib/libsmbclient.so 0755 root other
echo f none include/libsmbclient.h 0644 root other
- echo "#\n# smbwrapper\n#"
- echo f none lib/smbwrapper.so 0755 root other
- echo f none bin/smbsh 0755 root other
+ if [ -f lib/smbwrapper.so -a -f bin/smbsh ]; then
+ echo "#\n# smbwrapper\n#"
+ echo f none lib/smbwrapper.so 0755 root other
+ echo f none bin/smbsh 0755 root other
+ fi
echo "#\n# nss_winbind.so\n#"
echo f none /lib/nss_winbind.so.1=lib/nss_winbind.so.1 0755 root other
@@ -100,12 +102,13 @@ add_dynamic_entries()
## BEGIN MAIN
#####################################################################
-TMPINSTALLDIR=/export/build
-
# Try to guess the distribution base..
-CURR_DIR=`pwd`
-DISTR_BASE=`echo $CURR_DIR | sed 's|\(.*\)/packaging.*|\1|'`
-echo "Assuming Samba distribution is rooted at $DISTR_BASE.."
+DISTR_BASE=`dirname \`pwd\` |sed -e 's@/packaging$@@'`
+echo "Distribution base: $DISTR_BASE"
+
+TMPINSTALLDIR="/tmp/`basename $DISTR_BASE`-build"
+echo "Temp install dir: $TMPINSTALLDIR"
+echo "Install directory: $INSTALL_BASE"
##
## first build the source
@@ -114,7 +117,7 @@ echo "Assuming Samba distribution is rooted at $DISTR_BASE.."
cd $DISTR_BASE/source
if [ "x$1" != "xnobuild" ]; then
- ./configure --prefix=$INSTALL_DIR \
+ ./configure --prefix=$INSTALL_BASE \
--with-acl-support \
--with-included-popt \
--localstatedir=/var/lib/samba \
@@ -130,11 +133,11 @@ if [ "x$1" != "xnobuild" ]; then
fi
fi
+mkdir $TMPINSTALLDIR
make DESTDIR=$TMPINSTALLDIR install
## clear out *.old
-( cd $TMPINSTALLDIR; du -a | grep \.old$ | awk '{print "rm -rf "$2}' | sh )
-
+find $TMPINSTALLDIR -name \*.old |while read x; do rm -rf "$x"; done
##
## Now get the install locations
@@ -157,9 +160,12 @@ cp -fp nsswitch/libnss_winbind.so $TMPINSTALLDIR/$LIBDIR/nss_winbind.so.1
if [ -f nsswitch/pam_winbind.so ]; then
cp -fp nsswitch/pam_winbind.so $TMPINSTALLDIR/$LIBDIR/pam_winbind.so
fi
-
-cp -p bin/smbwrapper.so $TMPINSTALLDIR/$INSTALL_BASE/lib
-cp -p bin/smbsh $TMPINSTALLDIR/$INSTALL_BASE/bin
+if [ -f bin/smbwrapper.so ]; then
+ cp -fp bin/smbwrapper.so $TMPINSTALLDIR/$INSTALL_BASE/lib
+fi
+if [ -f bin/smbsh ]; then
+ cp -fp bin/smbsh $TMPINSTALLDIR/$INSTALL_BASE/bin
+fi
mkdir -p $TMPINSTALLDIR/$INSTALL_BASE/docs
cp -p ../docs/*pdf $TMPINSTALLDIR/$INSTALL_BASE/docs
diff --git a/source/Makefile.in b/source/Makefile.in
index 0b39fd3dce8..a6e434464fe 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -208,8 +208,6 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
-
LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
READLINE_OBJ = lib/readline.o
@@ -313,7 +311,8 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_sam_sid.o passdb/pdb_compat.o \
passdb/privileges.o passdb/lookup_sid.o \
- passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o
+ passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
+ lib/system_smbd.o
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
@@ -395,7 +394,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
+ $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
@@ -619,7 +618,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
$(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
+ $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
$(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
diff --git a/source/VERSION b/source/VERSION
index 40dbcda5e70..e7bcb1326b0 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -19,7 +19,7 @@
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=10
+SAMBA_VERSION_RELEASE=11
########################################################
# For 'pre' releases the version will be #
@@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=10
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=
+SAMBA_VERSION_PRE_RELEASE=1
########################################################
# For 'rc' releases the version will be #
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index a10482cf2e0..2eacc2b0d10 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -657,47 +657,27 @@ static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
*n_groups = 0;
*groups = NULL;
-
- /* Try winbind first */
- if ( strchr(username, *lp_winbind_separator()) ) {
- n_unix_groups = winbind_getgroups( username, unix_groups );
+ if (strchr(username, *lp_winbind_separator()) == NULL) {
+ NTSTATUS result;
- DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username,
- n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
-
- if ( n_unix_groups == -1 )
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
+ become_root();
+ result = pdb_enum_group_memberships(username, gid, groups,
+ unix_groups, n_groups);
+ unbecome_root();
+ return result;
}
- else {
- /* fallback to getgrouplist() */
-
- n_unix_groups = groups_max();
-
- if ((*unix_groups = SMB_MALLOC_ARRAY( gid_t, n_unix_groups ) ) == NULL) {
- DEBUG(0, ("get_user_groups: Out of memory allocating unix group list\n"));
- return NT_STATUS_NO_MEMORY;
- }
+
+ /* We have the separator, this must be winbind */
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
-
- gid_t *groups_tmp;
-
- groups_tmp = SMB_REALLOC_ARRAY(*unix_groups, gid_t, n_unix_groups);
-
- if (!groups_tmp) {
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_MEMORY;
- }
- *unix_groups = groups_tmp;
+ n_unix_groups = winbind_getgroups( username, unix_groups );
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
- }
- }
- }
+ DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
+ username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
+
+ if ( n_unix_groups == -1 )
+ return NT_STATUS_NO_SUCH_USER; /* what should this return
+ * value be? */
debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
@@ -884,7 +864,7 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
Make (and fill) a user_info struct for a guest login.
***************************************************************************/
-NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
SAM_ACCOUNT *sampass = NULL;
@@ -919,6 +899,49 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
return nt_status;
}
+static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
+{
+ auth_serversupplied_info *dst;
+
+ if (!NT_STATUS_IS_OK(make_server_info(&dst)))
+ return NULL;
+
+ dst->guest = src->guest;
+ dst->uid = src->uid;
+ dst->gid = src->gid;
+ dst->n_groups = src->n_groups;
+ if (src->n_groups != 0)
+ dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
+ else
+ dst->groups = NULL;
+ dst->ptok = dup_nt_token(src->ptok);
+ dst->user_session_key = data_blob(src->user_session_key.data,
+ src->user_session_key.length);
+ dst->lm_session_key = data_blob(src->lm_session_key.data,
+ src->lm_session_key.length);
+ pdb_copy_sam_account(src->sam_account, &dst->sam_account);
+ dst->pam_handle = NULL;
+ dst->unix_name = smb_xstrdup(src->unix_name);
+
+ return dst;
+}
+
+static auth_serversupplied_info *guest_info = NULL;
+
+BOOL init_guest_info(void)
+{
+ if (guest_info != NULL)
+ return True;
+
+ return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
+}
+
+NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+{
+ *server_info = copy_serverinfo(guest_info);
+ return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+}
+
/***************************************************************************
Purely internal function for make_server_info_info3
Fill the sam account from getpwnam
@@ -1301,11 +1324,12 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
(*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
}
- if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) {
+ if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
(*server_info)->lm_session_key = data_blob(NULL, 0);
} else {
- (*server_info)->lm_session_key = data_blob(info3->padding, 16);
- }
+ (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
+ }
+
return NT_STATUS_OK;
}
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
index 4260a0e80b4..78235d30fce 100644
--- a/source/auth/auth_winbind.c
+++ b/source/auth/auth_winbind.c
@@ -88,11 +88,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
request.flags = WBFLAG_PAM_INFO3_NDR;
- push_utf8_fstring(request.data.auth_crap.user,
+ fstrcpy(request.data.auth_crap.user,
user_info->smb_name.str);
- push_utf8_fstring(request.data.auth_crap.domain,
+ fstrcpy(request.data.auth_crap.domain,
user_info->domain.str);
- push_utf8_fstring(request.data.auth_crap.workstation,
+ fstrcpy(request.data.auth_crap.workstation,
user_info->wksta_name.str);
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
diff --git a/source/auth/pampass.c b/source/auth/pampass.c
index 68871547b19..68c2f183f17 100644
--- a/source/auth/pampass.c
+++ b/source/auth/pampass.c
@@ -59,7 +59,7 @@ typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_resp
/*
* Macros to help make life easy
*/
-#define COPY_STRING(s) (s) ? strdup(s) : NULL
+#define COPY_STRING(s) (s) ? SMB_STRDUP(s) : NULL
/*******************************************************************
PAM error handler.
diff --git a/source/client/client.c b/source/client/client.c
index 2d4a129be7c..7470a7ba5fd 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -1789,6 +1789,182 @@ static char *unix_mode_to_str(char *s, mode_t m)
}
/****************************************************************************
+ Utility function for UNIX getfacl.
+****************************************************************************/
+
+static char *perms_to_string(fstring permstr, unsigned char perms)
+{
+ fstrcpy(permstr, "---");
+ if (perms & SMB_POSIX_ACL_READ) {
+ permstr[0] = 'r';
+ }
+ if (perms & SMB_POSIX_ACL_WRITE) {
+ permstr[1] = 'w';
+ }
+ if (perms & SMB_POSIX_ACL_EXECUTE) {
+ permstr[2] = 'x';
+ }
+ return permstr;
+}
+
+/****************************************************************************
+ UNIX getfacl.
+****************************************************************************/
+
+static int cmd_getfacl(void)
+{
+ pstring src, name;
+ uint16 major, minor;
+ uint32 caplow, caphigh;
+ char *retbuf = NULL;
+ size_t rb_size = 0;
+ SMB_STRUCT_STAT sbuf;
+ uint16 num_file_acls = 0;
+ uint16 num_dir_acls = 0;
+ uint16 i;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ d_printf("Server doesn't support UNIX CIFS calls.\n");
+ return 1;
+ }
+
+ if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
+ d_printf("Can't get UNIX CIFS version from server.\n");
+ return 1;
+ }
+
+ if (!(caplow & CIFS_UNIX_POSIX_ACLS_CAP)) {
+ d_printf("This server supports UNIX extensions but doesn't support POSIX ACLs.\n");
+ return 1;
+ }
+
+ pstrcpy(src,cur_dir);
+
+ if (!next_token_nr(NULL,name,NULL,sizeof(name))) {
+ d_printf("stat file\n");
+ return 1;
+ }
+
+ pstrcat(src,name);
+
+ if (!cli_unix_stat(cli, src, &sbuf)) {
+ d_printf("%s getfacl doing a stat on file %s\n",
+ cli_errstr(cli), src);
+ return 1;
+ }
+
+ if (!cli_unix_getfacl(cli, src, &rb_size, &retbuf)) {
+ d_printf("%s getfacl file %s\n",
+ cli_errstr(cli), src);
+ return 1;
+ }
+
+ /* ToDo : Print out the ACL values. */
+ if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+ d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
+ src, (unsigned int)CVAL(retbuf,0) );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ num_file_acls = SVAL(retbuf,2);
+ num_dir_acls = SVAL(retbuf,4);
+ if (rb_size != SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)) {
+ d_printf("getfacl file %s, incorrect POSIX acl buffer size (should be %u, was %u).\n",
+ src,
+ (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
+ (unsigned int)rb_size);
+
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("# file: %s\n", src);
+ d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+
+ if (num_file_acls == 0 && num_dir_acls == 0) {
+ d_printf("No acls found.\n");
+ }
+
+ for (i = 0; i < num_file_acls; i++) {
+ uint32 uorg;
+ fstring permstring;
+ unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE));
+ unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+ switch(tagtype) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ d_printf("user::");
+ break;
+ case SMB_POSIX_ACL_USER:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("user:%u:", uorg);
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ d_printf("group::");
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("group:%u", uorg);
+ break;
+ case SMB_POSIX_ACL_MASK:
+ d_printf("mask::");
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ d_printf("other::");
+ break;
+ default:
+ d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+ src, (unsigned int)tagtype );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("%s\n", perms_to_string(permstring, perms));
+ }
+
+ for (i = 0; i < num_dir_acls; i++) {
+ uint32 uorg;
+ fstring permstring;
+ unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE));
+ unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+ switch(tagtype) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ d_printf("default:user::");
+ break;
+ case SMB_POSIX_ACL_USER:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("default:user:%u:", uorg);
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ d_printf("default:group::");
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("default:group:%u", uorg);
+ break;
+ case SMB_POSIX_ACL_MASK:
+ d_printf("default:mask::");
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ d_printf("default:other::");
+ break;
+ default:
+ d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+ src, (unsigned int)tagtype );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("%s\n", perms_to_string(permstring, perms));
+ }
+
+ SAFE_FREE(retbuf);
+ return 0;
+}
+
+/****************************************************************************
UNIX stat.
****************************************************************************/
@@ -2355,6 +2531,7 @@ static struct
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
+ {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_LOCAL}},
{"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
@@ -2639,10 +2816,12 @@ static char **completion_fn(const char *text, int start, int end)
return NULL;
} else {
char **matches;
- int i, len, samelen, count=1;
+ int i, len, samelen = 0, count=1;
matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
- if (!matches) return NULL;
+ if (!matches) {
+ return NULL;
+ }
matches[0] = NULL;
len = strlen(text);
diff --git a/source/client/tree.c b/source/client/tree.c
index 97ad7742e31..5071c45dbc9 100644
--- a/source/client/tree.c
+++ b/source/client/tree.c
@@ -129,7 +129,7 @@ char *get_path(GtkWidget *item)
struct tree_data *make_tree_data(guint32 type, const char *name)
{
- struct tree_data *p = (struct tree_data *)malloc(sizeof(struct tree_data));
+ struct tree_data *p = SMB_MALLOC_P(struct tree_data);
if (p) {
diff --git a/source/config.guess b/source/config.guess
index 78f6b92cd30..dd1688b7b5f 100755
--- a/source/config.guess
+++ b/source/config.guess
@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2003-01-10'
+timestamp='2004-06-11'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -106,6 +106,7 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
@@ -196,15 +197,24 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
+ amd64:OpenBSD:*:*)
+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
+ cats:OpenBSD:*:*)
+ echo arm-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
+ luna88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
@@ -235,73 +245,70 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
- *:MicroBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
+ case $UNAME_RELEASE in
+ *4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- eval $set_cc_for_build
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
- if test "$?" = 0 ; then
- case `$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- 3-1307)
- UNAME_MACHINE="alphaev7"
- ;;
- esac
- fi
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha*:OpenVMS:*:*)
+ echo alpha-hp-vms
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
@@ -324,6 +331,9 @@ EOF
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
@@ -341,6 +351,9 @@ EOF
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
DRS?6000:UNIX_SV:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7 && exit 0 ;;
@@ -413,6 +426,9 @@ EOF
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
@@ -748,7 +764,7 @@ EOF
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
*:UNICOS/mp:*:*)
- echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
@@ -756,6 +772,11 @@ EOF
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
@@ -777,7 +798,10 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+ # FreeBSD's kernel, but not the complete OS.
+ case ${LIBC} in gnu) kernel_only='k' ;; esac
+ echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -788,8 +812,8 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
- x86:Interix*:3*)
- echo i586-pc-interix3
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit 0 ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
@@ -810,17 +834,28 @@ EOF
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
+ # the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit 0 ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit 0 ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
@@ -896,6 +931,9 @@ EOF
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
@@ -953,6 +991,9 @@ EOF
LIBC=gnuaout
#endif
#endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
@@ -983,6 +1024,9 @@ EOF
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
@@ -1052,9 +1096,9 @@ EOF
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit 0 ;;
- M68*:*:R3V[567]*:*)
+ M68*:*:R3V[5678]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -1169,7 +1213,7 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
- NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1210,6 +1254,12 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit 0 ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
diff --git a/source/config.sub b/source/config.sub
index 2476310dff3..ba331039bb8 100755
--- a/source/config.sub
+++ b/source/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2001-12-03'
+timestamp='2004-03-12'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -118,7 +118,8 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -227,28 +228,43 @@ case $basic_machine in
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
- | d10v | d30v | dsp16xx \
- | fr30 \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
- | m32r | m68000 | m68k | m88k | mcore \
- | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el | mips64vr4300 \
- | mips64vr4300el | mips64vr5000 | mips64vr5000el \
- | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
- | mipsisa32 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | msp430 \
| ns16k | ns32k \
- | openrisc \
+ | openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[34] | sh[34]eb | shbe | shle \
- | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
| strongarm \
- | tahoe | thumb | tic80 | tron \
+ | tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
@@ -278,38 +294,55 @@ case $basic_machine in
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alphapca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armv*-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c54x-* \
- | clipper-* | cray2-* | cydra-* \
- | d10v-* | d30v-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
- | m32r-* \
- | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
- | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
- | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
- | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | msp430-* \
+ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
- | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
@@ -330,6 +363,9 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -344,6 +380,12 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -375,6 +417,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -395,17 +441,13 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
+ cray | j90)
+ basic_machine=j90-cray
os=-unicos
;;
- [cjt]90)
- basic_machine=${basic_machine}-cray
- os=-unicos
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
;;
crds | unos)
basic_machine=m68k-crds
@@ -413,12 +455,24 @@ case $basic_machine in
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -599,14 +653,6 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux-gnu
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux-gnu
- ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -621,6 +667,10 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -693,6 +743,10 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ nv1)
+ basic_machine=nv1-cray
+ os=-unicosmp
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -700,6 +754,14 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -722,49 +784,55 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
- pc532 | pc532-*)
+ pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
- pentiumpro | p6 | 6x86 | athlon)
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
- pentiumii | pentium2)
+ pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- pentiumii-* | pentium2-*)
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
- ;;
+ ;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
- ;;
+ ;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
- ;;
+ ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
- ;;
+ ;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
@@ -795,6 +863,16 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
sequent)
basic_machine=i386-sequent
;;
@@ -802,6 +880,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
@@ -869,22 +950,42 @@ case $basic_machine in
os=-dynix
;;
t3e)
- basic_machine=t3e-cray
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -906,8 +1007,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -928,17 +1029,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
- windows32)
- basic_machine=i386-pc
- os=-windows32-msvcrt
+ xps | xps100)
+ basic_machine=xps100-honeywell
;;
- xmp)
- basic_machine=xmp-cray
+ ymp)
+ basic_machine=ymp-cray
os=-unicos
;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -959,13 +1056,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
- mips)
- if [ x$os = x-linux-gnu ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
romp)
basic_machine=romp-ibm
;;
@@ -985,13 +1075,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4 | sh3eb | sh4eb)
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv9 | sparcv9b)
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
- cydra)
+ cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1006,10 +1099,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
- c4x*)
- basic_machine=c4x-none
- os=-coff
- ;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1065,17 +1154,20 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus*)
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1087,8 +1179,10 @@ case $os in
;;
esac
;;
+ -nto-qnx*)
+ ;;
-nto*)
- os=-nto-qnx
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -1097,6 +1191,9 @@ case $os in
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -1109,6 +1206,9 @@ case $os in
-opened*)
os=-openedition
;;
+ -os400*)
+ os=-os400
+ ;;
-wince*)
os=-wince
;;
@@ -1130,14 +1230,20 @@ case $os in
-atheos*)
os=-atheos
;;
+ -syllable*)
+ os=-syllable
+ ;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
-ns2 )
- os=-nextstep2
+ os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1149,6 +1255,9 @@ case $os in
-sinix*)
os=-sysv4
;;
+ -tpf*)
+ os=-tpf
+ ;;
-triton*)
os=-sysv3
;;
@@ -1176,8 +1285,14 @@ case $os in
-xenix)
os=-xenix
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
;;
-none)
;;
@@ -1210,10 +1325,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
- pdp11-*)
+ pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1240,6 +1359,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
+ or32-*)
+ os=-coff
+ ;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1303,19 +1425,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
- *-gould)
+ *-gould)
os=-sysv
;;
- *-highlevel)
+ *-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
- *-sgi)
+ *-sgi)
os=-irix
;;
- *-siemens)
+ *-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1384,10 +1506,16 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
+ -os400*)
+ vendor=ibm
+ ;;
-ptx*)
vendor=sequent
;;
- -vxsim* | -vxworks*)
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
diff --git a/source/configure.in b/source/configure.in
index e85f604b584..35300151104 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -238,7 +238,7 @@ AC_ARG_ENABLE(debug,
AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
[if eval "test x$enable_developer = xyes"; then
developer=yes
- CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER -O1"
fi])
AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
@@ -3000,12 +3000,10 @@ if test x"$with_ads_support" != x"no"; then
krb5_keytab keytab;
krb5_init_context(&context);
- if (krb5_kt_resolve(context, "WRFILE:api", &keytab))
- exit(0);
- exit(1);
+ return krb5_kt_resolve(context, "WRFILE:api", &keytab);
}],
- samba_cv_HAVE_WRFILE_KEYTAB=no,
- samba_cv_HAVE_WRFILE_KEYTAB=yes)])
+ samba_cv_HAVE_WRFILE_KEYTAB=yes,
+ samba_cv_HAVE_WRFILE_KEYTAB=no)])
if test x"$samba_cv_HAVE_WRFILE_KEYTAB" = x"yes"; then
AC_DEFINE(HAVE_WRFILE_KEYTAB,1,
@@ -4241,7 +4239,36 @@ samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)])
AC_MSG_RESULT(no);
fi
;;
+ *aix*)
+ AC_CACHE_CHECK([for AIX send_file support],samba_cv_HAVE_SENDFILE,[
+ AC_TRY_LINK([\
+#include <sys/socket.h>],
+[\
+ int fromfd, tofd;
+ size_t total=0;
+ struct sf_parms hdtrl;
+ ssize_t nwritten;
+ off64_t offset;
+
+ hdtrl.header_data = 0;
+ hdtrl.header_length = 0;
+ hdtrl.file_descriptor = fromfd;
+ hdtrl.file_offset = 0;
+ hdtrl.file_bytes = 0;
+ hdtrl.trailer_data = 0;
+ hdtrl.trailer_length = 0;
+ nwritten = send_file(&tofd, &hdtrl, 0);
+],
+samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
+ if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then
+ AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
+ AC_DEFINE(AIX_SENDFILE_API,1,[Whether the AIX send_file() API is available])
+ AC_DEFINE(WITH_SENDFILE,1,[Whether to include sendfile() support])
+ else
+ AC_MSG_RESULT(no);
+ fi
+ ;;
*)
;;
esac
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 9a34e02f675..7095997dc8d 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -496,21 +496,19 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
/* This operation happens on session setup, so it should better be fast. We
* store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
-static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
+static NTSTATUS one_alias_membership(const DOM_SID *member,
+ DOM_SID **sids, int *num)
{
fstring key, string_sid;
TDB_DATA kbuf, dbuf;
const char *p;
- *num = 0;
- *sids = NULL;
-
if (!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping\n"));
return NT_STATUS_ACCESS_DENIED;
}
- sid_to_string(string_sid, sid);
+ sid_to_string(string_sid, member);
slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
kbuf.dsize = strlen(key)+1;
@@ -531,7 +529,7 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
if (!string_to_sid(&alias, string_sid))
continue;
- add_sid_to_array(&alias, sids, num);
+ add_sid_to_array_unique(&alias, sids, num);
if (sids == NULL)
return NT_STATUS_NO_MEMORY;
@@ -541,6 +539,22 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
return NT_STATUS_OK;
}
+static NTSTATUS alias_memberships(const DOM_SID *members, int num_members,
+ DOM_SID **sids, int *num)
+{
+ int i;
+
+ *num = 0;
+ *sids = NULL;
+
+ for (i=0; i<num_members; i++) {
+ NTSTATUS status = one_alias_membership(&members[i], sids, num);
+ if (!NT_STATUS_IS_OK(status))
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
{
DOM_SID *sids;
@@ -548,7 +562,7 @@ static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
/* This feels the wrong way round, but the on-disk data structure
* dictates it this way. */
- if (!NT_STATUS_IS_OK(alias_memberships(member, &sids, &num)))
+ if (!NT_STATUS_IS_OK(alias_memberships(member, 1, &sids, &num)))
return False;
for (i=0; i<num; i++) {
@@ -707,7 +721,7 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
pstring key;
fstring sid_string;
- result = alias_memberships(member, &sids, &num);
+ result = alias_memberships(member, 1, &sids, &num);
if (!NT_STATUS_IS_OK(result))
return result;
@@ -1343,10 +1357,11 @@ NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
}
NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num)
{
- return alias_memberships(sid, aliases, num);
+ return alias_memberships(members, num_members, aliases, num);
}
/**********************************************************************
diff --git a/source/include/client.h b/source/include/client.h
index 52a6c76299d..b556538f743 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -27,7 +27,7 @@
overlap on the wire. This size gives us a nice read/write size, which
will be a multiple of the page size on almost any system */
#define CLI_BUFFER_SIZE (0xFFFF)
-
+#define CLI_MAX_LARGE_READX_SIZE (127*1024)
/*
* These definitions depend on smb.h
diff --git a/source/include/includes.h b/source/include/includes.h
index ef0f761ff7d..66ff4fa9f02 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -1202,15 +1202,6 @@ int vasprintf(char **ptr, const char *format, va_list ap);
#define LOG_DEBUG 7 /* debug-level messages */
#endif
-/* NetBSD doesn't have these */
-#ifndef SHM_R
-#define SHM_R 0400
-#endif
-
-#ifndef SHM_W
-#define SHM_W 0200
-#endif
-
#if HAVE_KERNEL_SHARE_MODES
#ifndef LOCK_MAND
#define LOCK_MAND 32 /* This is a mandatory flock */
diff --git a/source/include/passdb.h b/source/include/passdb.h
index 7d3e0014b65..db6bc2ac75e 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -287,6 +287,12 @@ typedef struct pdb_context
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*pdb_enum_group_memberships)(struct pdb_context *context,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups);
+
NTSTATUS (*pdb_find_alias)(struct pdb_context *context,
const char *name, DOM_SID *sid);
@@ -323,9 +329,10 @@ typedef struct pdb_context
DOM_SID **members, int *num_members);
NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
- const DOM_SID *alias,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases,
- int *num);
+ int *num_aliases);
void (*free_fn)(struct pdb_context **);
@@ -378,6 +385,12 @@ typedef struct pdb_methods
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*enum_group_memberships)(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups);
+
NTSTATUS (*find_alias)(struct pdb_methods *methods,
const char *name, DOM_SID *sid);
@@ -408,7 +421,8 @@ typedef struct pdb_methods
const DOM_SID *alias, DOM_SID **members,
int *num_members);
NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num);
void *private_data; /* Private data of some kind */
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index 0c6eee3650a..ee8208e90ea 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -395,6 +395,15 @@ typedef struct bufhdr2_info
}
BUFHDR2;
+/* BUFHDR4 - another buffer header */
+typedef struct bufhdr4_info
+{
+ uint32 size;
+ uint32 buffer;
+
+}
+BUFHDR4;
+
/* BUFFER4 - simple length and buffer */
typedef struct buffer4_info
{
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index 44beb2b8c82..b865d05b340 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -168,7 +168,9 @@ typedef struct net_user_info_3
UNIHDR hdr_logon_dom; /* logon domain unicode string header */
uint32 buffer_dom_id; /* undocumented logon domain id pointer */
- uint8 padding[40]; /* unused padding bytes. expansion room */
+ uint8 lm_sess_key[8]; /* lm session key */
+ uint32 acct_flags; /* account flags */
+ uint32 unknown[7]; /* unknown */
uint32 num_other_sids; /* number of foreign/trusted domain sids */
uint32 buffer_other_sids;
@@ -595,6 +597,27 @@ typedef struct sam_delta_hdr_info
} SAM_DELTA_HDR;
+/* LOCKOUT_STRING */
+typedef struct account_lockout_string {
+ uint32 array_size;
+ uint32 offset;
+ uint32 length;
+/* uint16 *bindata; */
+ UINT64_S lockout_duration;
+ UINT64_S reset_count;
+ uint32 bad_attempt_lockout;
+ uint32 dummy;
+
+} LOCKOUT_STRING;
+
+/* HDR_LOCKOUT_STRING */
+typedef struct hdr_account_lockout_string {
+ uint16 size;
+ uint16 length;
+ uint32 buffer;
+
+} HDR_LOCKOUT_STRING;
+
/* SAM_DOMAIN_INFO (0x1) */
typedef struct sam_domain_info_info
{
@@ -608,16 +631,32 @@ typedef struct sam_domain_info_info
UINT64_S min_pwd_age;
UINT64_S dom_mod_count;
NTTIME creation_time;
+ uint32 security_information;
- BUFHDR2 hdr_sec_desc; /* security descriptor */
- UNIHDR hdr_unknown;
- uint8 reserved[40];
+ BUFHDR4 hdr_sec_desc; /* security descriptor */
+
+ HDR_LOCKOUT_STRING hdr_account_lockout;
+
+ UNIHDR hdr_unknown2;
+ UNIHDR hdr_unknown3;
+ UNIHDR hdr_unknown4;
UNISTR2 uni_dom_name;
- UNISTR2 buf_oem_info; /* never seen */
+ UNISTR2 buf_oem_info;
BUFFER4 buf_sec_desc;
- UNISTR2 buf_unknown;
+
+ LOCKOUT_STRING account_lockout;
+
+ UNISTR2 buf_unknown2;
+ UNISTR2 buf_unknown3;
+ UNISTR2 buf_unknown4;
+
+ uint32 logon_chgpass;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+
} SAM_DOMAIN_INFO;
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index ae603c9cd93..9945f674c82 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -537,6 +537,13 @@ typedef struct sam_unknown_info_7_info
} SAM_UNK_INFO_7;
+typedef struct sam_unknown_info_8_info
+{
+ UINT64_S seq_num;
+ NTTIME domain_create_time;
+
+} SAM_UNK_INFO_8;
+
typedef struct sam_unknown_info_12_inf
{
NTTIME duration;
@@ -554,11 +561,8 @@ typedef struct sam_unknown_info_5_inf
typedef struct sam_unknown_info_2_inf
{
- uint32 unknown_0; /* 0x0000 0000 */
- uint32 unknown_1; /* 0x8000 0000 */
- uint32 unknown_2; /* 0x0000 0000 */
-
- uint32 ptr_0; /* pointer to unknown structure */
+ NTTIME logout; /* whether users are forcibly disconnected when logon hours expire */
+ UNIHDR hdr_comment; /* comment according to samba4 idl */
UNIHDR hdr_domain; /* domain name unicode header */
UNIHDR hdr_server; /* server name unicode header */
@@ -566,8 +570,7 @@ typedef struct sam_unknown_info_2_inf
pointer is referring to
*/
- uint32 seq_num; /* some sort of incrementing sequence number? */
- uint32 unknown_3; /* 0x0000 0000 */
+ UINT64_S seq_num;
uint32 unknown_4; /* 0x0000 0001 */
uint32 unknown_5; /* 0x0000 0003 */
@@ -578,6 +581,7 @@ typedef struct sam_unknown_info_2_inf
uint8 padding[12]; /* 12 bytes zeros */
+ UNISTR2 uni_comment; /* comment unicode string */
UNISTR2 uni_domain; /* domain name unicode string */
UNISTR2 uni_server; /* server name unicode string */
@@ -604,6 +608,7 @@ typedef struct sam_unknown_ctr_info
SAM_UNK_INFO_5 inf5;
SAM_UNK_INFO_6 inf6;
SAM_UNK_INFO_7 inf7;
+ SAM_UNK_INFO_8 inf8;
SAM_UNK_INFO_12 inf12;
} info;
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
index 58502ec34e7..47f336cdb7a 100644
--- a/source/include/smbldap.h
+++ b/source/include/smbldap.h
@@ -139,6 +139,7 @@ BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
struct smbldap_state {
LDAP *ldap_struct;
+ pid_t pid;
time_t last_ping;
/* retrive-once info */
const char *uri;
diff --git a/source/include/smbprofile.h b/source/include/smbprofile.h
index e494faf7da6..ed6fce9a6d6 100644
--- a/source/include/smbprofile.h
+++ b/source/include/smbprofile.h
@@ -34,7 +34,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
#define PROF_SHMEM_KEY ((key_t)0x07021999)
#define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 9
+#define PROF_SHM_VERSION 10
/* time values in the following structure are in microseconds */
@@ -47,6 +47,12 @@ struct profile_stats {
unsigned syscall_opendir_time;
unsigned syscall_readdir_count;
unsigned syscall_readdir_time;
+ unsigned syscall_seekdir_count;
+ unsigned syscall_seekdir_time;
+ unsigned syscall_telldir_count;
+ unsigned syscall_telldir_time;
+ unsigned syscall_rewinddir_count;
+ unsigned syscall_rewinddir_time;
unsigned syscall_mkdir_count;
unsigned syscall_mkdir_time;
unsigned syscall_rmdir_count;
diff --git a/source/include/trans2.h b/source/include/trans2.h
index 3106cd092ab..b1fe2d9d832 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -329,6 +329,13 @@ Byte offset Type name description
#define SMB_FS_FULL_SIZE_INFORMATION 1007
#define SMB_FS_OBJECTID_INFORMATION 1008
+/* flags on trans2 findfirst/findnext that control search */
+#define FLAG_TRANS2_FIND_CLOSE 0x1
+#define FLAG_TRANS2_FIND_CLOSE_IF_END 0x2
+#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4
+#define FLAG_TRANS2_FIND_CONTINUE 0x8
+#define FLAG_TRANS2_FIND_BACKUP_INTENT 0x10
+
/* UNIX CIFS Extensions - created by HP */
/*
* UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.
@@ -452,4 +459,81 @@ Offset Size Name
/* ... more as we think of them :-). */
+/* SMB POSIX ACL definitions. */
+/* Wire format is (all little endian) :
+
+[2 bytes] - Version number.
+[2 bytes] - Number of ACE entries to follow.
+[2 bytes] - Number of default ACE entries to follow.
+-------------------------------------
+^
+|
+ACE entries
+|
+v
+-------------------------------------
+^
+|
+Default ACE entries
+|
+v
+-------------------------------------
+
+Where an ACE entry looks like :
+
+[1 byte] - Entry type.
+
+Entry types are :
+
+ACL_USER_OBJ 0x01
+ACL_USER 0x02
+ACL_GROUP_OBJ 0x04
+ACL_GROUP 0x08
+ACL_MASK 0x10
+ACL_OTHER 0x20
+
+[1 byte] - permissions (perm_t)
+
+perm_t types are :
+
+ACL_READ 0x04
+ACL_WRITE 0x02
+ACL_EXECUTE 0x01
+
+[8 bytes] - uid/gid to apply this permission to.
+
+In the same format as the uid/gid fields in the other
+UNIX extensions definitions. Use 0xFFFFFFFFFFFFFFFF for
+the MASK and OTHER entry types.
+
+If the Number of ACE entries for either file or default ACE's
+is set to 0xFFFF this means ignore this kind of ACE (and the
+number of entries sent will be zero.
+
+*/
+
+/* The query/set info levels for POSIX ACLs. */
+#define SMB_QUERY_POSIX_ACL 0x204
+#define SMB_SET_POSIX_ACL 0x204
+
+/* Current on the wire ACL version. */
+#define SMB_POSIX_ACL_VERSION 1
+
+/* ACE entry type. */
+#define SMB_POSIX_ACL_USER_OBJ 0x01
+#define SMB_POSIX_ACL_USER 0x02
+#define SMB_POSIX_ACL_GROUP_OBJ 0x04
+#define SMB_POSIX_ACL_GROUP 0x08
+#define SMB_POSIX_ACL_MASK 0x10
+#define SMB_POSIX_ACL_OTHER 0x20
+
+/* perm_t types. */
+#define SMB_POSIX_ACL_READ 0x04
+#define SMB_POSIX_ACL_WRITE 0x02
+#define SMB_POSIX_ACL_EXECUTE 0x01
+
+#define SMB_POSIX_ACL_HEADER_SIZE 6
+#define SMB_POSIX_ACL_ENTRY_SIZE 10
+
+#define SMB_POSIX_IGNORE_ACE_ENTRIES 0xFFFF
#endif
diff --git a/source/include/vfs.h b/source/include/vfs.h
index db766b985d9..e8c6ff32d55 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
VFS structures and parameters
- Copyright (C) Jeremy Allison 1999-2003
+ Copyright (C) Jeremy Allison 1999-2004
Copyright (C) Tim Potter 1999
Copyright (C) Alexander Bokovoy 2002
Copyright (C) Stefan (metze) Metzmacher 2003
@@ -55,7 +55,8 @@
/* Changed to version 8 includes EA calls. JRA. */
/* Changed to version 9 to include the get_shadow_data call. --metze */
/* Changed to version 10 to include pread/pwrite calls. */
-#define SMB_VFS_INTERFACE_VERSION 10
+/* Changed to version 11 to include seekdir/telldir/rewinddir calls. JRA */
+#define SMB_VFS_INTERFACE_VERSION 11
/* to bug old modules witch are trying to compile with the old functions */
@@ -102,6 +103,9 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_OPENDIR,
SMB_VFS_OP_READDIR,
+ SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_OP_TELLDIR,
+ SMB_VFS_OP_REWINDDIR,
SMB_VFS_OP_MKDIR,
SMB_VFS_OP_RMDIR,
SMB_VFS_OP_CLOSEDIR,
@@ -209,7 +213,10 @@ struct vfs_ops {
/* Directory operations */
DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname);
- struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp, long offset);
+ long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ void (*rewind_dir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir);
@@ -310,6 +317,9 @@ struct vfs_ops {
struct vfs_handle_struct *opendir;
struct vfs_handle_struct *readdir;
+ struct vfs_handle_struct *seekdir;
+ struct vfs_handle_struct *telldir;
+ struct vfs_handle_struct *rewind_dir;
struct vfs_handle_struct *mkdir;
struct vfs_handle_struct *rmdir;
struct vfs_handle_struct *closedir;
diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
index 1ec1c5a7789..79f5bbf3c16 100644
--- a/source/include/vfs_macros.h
+++ b/source/include/vfs_macros.h
@@ -38,6 +38,9 @@
/* Directory operations */
#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewinddir((conn)->vfs.handles.rewinddir, (conn), (dirp)))
#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
@@ -136,6 +139,9 @@
/* Directory operations */
#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewinddir((conn)->vfs_opaque.handles.rewinddir, (conn), (dirp)))
#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
@@ -234,6 +240,10 @@
/* Directory operations */
#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
#define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (conn), (dirp)))
+#define SMB_VFS_NEXT_DIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
#define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path)))
#define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir))
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index 6bd3c76ca1f..aa593832584 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -149,7 +149,7 @@ BOOL account_policy_get(int field, uint32 *value)
return False;
}
if (!tdb_fetch_uint32(tdb, name, value)) {
- DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for efild %d (%s), returning 0", field, name));
+ DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
return False;
}
DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
diff --git a/source/lib/afs.c b/source/lib/afs.c
index 8688fde6b1c..5ff027ee01d 100644
--- a/source/lib/afs.c
+++ b/source/lib/afs.c
@@ -124,9 +124,13 @@ static BOOL afs_createtoken(const char *username, const char *cell,
p += 8;
- /* Ticket lifetime. We fake everything here, so go as long as
- possible. This is in 5-minute intervals, so 255 is 21 hours
- and 15 minutes.*/
+ /* This is a kerberos 4 life time. The life time is expressed
+ * in units of 5 minute intervals up to 38400 seconds, after
+ * that a table is used up to lifetime 0xBF. Values between
+ * 0xC0 and 0xFF is undefined. 0xFF is defined to be the
+ * infinite time that never expire.
+ *
+ * So here we cheat and use the infinite time */
*p = 255;
p += 1;
@@ -135,7 +139,11 @@ static BOOL afs_createtoken(const char *username, const char *cell,
SIVAL(p, 0, now);
ct->BeginTimestamp = now;
- ct->EndTimestamp = now + (255*60*5);
+ if(lp_afs_token_lifetime() == 0)
+ ct->EndTimestamp = NEVERDATE;
+ else
+ ct->EndTimestamp = now + lp_afs_token_lifetime();
+
if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
ct->BeginTimestamp += 1; /* Lifetime must be even */
}
diff --git a/source/lib/afs_settoken.c b/source/lib/afs_settoken.c
index 5c646c72e48..2e74328d5d6 100644
--- a/source/lib/afs_settoken.c
+++ b/source/lib/afs_settoken.c
@@ -53,7 +53,7 @@ static BOOL afs_decode_token(const char *string, char **cell,
DATA_BLOB blob;
struct ClearToken result_ct;
- char *s = strdup(string);
+ char *s = SMB_STRDUP(string);
char *t;
@@ -62,7 +62,7 @@ static BOOL afs_decode_token(const char *string, char **cell,
return False;
}
- *cell = strdup(t);
+ *cell = SMB_STRDUP(t);
if ((t = strtok(NULL, "\n")) == NULL) {
DEBUG(10, ("strtok failed\n"));
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index dc00ca4cf4b..b9b9d90db67 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -84,6 +84,15 @@ static const char *charset_name(charset_t ch)
}
ret = ln;
}
+#ifdef HAVE_SETLOCALE
+ /* We set back the locale to C to get ASCII-compatible toupper/lower functions.
+ For now we do not need any other POSIX localisations anyway. When we should
+ really need localized string functions one day we need to write our own
+ ascii_tolower etc.
+ */
+ setlocale(LC_ALL, "C");
+ #endif
+
#endif
if (!ret || !*ret) ret = "ASCII";
@@ -372,7 +381,7 @@ size_t convert_string(charset_t from, charset_t to,
unsigned char *q = (unsigned char *)dest;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
size_t retval = 0;
/* If all characters are ascii, fast path here. */
@@ -408,7 +417,7 @@ size_t convert_string(charset_t from, charset_t to,
size_t retval = 0;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
/* If all characters are ascii, fast path here. */
while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
@@ -444,7 +453,7 @@ size_t convert_string(charset_t from, charset_t to,
size_t retval = 0;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
/* If all characters are ascii, fast path here. */
while (slen && (dlen >= 2)) {
diff --git a/source/lib/module.c b/source/lib/module.c
index c5bf89bd980..49121d12ca1 100644
--- a/source/lib/module.c
+++ b/source/lib/module.c
@@ -40,9 +40,12 @@ static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe)
*/
handle = sys_dlopen(module_name, RTLD_LAZY);
+ /* This call should reset any possible non-fatal errors that
+ occured since last call to dl* functions */
+ error = sys_dlerror();
+
if(!handle) {
int level = is_probe ? 3 : 0;
- error = sys_dlerror();
DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : ""));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index 92514342b23..a0cbfd2ee21 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -167,8 +167,17 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot
}
}
- pstrcpy_wa(p, pattern);
- pstrcpy_wa(s, string);
+ if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) {
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ return -1;
+ }
+
+ if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) {
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ return -1;
+ }
if (protocol <= PROTOCOL_LANMAN2) {
/*
diff --git a/source/lib/replace.c b/source/lib/replace.c
index fe1cfc04eb1..298707727e9 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -205,7 +205,7 @@ Corrections by richard.kettlewell@kewill.com
struct group *g;
char *gr;
- if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) {
+ if((grouplst = SMB_MALLOC_ARRAY(gid_t, max_gr)) == NULL) {
DEBUG(0,("initgroups: malloc fail !\n"));
return -1;
}
@@ -311,6 +311,11 @@ needs.
/****************************************************************************
duplicate a string
****************************************************************************/
+
+#ifdef strdup
+#undef strdup
+#endif
+
char *strdup(const char *s)
{
size_t len;
@@ -319,7 +324,7 @@ duplicate a string
if (!s) return(NULL);
len = strlen(s)+1;
- ret = (char *)malloc(len);
+ ret = (char *)SMB_MALLOC(len);
if (!ret) return(NULL);
memcpy(ret,s,len);
return(ret);
@@ -415,7 +420,7 @@ char *rep_inet_ntoa(struct in_addr ip)
#ifndef HAVE_VSYSLOG
#ifdef HAVE_SYSLOG
- void vsyslog (int facility_priority, char *format, va_list arglist)
+ void vsyslog (int facility_priority, const char *format, va_list arglist)
{
char *msg = NULL;
vasprintf(&msg, format, arglist);
diff --git a/source/lib/sendfile.c b/source/lib/sendfile.c
index 4aa76a0c74a..f9f33b8f35e 100644
--- a/source/lib/sendfile.c
+++ b/source/lib/sendfile.c
@@ -65,8 +65,20 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
nwritten = sendfile(tofd, fromfd, &offset, total);
#endif
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
total -= nwritten;
@@ -131,8 +143,20 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
do {
nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
small_total -= nwritten;
@@ -250,7 +274,7 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
hdtrl[0].iov_len = hdr_len = 0;
}
hdtrl[1].iov_base = NULL;
- hdtrl[1].iov_base = 0;
+ hdtrl[1].iov_len = 0;
total = count;
while (total + hdtrl[0].iov_len) {
@@ -371,6 +395,62 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
return count + hdr_len;
}
+#elif defined(AIX_SENDFILE_API)
+
+/* BEGIN AIX SEND_FILE */
+
+/* Contributed by William Jojo <jojowil@hvcc.edu> */
+#include <sys/socket.h>
+
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
+{
+ size_t total=0;
+ struct sf_parms hdtrl;
+
+ /* Set up the header/trailer struct params. */
+ if (header) {
+ hdtrl.header_data = header->data;
+ hdtrl.header_length = header->length;
+ } else {
+ hdtrl.header_data = NULL;
+ hdtrl.header_length = 0;
+ }
+ hdtrl.trailer_data = NULL;
+ hdtrl.trailer_length = 0;
+
+ hdtrl.file_descriptor = fromfd;
+ hdtrl.file_offset = offset;
+ hdtrl.file_bytes = count;
+
+ while ( hdtrl.file_bytes + hdtrl.header_length ) {
+ ssize_t ret;
+
+ /*
+ Return Value
+
+ There are three possible return values from send_file:
+
+ Value Description
+
+ -1 an error has occurred, errno contains the error code.
+
+ 0 the command has completed successfully.
+
+ 1 the command was completed partially, some data has been
+ transmitted but the command has to return for some reason,
+ for example, the command was interrupted by signals.
+ */
+ do {
+ ret = send_file(&tofd, &hdtrl, 0);
+ } while ( (ret == 1) || (ret == -1 && errno == EINTR) );
+ if ( ret == -1 )
+ return -1;
+ }
+
+ return count + header->length;
+}
+/* END AIX SEND_FILE */
+
#else /* No sendfile implementation. Return error. */
ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 3278c8d913a..4afafde9bb6 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -906,6 +906,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
ldap_state->last_ping = time(NULL);
+ ldap_state->pid = sys_getpid();
DEBUG(4,("The LDAP server is succesfully connected\n"));
return LDAP_SUCCESS;
@@ -964,6 +965,9 @@ static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
got_alarm = False;
old_handler = CatchSignal(SIGALRM, gotalarm_sig);
alarm(endtime - now);
+
+ if (ldap_state->pid != sys_getpid())
+ smbldap_close(ldap_state);
}
while (1) {
@@ -973,6 +977,7 @@ static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
*attempts += 1;
+ smbldap_close(ldap_state);
open_rc = smbldap_open(ldap_state);
if (open_rc == LDAP_SUCCESS) {
diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c
index 9b5bef00e8a..4484810884d 100644
--- a/source/lib/sysacls.c
+++ b/source/lib/sysacls.c
@@ -612,7 +612,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
*/
len = 0;
maxlen = 20 * acl_d->count;
- if ((text = malloc(maxlen)) == NULL) {
+ if ((text = SMB_MALLOC(maxlen)) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -690,7 +690,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
maxlen += nbytes + 20 * (acl_d->count - i);
- if ((text = Realloc(oldtext, maxlen)) == NULL) {
+ if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
SAFE_FREE(oldtext);
errno = ENOMEM;
return NULL;
@@ -722,7 +722,7 @@ SMB_ACL_T sys_acl_init(int count)
* acl[] array, this actually allocates an ACL with room
* for (count+1) entries
*/
- if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -886,7 +886,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
* allocate a temporary buffer for the complete ACL
*/
acl_count = acc_acl->count + def_acl->count;
- acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
+ acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
if (acl_buf == NULL) {
sys_acl_free_acl(tmp_acl);
@@ -1243,7 +1243,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
*/
len = 0;
maxlen = 20 * acl_d->count;
- if ((text = malloc(maxlen)) == NULL) {
+ if ((text = SMB_MALLOC(maxlen)) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -1321,7 +1321,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
maxlen += nbytes + 20 * (acl_d->count - i);
- if ((text = Realloc(oldtext, maxlen)) == NULL) {
+ if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
free(oldtext);
errno = ENOMEM;
return NULL;
@@ -1353,7 +1353,7 @@ SMB_ACL_T sys_acl_init(int count)
* acl[] array, this actually allocates an ACL with room
* for (count+1) entries
*/
- if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -1819,7 +1819,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
* allocate a temporary buffer for the complete ACL
*/
acl_count = acc_acl->count + def_acl->count;
- acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
+ acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
if (acl_buf == NULL) {
sys_acl_free_acl(tmp_acl);
@@ -1982,7 +1982,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
{
SMB_ACL_T a;
- if ((a = malloc(sizeof(*a))) == NULL) {
+ if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -1999,7 +1999,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
{
SMB_ACL_T a;
- if ((a = malloc(sizeof(*a))) == NULL) {
+ if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -2056,7 +2056,7 @@ SMB_ACL_T sys_acl_init(int count)
return NULL;
}
- if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
@@ -2282,7 +2282,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
DEBUG(10,("Entering sys_acl_get_file\n"));
DEBUG(10,("path_p is %s\n",path_p));
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno=ENOMEM;
@@ -2313,7 +2313,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
if(acl_entry_link_head == NULL)
return(NULL);
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
@@ -2348,8 +2348,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
* and already has entryp allocated. */
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)
- malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
SAFE_FREE(file_acl);
@@ -2360,7 +2359,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
@@ -2419,7 +2418,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
for( i = 1; i < 4; i++) {
DEBUG(10,("i is %d\n",i));
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
@@ -2429,7 +2428,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
@@ -2496,7 +2495,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
DEBUG(10,("Entering sys_acl_get_fd\n"));
DEBUG(10,("fd is %d\n",fd));
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno=ENOMEM;
@@ -2529,7 +2528,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
return(NULL);
}
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
@@ -2566,7 +2565,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
* and already has entryp allocated. */
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
@@ -2575,7 +2574,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
}
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
@@ -2634,7 +2633,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
for( i = 1; i < 4; i++) {
DEBUG(10,("i is %d\n",i));
if(acl_entry_link_head->count != 0){
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
@@ -2644,7 +2643,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
@@ -2723,7 +2722,7 @@ SMB_ACL_T sys_acl_init( int count)
DEBUG(10,("Entering sys_acl_init\n"));
- theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ theacl = SMB_MALLOC_P(struct acl_entry_link);
if(theacl == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_init is %d\n",errno));
@@ -2758,7 +2757,7 @@ int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
}
if(theacl->count != 0){
- temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
@@ -2770,7 +2769,7 @@ int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
}
- *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(*pentry == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
@@ -2860,7 +2859,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
return(0);
acl_length = BUFSIZ;
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno = ENOMEM;
@@ -2893,7 +2892,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
acl_length += sizeof(struct acl_entry);
- file_acl_temp = (struct acl *)malloc(acl_length);
+ file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
if(file_acl_temp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
@@ -2948,7 +2947,7 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
DEBUG(10,("Entering sys_acl_set_fd\n"));
acl_length = BUFSIZ;
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno = ENOMEM;
@@ -2982,7 +2981,7 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
acl_length += sizeof(struct acl_entry);
- file_acl_temp = (struct acl *)malloc(acl_length);
+ file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
if(file_acl_temp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
diff --git a/source/lib/sysquotas.c b/source/lib/sysquotas.c
index 1c5c7e8bd4f..61e2382bc9d 100644
--- a/source/lib/sysquotas.c
+++ b/source/lib/sysquotas.c
@@ -73,9 +73,9 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
continue ;
if (S.st_dev == devno) {
- (*mntpath) = strdup(mnt->mnt_dir);
- (*bdev) = strdup(mnt->mnt_fsname);
- (*fs) = strdup(mnt->mnt_type);
+ (*mntpath) = SMB_STRDUP(mnt->mnt_dir);
+ (*bdev) = SMB_STRDUP(mnt->mnt_fsname);
+ (*fs) = SMB_STRDUP(mnt->mnt_type);
if ((*mntpath)&&(*bdev)&&(*fs)) {
ret = 0;
} else {
@@ -124,8 +124,8 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
* but I don't know how
* --metze
*/
- (*mntpath) = strdup(path);
- (*bdev) = strdup(dev_disk);
+ (*mntpath) = SMB_STRDUP(path);
+ (*bdev) = SMB_STRDUP(dev_disk);
if ((*mntpath)&&(*bdev)) {
ret = 0;
} else {
@@ -152,7 +152,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
(*bdev) = NULL;
(*fs) = NULL;
- (*mntpath) = strdup(path);
+ (*mntpath) = SMB_STRDUP(path);
if (*mntpath) {
ret = 0;
} else {
diff --git a/source/lib/system.c b/source/lib/system.c
index 8b5105d11de..7434cbe35ee 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -362,6 +362,19 @@ FILE *sys_fopen(const char *path, const char *type)
}
/*******************************************************************
+ An opendir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+DIR *sys_opendir(const char *name)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
+ return opendir64(name);
+#else
+ return opendir(name);
+#endif
+}
+
+/*******************************************************************
A readdir wrapper that will deal with 64 bit filesizes.
********************************************************************/
@@ -375,6 +388,58 @@ SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
}
/*******************************************************************
+ A seekdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_seekdir(DIR *dirp, long offset)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
+ seekdir64(dirp, offset);
+#else
+ seekdir(dirp, offset);
+#endif
+}
+
+/*******************************************************************
+ A telldir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+long sys_telldir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
+ return (long)telldir64(dirp);
+#else
+ return (long)telldir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A rewinddir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_rewinddir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
+ rewinddir64(dirp);
+#else
+ rewinddir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A close wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+int sys_closedir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
+ return closedir64(dirp);
+#else
+ return closedir(dirp);
+#endif
+}
+
+/*******************************************************************
An mknod() wrapper that will deal with 64 bit filesizes.
********************************************************************/
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
index 693dbf68d91..eed607ee8fb 100644
--- a/source/lib/system_smbd.c
+++ b/source/lib/system_smbd.c
@@ -109,7 +109,7 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in
}
#endif
-int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
+static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
char *p;
int retval;
@@ -139,3 +139,91 @@ int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
return retval;
}
+
+BOOL getgroups_user(const char *user, gid_t primary_gid,
+ gid_t **ret_groups, int *ngroups)
+{
+ int ngrp, max_grp;
+ gid_t *temp_groups;
+ gid_t *groups;
+ int i;
+
+ max_grp = groups_max();
+ temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
+ if (! temp_groups) {
+ return False;
+ }
+
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
+
+ gid_t *groups_tmp;
+
+ groups_tmp = SMB_REALLOC_ARRAY(temp_groups, gid_t, max_grp);
+
+ if (!groups_tmp) {
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ temp_groups = groups_tmp;
+
+ if (sys_getgrouplist(user, primary_gid,
+ temp_groups, &max_grp) == -1) {
+ DEBUG(0, ("get_user_groups: failed to get the unix "
+ "group list\n"));
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ }
+
+ ngrp = 0;
+ groups = NULL;
+
+ /* Add in primary group first */
+ add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+
+ for (i=0; i<max_grp; i++)
+ add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+
+ *ngroups = ngrp;
+ *ret_groups = groups;
+ SAFE_FREE(temp_groups);
+ return True;
+}
+
+NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids,
+ gid_t **gids,
+ int *num_groups)
+{
+ int i;
+
+ if (!getgroups_user(username, primary_gid, gids, num_groups)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (*num_groups == 0) {
+ smb_panic("primary group missing");
+ }
+
+ *sids = SMB_MALLOC_ARRAY(DOM_SID, *num_groups);
+
+ if (*sids == NULL) {
+ SAFE_FREE(gids);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<*num_groups; i++) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&(*sids)[i], (*gids)[i]))) {
+ DEBUG(1, ("get_user_groups: failed to convert "
+ "gid %ld to a sid!\n",
+ (long int)(*gids)[i+1]));
+ SAFE_FREE(*sids);
+ SAFE_FREE(*gids);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 00afdded83c..4d66ed96558 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -52,7 +52,7 @@
#endif /* WITH_NISPLUS_HOME */
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
-int Protocol = PROTOCOL_COREPLUS;
+enum protocol_types Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
@@ -963,7 +963,7 @@ void *Realloc(void *p,size_t size)
/****************************************************************************
Type-safe realloc.
****************************************************************************/
-
+
void *realloc_array(void *p,size_t el_size, unsigned int count)
{
if (count >= MAX_ALLOC_SIZE/el_size) {
@@ -2239,6 +2239,7 @@ char *smb_xstrdup(const char *s)
if (!s1)
smb_panic("smb_xstrdup: malloc fail\n");
return s1;
+
}
/**
diff --git a/source/lib/util_pw.c b/source/lib/util_pw.c
index 8db41e8b8be..0d7ffe09e9b 100644
--- a/source/lib/util_pw.c
+++ b/source/lib/util_pw.c
@@ -52,10 +52,40 @@ void passwd_free (struct passwd **buf)
SAFE_FREE(*buf);
}
+#define PWNAMCACHE_SIZE 4
+static struct passwd *pwnam_cache[PWNAMCACHE_SIZE];
+static BOOL pwnam_cache_initialized = False;
+
+static void init_pwnam_cache(void)
+{
+ int i;
+
+ if (pwnam_cache_initialized)
+ return;
+
+ for (i=0; i<PWNAMCACHE_SIZE; i++)
+ pwnam_cache[i] = NULL;
+
+ pwnam_cache_initialized = True;
+ return;
+}
+
struct passwd *getpwnam_alloc(const char *name)
{
+ int i;
+
struct passwd *temp;
+ init_pwnam_cache();
+
+ for (i=0; i<PWNAMCACHE_SIZE; i++) {
+ if ((pwnam_cache[i] != NULL) &&
+ (strcmp(name, pwnam_cache[i]->pw_name) == 0)) {
+ DEBUG(10, ("Got %s from pwnam_cache\n", name));
+ return alloc_copy_passwd(pwnam_cache[i]);
+ }
+ }
+
temp = sys_getpwnam(name);
if (!temp) {
@@ -67,6 +97,19 @@ struct passwd *getpwnam_alloc(const char *name)
return NULL;
}
+ for (i=0; i<PWNAMCACHE_SIZE; i++) {
+ if (pwnam_cache[i] == NULL)
+ break;
+ }
+
+ if (i == PWNAMCACHE_SIZE)
+ i = rand() % PWNAMCACHE_SIZE;
+
+ if (pwnam_cache[i] != NULL)
+ passwd_free(&pwnam_cache[i]);
+
+ pwnam_cache[i] = alloc_copy_passwd(temp);
+
return alloc_copy_passwd(temp);
}
diff --git a/source/lib/util_smbd.c b/source/lib/util_smbd.c
index 153dbdbd02f..586362c1e4c 100644
--- a/source/lib/util_smbd.c
+++ b/source/lib/util_smbd.c
@@ -37,25 +37,20 @@
NOTE! uses become_root() to gain correct priviages on systems
that lack a native getgroups() call (uses initgroups and getgroups)
*/
-BOOL getgroups_user(const char *user, gid_t **ret_groups, int *ngroups)
+BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int *ngroups)
{
- struct passwd *pwd;
int ngrp, max_grp;
gid_t *temp_groups;
gid_t *groups;
int i;
- pwd = getpwnam_alloc(user);
- if (!pwd) return False;
-
max_grp = groups_max();
temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
if (! temp_groups) {
- passwd_free(&pwd);
return False;
}
- if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
gid_t *groups_tmp;
@@ -67,9 +62,8 @@ BOOL getgroups_user(const char *user, gid_t **ret_groups, int *ngroups)
}
temp_groups = groups_tmp;
- if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- passwd_free(&pwd);
SAFE_FREE(temp_groups);
return False;
}
@@ -79,9 +73,7 @@ BOOL getgroups_user(const char *user, gid_t **ret_groups, int *ngroups)
groups = NULL;
/* Add in primary group first */
- add_gid_to_array_unique(pwd->pw_gid, &groups, &ngrp);
-
- passwd_free(&pwd);
+ add_gid_to_array_unique(primary_gid, &groups, &ngrp);
for (i=0; i<max_grp; i++)
add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 8c16533bf96..58bc5ed6fe4 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -798,6 +798,156 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
}
/****************************************************************************
+ Create an outgoing TCP socket to any of the addrs. This is for
+ simultaneous connects to port 445 and 139 of a host or even a variety
+ of DC's all of which are equivalent for our purposes.
+**************************************************************************/
+
+BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
+ int timeout, int *fd_index, int *fd)
+{
+ int i, resulting_index, res;
+ int *sockets;
+ BOOL good_connect;
+
+ fd_set r_fds, wr_fds;
+ struct timeval tv;
+ int maxfd;
+
+ int connect_loop = 10000; /* 10 milliseconds */
+
+ timeout *= 1000; /* convert to microseconds */
+
+ sockets = SMB_MALLOC_ARRAY(int, num_addrs);
+
+ if (sockets == NULL)
+ return False;
+
+ resulting_index = -1;
+
+ for (i=0; i<num_addrs; i++)
+ sockets[i] = -1;
+
+ for (i=0; i<num_addrs; i++) {
+ sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
+ if (sockets[i] < 0)
+ goto done;
+ set_blocking(sockets[i], False);
+ }
+
+ connect_again:
+ good_connect = False;
+
+ for (i=0; i<num_addrs; i++) {
+
+ if (sockets[i] == -1)
+ continue;
+
+ if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),
+ sizeof(*addrs)) == 0) {
+ /* Rather unlikely as we are non-blocking, but it
+ * might actually happen. */
+ resulting_index = i;
+ goto done;
+ }
+
+ if (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN) {
+ /* These are the error messages that something is
+ progressing. */
+ good_connect = True;
+ } else if (errno != 0) {
+ /* There was a direct error */
+ close(sockets[i]);
+ sockets[i] = -1;
+ }
+ }
+
+ if (!good_connect) {
+ /* All of the connect's resulted in real error conditions */
+ goto done;
+ }
+
+ /* Lets see if any of the connect attempts succeeded */
+
+ maxfd = 0;
+ FD_ZERO(&wr_fds);
+ FD_ZERO(&r_fds);
+
+ for (i=0; i<num_addrs; i++) {
+ if (sockets[i] == -1)
+ continue;
+ FD_SET(sockets[i], &wr_fds);
+ FD_SET(sockets[i], &r_fds);
+ if (sockets[i]>maxfd)
+ maxfd = sockets[i];
+ }
+
+ tv.tv_sec = 0;
+ tv.tv_usec = connect_loop;
+
+ res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
+
+ if (res < 0)
+ goto done;
+
+ if (res == 0)
+ goto next_round;
+
+ for (i=0; i<num_addrs; i++) {
+
+ if (sockets[i] == -1)
+ continue;
+
+ /* Stevens, Network Programming says that if there's a
+ * successful connect, the socket is only writable. Upon an
+ * error, it's both readable and writable. */
+
+ if (FD_ISSET(sockets[i], &r_fds) &&
+ FD_ISSET(sockets[i], &wr_fds)) {
+ /* readable and writable, so it's an error */
+ close(sockets[i]);
+ sockets[i] = -1;
+ continue;
+ }
+
+ if (!FD_ISSET(sockets[i], &r_fds) &&
+ FD_ISSET(sockets[i], &wr_fds)) {
+ /* Only writable, so it's connected */
+ resulting_index = i;
+ goto done;
+ }
+ }
+
+ next_round:
+
+ timeout -= connect_loop;
+ if (timeout <= 0)
+ goto done;
+ connect_loop *= 1.5;
+ if (connect_loop > timeout)
+ connect_loop = timeout;
+ goto connect_again;
+
+ done:
+ for (i=0; i<num_addrs; i++) {
+ if (i == resulting_index)
+ continue;
+ if (sockets[i] >= 0)
+ close(sockets[i]);
+ }
+
+ if (resulting_index >= 0) {
+ *fd_index = resulting_index;
+ *fd = sockets[*fd_index];
+ set_blocking(*fd, True);
+ }
+
+ free(sockets);
+
+ return (resulting_index >= 0);
+}
+/****************************************************************************
Open a connected UDP socket to host on port
**************************************************************************/
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index c6b6570f5c4..6ebada94d71 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1527,6 +1527,9 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
/**
Some platforms don't have strndup.
**/
+#if defined(PARANOID_MALLOC_CHECKER)
+#undef strndup
+#endif
char *strndup(const char *s, size_t n)
{
@@ -1541,6 +1544,11 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
return ret;
}
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
+#endif
+
#endif
#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index d3423d9f239..bb9d69b164d 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -708,16 +708,6 @@ BOOL trim_string_w(smb_ucs2_t *s, const smb_ucs2_t *front,
The char* arguments must NOT be multibyte - to be completely sure
of this only pass string constants */
-
-void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
-{
- int i;
- for (i=0;i<PSTRING_LEN;i++) {
- dest[i] = UCS2_CHAR(src[i]);
- if (src[i] == 0) return;
- }
-}
-
int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
diff --git a/source/libads/ads_status.c b/source/libads/ads_status.c
index 463f647f9c7..536ef766e37 100644
--- a/source/libads/ads_status.c
+++ b/source/libads/ads_status.c
@@ -96,11 +96,9 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
*/
const char *ads_errstr(ADS_STATUS status)
{
- uint32 msg_ctx;
static char *ret;
SAFE_FREE(ret);
- msg_ctx = 0;
switch (status.error_type) {
case ENUM_ADS_ERROR_SYSTEM:
@@ -116,9 +114,12 @@ const char *ads_errstr(ADS_STATUS status)
#ifdef HAVE_GSSAPI
case ENUM_ADS_ERROR_GSS:
{
+ uint32 msg_ctx;
uint32 minor;
-
gss_buffer_desc msg1, msg2;
+
+ msg_ctx = 0;
+
msg1.value = NULL;
msg2.value = NULL;
gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE,
diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c
index a38f3c35b1a..b08e28e0ba4 100644
--- a/source/libads/kerberos.c
+++ b/source/libads/kerberos.c
@@ -320,6 +320,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx,
krb5_auth_context auth_context = NULL;
krb5_error_code err = 0;
+ ZERO_STRUCT(creds);
+
asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm());
if (machine_account == NULL) {
goto out;
@@ -340,7 +342,6 @@ static krb5_error_code get_service_ticket(krb5_context ctx,
ticket to ourselves. */
/* Set up the enctype and client and server principal fields for krb5_get_credentials. */
- memset(&creds, '\0', sizeof(creds));
kerberos_set_creds_enctype(&creds, enctype);
if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) {
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 541472ffd27..c18e253f7b2 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -67,6 +67,40 @@ static void gotalarm_sig(void)
return ldp;
}
+static int ldap_search_with_timeout(LDAP *ld,
+ LDAP_CONST char *base,
+ int scope,
+ LDAP_CONST char *filter,
+ char **attrs,
+ int attrsonly,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls,
+ struct timeval *timeout,
+ int sizelimit,
+ LDAPMessage **res )
+{
+ int result;
+
+ /* Setup timeout */
+ gotalarm = 0;
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(lp_ldap_timeout());
+ /* End setup timeout. */
+
+ result = ldap_search_ext_s(ld, base, scope, filter, attrs,
+ attrsonly, sctrls, cctrls, timeout,
+ sizelimit, res);
+
+ /* Teardown timeout. */
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ alarm(0);
+
+ if (gotalarm != 0)
+ return LDAP_TIMELIMIT_EXCEEDED;
+
+ return result;
+}
+
/*
try a connection to a given ldap server, returning True and setting the servers IP
in the ads struct if successful
@@ -468,15 +502,17 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
*/
ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, controls,
- NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
+ search_attrs, 0, controls,
+ NULL, NULL, LDAP_NO_LIMIT,
+ (LDAPMessage **)res);
ber_free(cookie_be, 1);
ber_bvfree(cookie_bv);
if (rc) {
- DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc)));
+ DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr,
+ ldap_err2string(rc)));
goto done;
}
@@ -659,9 +695,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
/* see the note in ads_do_paged_search - we *must* disable referrals */
ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, NULL, NULL,
- &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
+ search_attrs, 0, NULL, NULL,
+ &timeout, LDAP_NO_LIMIT,
+ (LDAPMessage **)res);
if (rc == LDAP_SIZELIMIT_EXCEEDED) {
DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n"));
diff --git a/source/libads/util.c b/source/libads/util.c
index f5b88735387..4a4d90d7fbc 100644
--- a/source/libads/util.c
+++ b/source/libads/util.c
@@ -62,7 +62,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
failed:
SAFE_FREE(service_principal);
SAFE_FREE(password);
- SAFE_FREE(new_password);
return ret;
}
#endif
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 60691287e61..29a9533bd24 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -151,12 +151,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
if (cli->use_level_II_oplocks)
capabilities |= CAP_LEVEL_II_OPLOCKS;
- if (cli->capabilities & CAP_UNICODE)
- capabilities |= CAP_UNICODE;
-
- if (cli->capabilities & CAP_LARGE_FILES)
- capabilities |= CAP_LARGE_FILES;
-
+ capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX));
return capabilities;
}
@@ -1134,6 +1129,14 @@ BOOL cli_negprot(struct cli_state *cli)
cli->sign_info.negotiated_smb_signing = True;
}
+ if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
+ SAFE_FREE(cli->outbuf);
+ SAFE_FREE(cli->inbuf);
+ cli->outbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
+ cli->inbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
+ cli->bufsize = CLI_MAX_LARGE_READX_SIZE;
+ }
+
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->use_spnego = False;
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index f11a292531c..9d20ed3adcd 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -168,6 +168,55 @@ static mode_t unix_filetype_from_wire(uint32 wire_type)
}
/****************************************************************************
+ Do a POSIX getfacl (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
+{
+ unsigned int param_len = 0;
+ unsigned int data_len = 0;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ char param[sizeof(pstring)+6];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ p = param;
+ memset(p, 0, 6);
+ SSVAL(p, 0, SMB_QUERY_POSIX_ACL);
+ p += 6;
+ p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ NULL, 0, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ if (data_len < 6) {
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+ return False;
+ }
+
+ SAFE_FREE(rparam);
+ *retbuf = rdata;
+ *prb_size = (size_t)data_len;
+
+ return True;
+}
+
+/****************************************************************************
Stat a file (UNIX extensions).
****************************************************************************/
diff --git a/source/libsmb/clifsinfo.c b/source/libsmb/clifsinfo.c
index 00fe189e9a9..22c8bff3ba0 100644
--- a/source/libsmb/clifsinfo.c
+++ b/source/libsmb/clifsinfo.c
@@ -20,6 +20,64 @@
#include "includes.h"
+/****************************************************************************
+ Get UNIX extensions version info.
+****************************************************************************/
+
+BOOL cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor,
+ uint32 *pcaplow, uint32 *pcaphigh)
+{
+ BOOL ret = False;
+ uint16 setup;
+ char param[2];
+ char *rparam=NULL, *rdata=NULL;
+ unsigned int rparam_count=0, rdata_count=0;
+
+ setup = TRANSACT2_QFSINFO;
+
+ SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL,
+ 0, 0,
+ &setup, 1, 0,
+ param, 2, 0,
+ NULL, 0, 560)) {
+ goto cleanup;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &rparam_count,
+ &rdata, &rdata_count)) {
+ goto cleanup;
+ }
+
+ if (cli_is_error(cli)) {
+ ret = False;
+ goto cleanup;
+ } else {
+ ret = True;
+ }
+
+ if (rdata_count < 12) {
+ goto cleanup;
+ }
+
+ *pmajor = SVAL(rdata,0);
+ *pminor = SVAL(rdata,2);
+ *pcaplow = IVAL(rdata,4);
+ *pcaphigh = IVAL(rdata,8);
+
+ /* todo: but not yet needed
+ * return the other stuff
+ */
+
+cleanup:
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return ret;
+}
BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr)
{
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index 068e7822072..66c16b69aef 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -184,7 +184,7 @@
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt)
{
#if defined(HAVE_KRB5_TKT_ENC_PART2)
- if (tkt->enc_part2)
+ if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length)
*auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
tkt->enc_part2->authorization_data[0]->length);
#else
@@ -233,7 +233,7 @@
return -1;
}
- sa = malloc( sizeof(struct sockaddr) * num_kdcs );
+ sa = SMB_MALLOC_ARRAY( struct sockaddr, num_kdcs );
if (!sa) {
DEBUG(0, ("krb5_locate_kdc: malloc failed\n"));
krb5_krbhst_free(ctx, hnd);
@@ -241,8 +241,7 @@
return -1;
}
- *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs);
- memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs );
+ memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs );
for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) {
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 32230988204..9e52ed35949 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -48,6 +48,7 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
SIVAL(cli->outbuf,smb_vwv3,offset);
SSVAL(cli->outbuf,smb_vwv5,size);
SSVAL(cli->outbuf,smb_vwv6,size);
+ SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1));
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
if (bigoffset)
@@ -75,7 +76,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
* rounded down to a multiple of 1024.
*/
- readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
+ if (cli->capabilities & CAP_LARGE_READX) {
+ readsize = CLI_MAX_LARGE_READX_SIZE;
+ } else {
+ readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
+ }
while (total < size) {
readsize = MIN(readsize, size-total);
@@ -117,6 +122,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
}
size2 = SVAL(cli->inbuf, smb_vwv5);
+ size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7) & 1)) << 16);
if (size2 > readsize) {
DEBUG(5,("server returned more than we wanted!\n"));
@@ -253,7 +259,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
size_t size, int i)
{
char *p;
- BOOL bigoffset = False;
+ BOOL large_writex = False;
if (size > cli->bufsize) {
cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024);
@@ -266,10 +272,11 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- if ((SMB_BIG_UINT)offset >> 32)
- bigoffset = True;
+ if (((SMB_BIG_UINT)offset >> 32) || (size > 0xFFFF)) {
+ large_writex = True;
+ }
- if (bigoffset)
+ if (large_writex)
set_message(cli->outbuf,14,0,True);
else
set_message(cli->outbuf,12,0,True);
@@ -297,7 +304,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
- if (bigoffset)
+ if (large_writex)
SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff);
p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11);
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 1e702d73138..df9c4ddcadc 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -1697,7 +1697,7 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat
struct smbc_dir_list *dir_list;
struct smbc_dirent *dirent;
int dirent_type;
- int remove = 0;
+ int do_remove = 0;
dirent_type = dir->dir_type;
@@ -1714,13 +1714,13 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat
for (dir_list = dir->dir_list;
dir_list != dir->dir_end;
dir_list = dir_list->next) {
- if (! remove &&
+ if (! do_remove &&
strcmp(dir_list->dirent->name, dirent->name) == 0) {
/* Duplicate. End end of list need to be removed. */
- remove = 1;
+ do_remove = 1;
}
- if (remove && dir_list->next == dir->dir_end) {
+ if (do_remove && dir_list->next == dir->dir_end) {
/* Found the end of the list. Remove it. */
dir->dir_end = dir_list;
free(dir_list->next);
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index cb8852c4ed2..e6868fb3730 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1009,9 +1009,9 @@ static BOOL resolve_ads(const char *name, int name_type,
resolve_hosts() when looking up DC's via SRV RR entries in DNS
**********************************************************************/
-static BOOL internal_resolve_name(const char *name, int name_type,
- struct ip_service **return_iplist,
- int *return_count, const char *resolve_order)
+BOOL internal_resolve_name(const char *name, int name_type,
+ struct ip_service **return_iplist,
+ int *return_count, const char *resolve_order)
{
pstring name_resolve_list;
fstring tok;
diff --git a/source/libsmb/ntlmssp_sign.c b/source/libsmb/ntlmssp_sign.c
index 2347619e57d..ee0f9df0249 100644
--- a/source/libsmb/ntlmssp_sign.c
+++ b/source/libsmb/ntlmssp_sign.c
@@ -344,6 +344,12 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
recv_sign_const = CLI_SIGN;
recv_seal_const = CLI_SEAL;
break;
+ default:
+ send_sign_const = "unknown role";
+ send_seal_const = "unknown role";
+ recv_sign_const = "unknown role";
+ recv_seal_const = "unknown role";
+ break;
}
calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
diff --git a/source/libsmb/samlogon_cache.c b/source/libsmb/samlogon_cache.c
index 086dd127a45..fdfc92a750a 100644
--- a/source/libsmb/samlogon_cache.c
+++ b/source/libsmb/samlogon_cache.c
@@ -136,7 +136,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USE
/* so we fill it in since winbindd_getpwnam() makes use of it */
if ( !user->uni_user_name.buffer ) {
- init_unistr2( &user->uni_user_name, username, STR_TERMINATE );
+ init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE );
init_uni_hdr( &user->hdr_user_name, &user->uni_user_name );
}
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index d92027e267a..3451b0cc1ab 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -592,7 +592,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
- enum brl_type lock_type, int check_self)
+ enum brl_type lock_type)
{
TDB_DATA kbuf, dbuf;
int count, i;
@@ -617,16 +617,11 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
for (i=0; i<count; i++) {
- if (check_self) {
- if (brl_conflict(&locks[i], &lock))
- goto fail;
- } else {
- /*
- * Our own locks don't conflict.
- */
- if (brl_conflict_other(&locks[i], &lock))
- goto fail;
- }
+ /*
+ * Our own locks don't conflict.
+ */
+ if (brl_conflict_other(&locks[i], &lock))
+ goto fail;
}
}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 15a4500bfa8..e10e8a1fa0f 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -62,27 +62,39 @@ static const char *lock_type_name(enum brl_type lock_type)
/****************************************************************************
Utility function called to see if a file region is locked.
- If check_self is True, then checks on our own fd with the same locking context
- are still made. If check_self is False, then checks are not made on our own fd
- with the same locking context are not made.
****************************************************************************/
BOOL is_locked(files_struct *fsp,connection_struct *conn,
SMB_BIG_UINT count,SMB_BIG_UINT offset,
- enum brl_type lock_type, BOOL check_self)
+ enum brl_type lock_type)
{
int snum = SNUM(conn);
+ int strict_locking = lp_strict_locking(snum);
BOOL ret;
if (count == 0)
return(False);
- if (!lp_locking(snum) || !lp_strict_locking(snum))
+ if (!lp_locking(snum) || !strict_locking)
return(False);
- ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
- global_smbpid, sys_getpid(), conn->cnum,
- offset, count, lock_type, check_self);
+ if (strict_locking == Auto) {
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
+ DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
+ ret = 0;
+ } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) {
+ DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
+ ret = 0;
+ } else {
+ ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
+ global_smbpid, sys_getpid(), conn->cnum,
+ offset, count, lock_type);
+ }
+ } else {
+ ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
+ global_smbpid, sys_getpid(), conn->cnum,
+ offset, count, lock_type);
+ }
DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
(double)offset, (double)count, ret ? "locked" : "unlocked",
@@ -541,6 +553,19 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t
BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
{
+#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
+ if (e1->pid == e2->pid &&
+ e1->share_file_id == e2->share_file_id &&
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
+ DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
+ (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
+ (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
+ smb_panic("PANIC: share_modes_identical logic error.\n");
+ }
+#endif
+
return (e1->pid == e2->pid &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
e1->dev == e2->dev &&
@@ -912,6 +937,7 @@ static void print_deferred_open_table(struct deferred_open_data *data)
}
}
+
/*******************************************************************
Form a static deferred open locking key for a dev/inode pair.
******************************************************************/
diff --git a/source/modules/vfs_afsacl.c b/source/modules/vfs_afsacl.c
index cd10dc71c2e..6d6848eb120 100644
--- a/source/modules/vfs_afsacl.c
+++ b/source/modules/vfs_afsacl.c
@@ -37,6 +37,8 @@ extern DOM_SID global_sid_Builtin_Backup_Operators;
extern DOM_SID global_sid_Authenticated_Users;
extern DOM_SID global_sid_NULL;
+static char space_replacement = '%';
+
extern int afs_syscall(int, char *, int, char *, int);
struct afs_ace {
@@ -83,7 +85,7 @@ static void free_afs_acl(struct afs_acl *acl)
static struct afs_ace *clone_afs_ace(TALLOC_CTX *mem_ctx, struct afs_ace *ace)
{
- struct afs_ace *result = talloc(mem_ctx, sizeof(struct afs_ace));
+ struct afs_ace *result = TALLOC_P(mem_ctx, struct afs_ace);
if (result == NULL)
return NULL;
@@ -167,7 +169,7 @@ static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
}
}
- result = talloc(mem_ctx, sizeof(struct afs_ace));
+ result = TALLOC_P(mem_ctx, struct afs_ace);
if (result == NULL) {
DEBUG(0, ("Could not talloc AFS ace\n"));
@@ -260,10 +262,12 @@ static BOOL parse_afs_acl(struct afs_acl *acl, const char *acl_str)
for (aces = nplus+nminus; aces > 0; aces--)
{
- const char *name;
+ const char *namep;
+ fstring name;
uint32 rights;
+ char *space;
- name = p;
+ namep = p;
if ((p = strchr(p, '\t')) == NULL)
return False;
@@ -277,6 +281,11 @@ static BOOL parse_afs_acl(struct afs_acl *acl, const char *acl_str)
return False;
p += 1;
+ fstrcpy(name, namep);
+
+ while ((space = strchr_m(name, space_replacement)) != NULL)
+ *space = ' ';
+
add_afs_ace(acl, nplus>0, name, rights);
nplus -= 1;
@@ -488,6 +497,17 @@ static struct static_dir_ace_mapping {
{ 0, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT,
0x00120089, 8 /* l */ },
+ /* some stupid workaround for preventing fallbacks */
+ { 0, 0x3, 0x0012019F, 9 /* rl */ },
+ { 0, 0x13, PERMS_FULL, 127 /* full */ },
+
+ /* read, delete and execute access plus synchronize */
+ { 0, 0x3, 0x001300A9, 9 /* should be rdl, set to rl */},
+ /* classical read list */
+ { 0, 0x13, 0x001200A9, 9 /* rl */},
+ /* almost full control, no delete */
+ { 0, 0x13, PERMS_CHANGE, 63 /* rwidlk */},
+
/* List folder */
{ 0, SEC_ACE_FLAG_CONTAINER_INHERIT,
PERMS_READ, 8 /* l */ },
@@ -527,8 +547,8 @@ static uint32 nt_to_afs_dir_rights(const char *filename, const SEC_ACE *ace)
return m->afs_rights;
}
- DEBUG(1, ("AFSACL FALLBACK: 0x%X 0x%X 0x%X %s\n",
- ace->type, ace->flags, ace->info.mask, filename));
+ DEBUG(1, ("AFSACL FALLBACK: 0x%X 0x%X 0x%X %s %X\n",
+ ace->type, ace->flags, ace->info.mask, filename, rights));
if (rights & (GENERIC_ALL_ACCESS|WRITE_DAC_ACCESS)) {
result |= PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT |
@@ -599,7 +619,7 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
uid_to_sid(&owner_sid, sbuf.st_uid);
gid_to_sid(&group_sid, sbuf.st_gid);
- nt_ace_list = (SEC_ACE *)malloc(afs_acl->num_aces * sizeof(SEC_ACE));
+ nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE, afs_acl->num_aces);
if (nt_ace_list == NULL)
return 0;
@@ -698,6 +718,7 @@ static BOOL nt_to_afs_acl(const char *filename,
fstring dom_name;
fstring name;
enum SID_NAME_USE name_type;
+ char *p;
if (ace->type != SEC_ACE_TYPE_ACCESS_ALLOWED) {
/* First cut: Only positive ACEs */
@@ -752,6 +773,9 @@ static BOOL nt_to_afs_acl(const char *filename,
}
}
+ while ((p = strchr_m(name, ' ')) != NULL)
+ *p = space_replacement;
+
add_afs_ace(afs_acl, True, name,
nt_to_afs_rights(filename, ace));
}
@@ -971,9 +995,26 @@ BOOL afsacl_set_nt_acl(vfs_handle_struct *handle,
return afs_set_nt_acl(handle, fsp, security_info_sent, psd);
}
+static int afsacl_connect(vfs_handle_struct *handle,
+ connection_struct *conn,
+ const char *service,
+ const char *user)
+{
+ char *spc;
+
+ spc = lp_parm_const_string(SNUM(handle->conn), "afsacl", "space", "%");
+
+ if (spc != NULL)
+ space_replacement = spc[0];
+
+ return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+}
+
/* VFS operations structure */
static vfs_op_tuple afsacl_ops[] = {
+ {SMB_VFS_OP(afsacl_connect), SMB_VFS_OP_CONNECT,
+ SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(afsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(afsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c
index 0526276acb8..18fa04533f0 100644
--- a/source/modules/vfs_cap.c
+++ b/source/modules/vfs_cap.c
@@ -45,9 +45,9 @@ static DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, cons
return SMB_VFS_NEXT_OPENDIR(handle, conn, capname);
}
-static struct dirent *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
DEBUG(3,("cap: cap_readdir\n"));
result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
if (result) {
diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c
index b27c916a2a2..09215d1e8d0 100644
--- a/source/modules/vfs_full_audit.c
+++ b/source/modules/vfs_full_audit.c
@@ -84,8 +84,14 @@ static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
SMB_DISK_QUOTA *qt);
static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn,
const char *fname);
-static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
+static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
connection_struct *conn, DIR *dirp);
+static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp, long offset);
+static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp);
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp);
static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
const char *path, mode_t mode);
static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn,
@@ -304,6 +310,12 @@ static vfs_op_tuple audit_op_tuples[] = {
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_readdir), SMB_VFS_OP_READDIR,
SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_seekdir), SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_telldir), SMB_VFS_OP_TELLDIR,
+ SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_rewinddir), SMB_VFS_OP_REWINDDIR,
+ SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_mkdir), SMB_VFS_OP_MKDIR,
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_rmdir), SMB_VFS_OP_RMDIR,
@@ -788,10 +800,10 @@ static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct
return result;
}
-static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
+static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
@@ -803,6 +815,36 @@ static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
return result;
}
+static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp, long offset)
+{
+ SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset);
+
+ do_log(SMB_VFS_OP_SEEKDIR, True, handle, "");
+ return;
+}
+
+static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp)
+{
+ long result;
+
+ result = SMB_VFS_NEXT_TELLDIR(handle, conn, dirp);
+
+ do_log(SMB_VFS_OP_OPENDIR, True, handle, "");
+
+ return result;
+}
+
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp)
+{
+ SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp);
+
+ do_log(SMB_VFS_OP_REWINDDIR, True, handle, "");
+ return;
+}
+
static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
const char *path, mode_t mode)
{
diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c
index a5dc09aca69..1b36914bbea 100644
--- a/source/modules/vfs_netatalk.c
+++ b/source/modules/vfs_netatalk.c
@@ -147,7 +147,7 @@ static void atalk_add_to_list(name_compare_entry **list)
static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
{
char *dpath;
- struct dirent *dent = 0;
+ SMB_STRUCT_DIRENT *dent = 0;
DIR *dir;
if (!path) return;
@@ -155,7 +155,7 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
dir = opendir(path);
if (!dir) return;
- while (NULL != (dent = readdir(dir))) {
+ while (NULL != (dent = sys_readdir(dir))) {
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c
index f136f4b0b81..133e8e9c647 100644
--- a/source/modules/vfs_shadow_copy.c
+++ b/source/modules/vfs_shadow_copy.c
@@ -59,7 +59,7 @@ static int vfs_shadow_copy_debug_level = DBGC_VFS;
typedef struct {
int pos;
int num;
- struct dirent *dirs;
+ SMB_STRUCT_DIRENT *dirs;
} shadow_copy_Dir;
static BOOL shadow_copy_match_name(const char *name)
@@ -92,8 +92,8 @@ static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *co
ZERO_STRUCTP(dirp);
while (True) {
- struct dirent *d;
- struct dirent *r;
+ SMB_STRUCT_DIRENT *d;
+ SMB_STRUCT_DIRENT *r;
d = SMB_VFS_NEXT_READDIR(handle, conn, p);
@@ -108,7 +108,7 @@ static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *co
DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name));
- r = SMB_REALLOC_ARRAY(dirp->dirs, struct dirent, dirp->num+1);
+ r = SMB_REALLOC_ARRAY(dirp->dirs,SMB_STRUCT_DIRENT, dirp->num+1);
if (!r) {
DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
break;
@@ -122,7 +122,7 @@ static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *co
return((DIR *)dirp);
}
-struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
+SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
@@ -156,7 +156,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str
while (True) {
SHADOW_COPY_LABEL *tlabels;
- struct dirent *d;
+ SMB_STRUCT_DIRENT *d;
d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p);
if (d == NULL) {
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index a5d5cc3f67a..8a111eb957a 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -1639,7 +1639,7 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
plus the broadcast sockets.
***************************************************************************/
-static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
+static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
{
int *sock_array = NULL;
struct subnet_record *subrec = NULL;
@@ -1672,21 +1672,25 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
/* Add in the broadcast socket on 137. */
FD_SET(ClientNMB,pset);
sock_array[num++] = ClientNMB;
+ *maxfd = MAX( *maxfd, ClientNMB);
/* Add in the 137 sockets on all the interfaces. */
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
FD_SET(subrec->nmb_sock,pset);
sock_array[num++] = subrec->nmb_sock;
+ *maxfd = MAX( *maxfd, subrec->nmb_sock);
}
/* Add in the broadcast socket on 138. */
FD_SET(ClientDGRAM,pset);
sock_array[num++] = ClientDGRAM;
+ *maxfd = MAX( *maxfd, ClientDGRAM);
/* Add in the 138 sockets on all the interfaces. */
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
FD_SET(subrec->dgram_sock,pset);
sock_array[num++] = subrec->dgram_sock;
+ *maxfd = MAX( *maxfd, subrec->dgram_sock);
}
*listen_number = (count*2) + 2;
@@ -1711,6 +1715,7 @@ BOOL listen_for_packets(BOOL run_election)
static int listen_number = 0;
static int *sock_array = NULL;
int i;
+ static int maxfd = 0;
fd_set fds;
int selrtn;
@@ -1720,7 +1725,7 @@ BOOL listen_for_packets(BOOL run_election)
#endif
if(listen_set == NULL || rescan_listen_set) {
- if(create_listen_fdset(&listen_set, &sock_array, &listen_number)) {
+ if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
@@ -1733,6 +1738,7 @@ BOOL listen_for_packets(BOOL run_election)
dns_fd = asyncdns_fd();
if (dns_fd != -1) {
FD_SET(dns_fd, &fds);
+ maxfd = MAX( maxfd, dns_fd);
}
#endif
@@ -1750,7 +1756,7 @@ BOOL listen_for_packets(BOOL run_election)
BlockSignals(False, SIGTERM);
- selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
+ selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
/* We can only take signals when we are in the select - block them again here. */
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index 9d4f0954ceb..bfd8dd45ee5 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -189,7 +189,7 @@ static int pam_winbind_request_log(enum winbindd_cmd req_type,
return retval;
default:
/* we don't know anything about this return value */
- _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s'",
+ _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s')",
retval, user);
return retval;
}
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index 477d2e0f682..22deaf82c6e 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -113,6 +113,10 @@ struct winbindd_domain {
void *private;
+ /* A working DC */
+ fstring dcname;
+ struct sockaddr_in dcaddr;
+
/* Sequence number stuff */
time_t last_seq_check;
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 139efec2141..1843ec188b0 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -201,205 +201,469 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
return True;
}
-/* Open a connction to the remote server, cache failures for 30 seconds */
+/************************************************************************
+ Given a fd with a just-connected TCP connection to a DC, open a connection
+ to the pipe.
+************************************************************************/
-static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
- struct winbindd_cm_conn *new_conn)
+static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
+ const int sockfd,
+ const int pipe_index,
+ const char *controller,
+ struct cli_state **cli,
+ BOOL *retry)
{
- NTSTATUS result;
- char *machine_password;
- char *machine_krb5_principal, *ipc_username, *ipc_domain, *ipc_password;
- struct in_addr dc_ip;
- int i;
- BOOL retry = True;
+ char *machine_password, *machine_krb5_principal;
+ char *ipc_username, *ipc_domain, *ipc_password;
+ struct ntuser_creds creds;
- ZERO_STRUCT(dc_ip);
+ BOOL got_mutex;
+ BOOL add_failed_connection = True;
- fstrcpy(new_conn->domain, domain->name);
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- if (!get_dc_name_via_netlogon(domain, new_conn->controller, &dc_ip)) {
+ struct sockaddr peeraddr;
+ socklen_t peeraddr_len;
- /* connection failure cache has been moved inside of
- get_dc_name so we can deal with half dead DC's --jerry */
+ struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
- if (!get_dc_name(domain->name, domain->alt_name[0] ?
- domain->alt_name : NULL,
- new_conn->controller, &dc_ip)) {
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(domain->name, "", result);
- return result;
- }
- }
-
- /* Initialise SMB connection */
- fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
-
- /* grab stored passwords */
+ machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
+ NULL);
- machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
+ if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
+ lp_realm()) == -1) {
SAFE_FREE(machine_password);
return NT_STATUS_NO_MEMORY;
}
cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
- for (i = 0; retry && (i < 3); i++) {
- BOOL got_mutex;
- if (!(got_mutex = secrets_named_mutex(new_conn->controller, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
- DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller));
- result = NT_STATUS_POSSIBLE_DEADLOCK;
- continue;
+ *retry = True;
+
+ got_mutex = secrets_named_mutex(controller,
+ WINBIND_SERVER_MUTEX_WAIT_TIME);
+
+ if (!got_mutex) {
+ DEBUG(0,("cm_open_connection: mutex grab failed for %s\n",
+ controller));
+ result = NT_STATUS_POSSIBLE_DEADLOCK;
+ goto done;
+ }
+
+ if ((*cli = cli_initialise(NULL)) == NULL) {
+ DEBUG(1, ("Could not cli_initialize\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ (*cli)->timeout = 10000; /* 10 seconds */
+ (*cli)->fd = sockfd;
+ fstrcpy((*cli)->desthost, controller);
+ (*cli)->use_kerberos = True;
+
+ peeraddr_len = sizeof(peeraddr);
+
+ if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
+ (peeraddr_len != sizeof(struct sockaddr_in)) ||
+ (peeraddr_in->sin_family != PF_INET))
+ goto done;
+
+ if (ntohs(peeraddr_in->sin_port) == 139) {
+ struct nmb_name calling;
+ struct nmb_name called;
+
+ make_nmb_name(&calling, global_myname(), 0x0);
+ make_nmb_name(&called, "*SMBSERVER", 0x20);
+
+ if (!cli_session_request(*cli, &calling, &called)) {
+ DEBUG(8, ("cli_session_request failed for %s\n",
+ controller));
+ goto done;
}
-
- new_conn->cli = NULL;
- result = cli_start_connection(&new_conn->cli, global_myname(),
- new_conn->controller,
- &dc_ip, 0, Undefined,
- CLI_FULL_CONNECTION_USE_KERBEROS,
- &retry);
+ }
- if (NT_STATUS_IS_OK(result)) {
+ cli_setup_signing_state(*cli, Undefined);
- /* reset the error code */
- result = NT_STATUS_UNSUCCESSFUL;
+ if (!cli_negprot(*cli)) {
+ DEBUG(1, ("cli_negprot failed\n"));
+ cli_shutdown(*cli);
+ goto done;
+ }
- /* Krb5 session */
+ /* Krb5 session */
- if ((lp_security() == SEC_ADS)
- && (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) {
- ADS_STATUS ads_status;
- new_conn->cli->use_kerberos = True;
- DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n",
- new_conn->controller, global_myname(), machine_krb5_principal));
-
- ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
- machine_password,
- lp_workgroup());
- if (!ADS_ERR_OK(ads_status)) {
- DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status)));
- result = ads_ntstatus(ads_status);
- } else {
- result = NT_STATUS_OK;
- }
- }
- new_conn->cli->use_kerberos = False;
-
- /* only do this is we have a username/password for thr IPC$ connection */
-
- if ( !NT_STATUS_IS_OK(result)
- && new_conn->cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
- && strlen(ipc_username) )
- {
- DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
- new_conn->controller, global_myname(), ipc_domain, ipc_username));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, ipc_username,
- ipc_password, strlen(ipc_password)+1,
- ipc_password, strlen(ipc_password)+1,
- ipc_domain)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* anonymous is all that is left if we get to here */
-
- if (!NT_STATUS_IS_OK(result)) {
-
- DEBUG(5, ("anonymous connection attempt to %s from %s\n",
- new_conn->controller, global_myname()));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, "", NULL, 0, NULL, 0, ""))
- {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed anonymous session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
-
- }
+ if ((lp_security() == SEC_ADS)
+ && ((*cli)->protocol >= PROTOCOL_NT1 &&
+ (*cli)->capabilities & CAP_EXTENDED_SECURITY)) {
+
+ ADS_STATUS ads_status;
+ (*cli)->use_kerberos = True;
+ DEBUG(5, ("connecting to %s from %s with kerberos principal "
+ "[%s]\n", controller, global_myname(),
+ machine_krb5_principal));
+
+ ads_status = cli_session_setup_spnego(*cli,
+ machine_krb5_principal,
+ machine_password,
+ lp_workgroup());
+
+ if (!ADS_ERR_OK(ads_status))
+ DEBUG(4,("failed kerberos session setup with %s\n",
+ ads_errstr(ads_status)));
+
+ result = ads_ntstatus(ads_status);
+ }
- if (NT_STATUS_IS_OK(result) && !cli_send_tconX(new_conn->cli, "IPC$", "IPC",
- "", 0)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
- cli_shutdown(new_conn->cli);
- if (NT_STATUS_IS_OK(result)) {
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
- }
+ if (NT_STATUS_IS_OK(result))
+ goto session_setup_done;
- if (NT_STATUS_IS_OK(result)) {
- struct ntuser_creds creds;
- init_creds(&creds, ipc_username, ipc_domain, ipc_password);
- cli_init_creds(new_conn->cli, &creds);
+ /* Fall back to non-kerberos session setup */
+
+ (*cli)->use_kerberos = False;
+
+ if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
+ (strlen(ipc_username) > 0)) {
+
+ /* Only try authenticated if we have a username */
+
+ DEBUG(5, ("connecting to %s from %s with username "
+ "[%s]\\[%s]\n", controller, global_myname(),
+ ipc_domain, ipc_username));
+
+ if (cli_session_setup(*cli, ipc_username,
+ ipc_password, strlen(ipc_password)+1,
+ ipc_password, strlen(ipc_password)+1,
+ ipc_domain)) {
+ DEBUG(5, ("authenticated session setup failed\n"));
+ goto session_setup_done;
}
+ }
+
+ /* Fall back to anonymous connection, this might fail later */
+
+ if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
+ DEBUG(5, ("Connected anonymously\n"));
+ goto session_setup_done;
+ }
- if (got_mutex)
- secrets_named_mutex_release(new_conn->controller);
+ result = cli_nt_error(*cli);
+
+ if (NT_STATUS_IS_OK(result))
+ result = NT_STATUS_UNSUCCESSFUL;
+
+ /* We can't session setup */
+
+ goto done;
+
+ session_setup_done:
+
+ if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
+
+ result = cli_nt_error(*cli);
+
+ DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
if (NT_STATUS_IS_OK(result))
- break;
+ result = NT_STATUS_UNSUCCESSFUL;
+
+ cli_shutdown(*cli);
+ goto done;
}
- /* try and use schannel if possible, but continue anyway if it
- failed. This allows existing setups to continue working,
- while solving the win2003 '100 user' limit for systems that
- are joined properly.
-
- Only do this for our own domain or perhaps a trusted domain
- if we are on a Samba DC */
+ init_creds(&creds, ipc_username, ipc_domain, ipc_password);
+ cli_init_creds(*cli, &creds);
- if (NT_STATUS_IS_OK(result) && (domain->primary || IS_DC) ) {
- NTSTATUS status = setup_schannel( new_conn->cli, domain->name );
+ secrets_named_mutex_release(controller);
+ got_mutex = False;
+ *retry = False;
+
+ if (domain->primary || IS_DC) {
+ NTSTATUS status = setup_schannel( *cli, domain->name );
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3,("schannel refused - continuing without schannel (%s)\n",
- nt_errstr(status)));
+ DEBUG(3,("schannel refused - continuing without "
+ "schannel (%s)\n", nt_errstr(status)));
}
}
+ /* set the domain if empty; needed for schannel connections */
+ if ( !*(*cli)->domain )
+ fstrcpy( (*cli)->domain, domain->name );
+
+ if ( !cli_nt_session_open (*cli, pipe_index) ) {
+
+ result = NT_STATUS_PIPE_NOT_AVAILABLE;
+
+ /* This might be a NT4 DC */
+ if ( is_win2k_pipe(pipe_index) )
+ add_failed_connection = False;
+
+ cli_shutdown(*cli);
+ goto done;
+ }
+
+ result = NT_STATUS_OK;
+ add_failed_connection = False;
+
+ done:
+ if (got_mutex)
+ secrets_named_mutex_release(controller);
+
+ SAFE_FREE(machine_password);
+ SAFE_FREE(machine_krb5_principal);
SAFE_FREE(ipc_username);
SAFE_FREE(ipc_domain);
SAFE_FREE(ipc_password);
- SAFE_FREE(machine_password);
- SAFE_FREE(machine_krb5_principal);
- if (!NT_STATUS_IS_OK(result)) {
- add_failed_connection_entry(domain->name, new_conn->controller, result);
- return result;
+ if (add_failed_connection)
+ add_failed_connection_entry(domain->name, controller, result);
+
+ return result;
+}
+
+struct dc_name_ip {
+ fstring name;
+ struct in_addr ip;
+};
+
+static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
+ const char *dcname, struct in_addr ip,
+ struct dc_name_ip **dcs, int *num)
+{
+ if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname)))
+ return False;
+
+ *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
+
+ if (*dcs == NULL)
+ return False;
+
+ fstrcpy((*dcs)[*num].name, dcname);
+ (*dcs)[*num].ip = ip;
+ *num += 1;
+ return True;
+}
+
+static BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, char ***array, int *num)
+{
+ char *dup_str = talloc_strdup(mem_ctx, str);
+
+ *array = TALLOC_REALLOC_ARRAY(mem_ctx, *array, char *, (*num)+1);
+
+ if ((*array == NULL) || (dup_str == NULL))
+ return False;
+
+ (*array)[*num] = dup_str;
+ *num += 1;
+ return True;
+}
+
+static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
+ struct in_addr ip, uint16 port,
+ struct sockaddr_in **addrs, int *num)
+{
+ *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
+
+ if (*addrs == NULL)
+ return False;
+
+ (*addrs)[*num].sin_family = PF_INET;
+ putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
+ (*addrs)[*num].sin_port = htons(port);
+
+ *num += 1;
+ return True;
+}
+
+static BOOL get_dcs_1c(TALLOC_CTX *mem_ctx,
+ const struct winbindd_domain *domain,
+ struct dc_name_ip **dcs, int *num_dcs)
+{
+ struct ip_service *iplist = NULL;
+ int i, num = 0;
+
+ if (!internal_resolve_name(domain->name, 0x1c, &iplist, &num,
+ lp_name_resolve_order()))
+ return False;
+
+ /* Now try to find the server names of at least one IP address, hosts
+ * not replying are cached as such */
+
+ for (i=0; i<num; i++) {
+
+ fstring dcname;
+
+ if (!name_status_find(domain->name, 0x1c, 0x20, iplist[i].ip,
+ dcname))
+ continue;
+
+ if (add_one_dc_unique(mem_ctx, domain->name, dcname,
+ iplist[i].ip, dcs, num_dcs)) {
+ /* One DC responded, so we assume that he will also
+ work on 139/445 */
+ break;
+ }
}
-
- /* set the domain if empty; needed for schannel connections */
- if ( !*new_conn->cli->domain )
- fstrcpy( new_conn->cli->domain, domain->name );
-
-
- if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
- result = NT_STATUS_PIPE_NOT_AVAILABLE;
- /*
- * only cache a failure if we are not trying to open the
- * **win2k** specific lsarpc UUID. This could be an NT PDC
- * and therefore a failure is normal. This should probably
- * be abstracted to a check for 2k specific pipes and wondering
- * if the PDC is an NT4 box. but since there is only one 2k
- * specific UUID right now, i'm not going to bother. --jerry
- */
- if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(domain->name, new_conn->controller, result);
- cli_shutdown(new_conn->cli);
- return result;
+
+ return True;
+}
+
+static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
+ struct dc_name_ip **dcs, int *num_dcs)
+{
+ fstring dcname;
+ struct in_addr ip;
+ BOOL is_our_domain;
+
+ const char *p;
+
+ is_our_domain = strequal(domain->name, lp_workgroup());
+
+ if (!is_our_domain && get_dc_name_via_netlogon(domain, dcname, &ip) &&
+ add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs))
+ return True;
+
+ if (!is_our_domain) {
+ /* NETLOGON to our own domain could not give us a DC name
+ * (which is an error), fall back to looking up domain#1c */
+ return get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
}
- return NT_STATUS_OK;
+ if (must_use_pdc(domain->name) && get_pdc_ip(domain->name, &ip)) {
+
+ if (!name_status_find(domain->name, 0x1b, 0x20, ip, dcname))
+ return False;
+
+ if (add_one_dc_unique(mem_ctx, domain->name,
+ dcname, ip, dcs, num_dcs))
+ return True;
+ }
+
+ p = lp_passwordserver();
+
+ if (*p == 0)
+ return get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
+
+ while (next_token(&p, dcname, LIST_SEP, sizeof(dcname))) {
+
+ if (strequal(dcname, "*")) {
+ get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
+ continue;
+ }
+
+ if (!resolve_name(dcname, &ip, 0x20))
+ continue;
+
+ add_one_dc_unique(mem_ctx, domain->name, dcname, ip,
+ dcs, num_dcs);
+ }
+
+ return True;
+}
+
+static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
+ const struct winbindd_domain *domain,
+ fstring dcname, struct sockaddr_in *addr, int *fd)
+{
+ struct dc_name_ip *dcs = NULL;
+ int num_dcs = 0;
+
+ char **dcnames = NULL;
+ int num_dcnames = 0;
+
+ struct sockaddr_in *addrs = NULL;
+ int num_addrs = 0;
+
+ int i, fd_index;
+
+ if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
+ return False;
+
+ for (i=0; i<num_dcs; i++) {
+
+ add_string_to_array(mem_ctx, dcs[i].name,
+ &dcnames, &num_dcnames);
+ add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
+ &addrs, &num_addrs);
+
+ add_string_to_array(mem_ctx, dcs[i].name,
+ &dcnames, &num_dcnames);
+ add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
+ &addrs, &num_addrs);
+ }
+
+ if ((num_dcnames == 0) || (num_dcnames != num_addrs))
+ return False;
+
+ if (!open_any_socket_out(addrs, num_addrs, 10000, &fd_index, fd)) {
+ for (i=0; i<num_dcs; i++) {
+ add_failed_connection_entry(domain->name,
+ dcs[i].name,
+ NT_STATUS_UNSUCCESSFUL);
+ }
+ return False;
+ }
+
+ fstrcpy(dcname, dcnames[fd_index]);
+ *addr = addrs[fd_index];
+
+ return True;
+}
+
+static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
+ const int pipe_index,
+ struct winbindd_cm_conn *new_conn)
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS result;
+
+ int retries;
+
+ if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (retries = 0; retries < 3; retries++) {
+
+ int fd = -1;
+ BOOL retry;
+
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+
+ if ((strlen(domain->dcname) > 0) &&
+ NT_STATUS_IS_OK(check_negative_conn_cache(domain->name,
+ domain->dcname))) {
+ int dummy;
+ if (!open_any_socket_out(&domain->dcaddr, 1, 10000,
+ &dummy, &fd)) {
+ fd = -1;
+ }
+ }
+
+ if ((fd == -1) &&
+ !find_new_dc(mem_ctx, domain, domain->dcname,
+ &domain->dcaddr, &fd))
+ break;
+
+ new_conn->cli = NULL;
+
+ result = cm_prepare_connection(domain, fd, pipe_index,
+ domain->dcname,
+ &new_conn->cli, &retry);
+
+ if (NT_STATUS_IS_OK(result)) {
+ fstrcpy(new_conn->domain, domain->name);
+ /* Initialise SMB connection */
+ fstrcpy(new_conn->pipe_name,
+ get_pipe_name_from_index(pipe_index));
+ break;
+ }
+
+ if (!retry)
+ break;
+ }
+
+ talloc_destroy(mem_ctx);
+ return result;
}
/************************************************************************
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 8ece6f114a8..d64c2e4a19c 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -932,7 +932,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
/* Add nested group memberships */
- if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
+ if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
return;
for (j=0; j<num_aliases; j++) {
@@ -1029,7 +1029,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
if (!winbindd_lookup_sid_by_name(domain, domain->name, name_user, &user_sid,
&name_type)) {
- DEBUG(1, ("user '%s' does not exist\n", name_user));
+ DEBUG(4, ("user '%s' does not exist\n", name_user));
goto done;
}
@@ -1085,9 +1085,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
add_gids_from_group_sid(&info3->other_sids[i].sid,
&gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
}
for (i = 0; i < info3->num_groups2; i++) {
@@ -1099,9 +1096,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
add_gids_from_group_sid(&group_sid, &gid_list,
&num_gids);
-
- if (gid_list == NULL)
- goto done;
}
SAFE_FREE(info3);
@@ -1119,12 +1113,13 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
for (i = 0; i < num_groups; i++) {
add_gids_from_group_sid(user_grpsids[i],
&gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
}
}
+ /* We want at least one group... */
+ if (gid_list == NULL)
+ goto done;
+
remove_duplicate_gids( &num_gids, gid_list );
/* Send data back to client */
@@ -1142,7 +1137,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
return result;
}
-static void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+static void add_sid_to_parray_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DOM_SID ***sids, int *num_sids)
{
int i;
@@ -1170,15 +1165,15 @@ static void add_local_sids_from_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DOM_SID *aliases = NULL;
int i, num_aliases = 0;
- if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
+ if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
return;
if (num_aliases == 0)
return;
for (i=0; i<num_aliases; i++)
- add_sid_to_array_unique(mem_ctx, &aliases[i], user_grpsids,
- num_groups);
+ add_sid_to_parray_unique(mem_ctx, &aliases[i], user_grpsids,
+ num_groups);
SAFE_FREE(aliases);
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index 9a99bad9d74..88e3254d24a 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -5,20 +5,9 @@
Copyright (C) Tim Potter 2000
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ You are free to use this interface definition in any way you see
+ fit, including without restriction, using this header in your own
+ products. You do not need to give any attribution.
*/
#ifndef SAFE_FREE
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index f7d3ac5aa41..cb44ec98d76 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -612,7 +612,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, sizeof(state->response.data.auth.user_session_key) /* 16 */);
}
if (state->request.flags & WBFLAG_PAM_LMKEY) {
- memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
+ memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
}
}
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index de7f2ff76fb..e6edb70f079 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -807,10 +807,10 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
SAM_UNK_CTR ctr;
- uint16 switch_value = 2;
NTSTATUS result;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
+ BOOL got_seq_num = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
int retry;
@@ -856,10 +856,27 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
/* Query domain info */
result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
- switch_value, &ctr);
+ 8, &ctr);
if (NT_STATUS_IS_OK(result)) {
- *seq = ctr.info.inf2.seq_num;
+ *seq = ctr.info.inf8.seq_num.low;
+ got_seq_num = True;
+ goto seq_num;
+ }
+
+ /* retry with info-level 2 in case the dc does not support info-level 8
+ * (like all older samba2 and samba3 dc's - Guenther */
+
+ result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
+ 2, &ctr);
+
+ if (NT_STATUS_IS_OK(result)) {
+ *seq = ctr.info.inf2.seq_num.low;
+ got_seq_num = True;
+ }
+
+ seq_num:
+ if (got_seq_num) {
DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
} else {
DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 7cbcba12453..1f727dd18d5 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -641,7 +641,7 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
*/
void fill_domain_username(fstring name, const char *domain, const char *user)
{
- strlower_m( name );
+ strlower_m( user );
if (assume_domain(domain)) {
strlcpy(name, user, sizeof(fstring));
diff --git a/source/nsswitch/winbindd_wins.c b/source/nsswitch/winbindd_wins.c
index 07c383e0e62..f199ebcb437 100644
--- a/source/nsswitch/winbindd_wins.c
+++ b/source/nsswitch/winbindd_wins.c
@@ -88,7 +88,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd;
struct ip_service *ret = NULL;
- struct in_addr *return_ip;
+ struct in_addr *return_ip = NULL;
int j, i, flags = 0;
*count = 0;
@@ -121,7 +121,9 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
j--) {
struct in_addr *bcast = iface_n_bcast(j);
return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (return_ip) break;
+ if (return_ip) {
+ break;
+ }
}
close(fd);
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 69ea5343876..5ca19134bb5 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -127,6 +127,7 @@ typedef struct
char *szSocketOptions;
char *szRealm;
char *szAfsUsernameMap;
+ int iAfsTokenLifetime;
char *szUsernameMap;
char *szLogonScript;
char *szLogonPath;
@@ -386,7 +387,7 @@ typedef struct
BOOL bMap_archive;
BOOL bStoreDosAttributes;
BOOL bLocking;
- BOOL bStrictLocking;
+ int iStrictLocking;
BOOL bPosixLocking;
BOOL bShareModes;
BOOL bOpLocks;
@@ -511,7 +512,7 @@ static service sDefault = {
True, /* bMap_archive */
False, /* bStoreDosAttributes */
True, /* bLocking */
- True, /* bStrictLocking */
+ True, /* iStrictLocking */
True, /* bPosixLocking */
True, /* bShareModes */
True, /* bOpLocks */
@@ -794,8 +795,8 @@ static struct parm_struct parm_table[] = {
{"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
- {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
- {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
+ {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
+ {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
@@ -1075,7 +1076,7 @@ static struct parm_struct parm_table[] = {
{"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{N_("Ldap Options"), P_SEP, P_SEPARATOR},
@@ -1125,6 +1126,7 @@ static struct parm_struct parm_table[] = {
{"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
{"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
{"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
+ {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
{"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
@@ -1226,8 +1228,6 @@ static void init_printer_values(service *pService)
string_set(&pService->szLpresumecommand, "");
string_set(&pService->szQueuepausecommand, "");
string_set(&pService->szQueueresumecommand, "");
-
- string_set(&Globals.szPrintcapname, "cups");
#else
string_set(&pService->szLpqcommand, "/usr/bin/lpstat -o '%p'");
string_set(&pService->szLprmcommand, "/usr/bin/cancel '%p-%j'");
@@ -1236,7 +1236,6 @@ static void init_printer_values(service *pService)
string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
string_set(&pService->szQueuepausecommand, "/usr/bin/disable '%p'");
string_set(&pService->szQueueresumecommand, "/usr/bin/enable '%p'");
- string_set(&Globals.szPrintcapname, "lpstat");
#endif /* HAVE_CUPS */
break;
@@ -1346,7 +1345,6 @@ static void init_globals(void)
string_set(&Globals.szWorkgroup, lp_workgroup());
string_set(&Globals.szPasswdProgram, "");
- string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
string_set(&Globals.szPidDir, dyn_PIDDIR);
string_set(&Globals.szLockDir, dyn_LOCKDIR);
string_set(&Globals.szSocketAddress, "0.0.0.0");
@@ -1375,7 +1373,7 @@ static void init_globals(void)
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
Globals.max_mux = 50; /* This is *needed* for profile support. */
- Globals.lpqcachetime = 10;
+ Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
Globals.bDisableSpoolss = False;
Globals.iMaxSmbdProcesses = 0;/* no limit specified */
Globals.pwordlevel = 0;
@@ -1478,6 +1476,11 @@ static void init_globals(void)
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
+ /* This is what we tell the afs client. in reality we set the token
+ * to never expire, though, when this runs out the afs client will
+ * forget the token. Set to 0 to get NEVERDATE.*/
+ Globals.iAfsTokenLifetime = 604800;
+
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -1626,7 +1629,6 @@ FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
-FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
@@ -1652,6 +1654,7 @@ FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
+FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
@@ -1863,7 +1866,7 @@ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
FN_LOCAL_BOOL(lp_locking, bLocking)
-FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
+FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
@@ -2697,7 +2700,7 @@ BOOL lp_file_list_changed(void)
time_t mod_time;
pstrcpy(n2, f->name);
- standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
+ standard_sub_basic( username, n2, sizeof(n2) );
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
f->name, n2, ctime(&f->modtime)));
@@ -4280,13 +4283,33 @@ int lp_maxprintjobs(int snum)
return maxjobs;
}
+const char *lp_printcapname(void)
+{
+ if ((Globals.szPrintcapname != NULL) &&
+ (Globals.szPrintcapname[0] != '\0'))
+ return Globals.szPrintcapname;
+
+ if (sDefault.iPrinting == PRINT_CUPS) {
+#ifdef HAVE_CUPS
+ return "cups";
+#else
+ return "lpstat";
+#endif
+ }
+
+ if (sDefault.iPrinting == PRINT_BSD)
+ return "/etc/printcap";
+
+ return PRINTCAP_NAME;
+}
+
/*******************************************************************
Ensure we don't use sendfile if server smb signing is active.
********************************************************************/
BOOL lp_use_sendfile(int snum)
{
- extern int Protocol;
+ extern enum protocol_types Protocol;
/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
if (Protocol < PROTOCOL_NT1) {
return False;
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index f4f42bfa7f7..8a3d35defd9 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -76,6 +76,13 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAM
/* Check if this is our own sid. This should perhaps be done by
winbind? For the moment handle it here. */
+ if (sid->num_auths == 4 && sid_equal(get_global_sam_sid(), sid)) {
+ DOM_SID tmp_sid;
+ sid_copy(&tmp_sid, sid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ local_lookup_sid(sid, name, name_type);
+ }
+
if (sid->num_auths == 5) {
DOM_SID tmp_sid;
uint32 rid;
@@ -472,7 +479,7 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
or we are dead in the water */
if ( !winbind_sid_to_gid(pgid, psid) ) {
- DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n",
+ DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
sid_to_string(sid_str, psid) ));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 698b166e517..aeea4316f38 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -742,6 +742,14 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
GROUP_MAP map;
BOOL ret;
+ if (sid_equal(get_global_sam_sid(), sid)) {
+ *psid_name_use = SID_NAME_DOMAIN;
+ fstrcpy(name, "");
+ DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
+ sid_string_static(sid)));
+ return True;
+ }
+
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
sid_string_static(&map.sid)));
@@ -2215,6 +2223,28 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
return (buflen);
}
+BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
+{
+ BOOL result;
+ uint8 *buf;
+ int len;
+
+ if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
+ return False;
+
+ len = init_buffer_from_sam_v2(&buf, src, False);
+
+ if (len == -1)
+ return False;
+
+ result = init_sam_from_buffer_v2(*dst, buf, len);
+ (*dst)->methods = src->methods;
+
+ free(buf);
+
+ return result;
+}
+
/**********************************************************************
**********************************************************************/
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 0066262a328..9bc38fb4449 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -452,6 +452,24 @@ static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
num_entries, unix_only);
}
+static NTSTATUS context_enum_group_memberships(struct pdb_context *context,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->
+ enum_group_memberships(context->pdb_methods, username,
+ primary_gid, sids, gids, num_groups);
+}
+
static NTSTATUS context_find_alias(struct pdb_context *context,
const char *name, DOM_SID *sid)
{
@@ -587,7 +605,8 @@ static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
}
static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -598,8 +617,8 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
}
return context->pdb_methods->
- enum_alias_memberships(context->pdb_methods, sid, aliases,
- num);
+ enum_alias_memberships(context->pdb_methods, members,
+ num_members, aliases, num);
}
/******************************************************************
@@ -717,6 +736,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
(*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
(*context)->pdb_enum_group_mapping = context_enum_group_mapping;
+ (*context)->pdb_enum_group_memberships = context_enum_group_memberships;
(*context)->pdb_find_alias = context_find_alias;
(*context)->pdb_create_alias = context_create_alias;
@@ -870,6 +890,8 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
}
+static SAM_ACCOUNT *sam_account_cache = NULL;
+
BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -878,7 +900,17 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
return False;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username));
+ if (!NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context,
+ sam_acct, username)))
+ return False;
+
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
+ pdb_copy_sam_account(sam_acct, &sam_account_cache);
+ return True;
}
BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
@@ -889,6 +921,10 @@ BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
return False;
}
+ if ((sam_account_cache != NULL) &&
+ (sid_equal(sid, pdb_get_user_sid(sam_account_cache))))
+ return pdb_copy_sam_account(sam_account_cache, &sam_acct);
+
return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
}
@@ -911,6 +947,11 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
return False;
}
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
}
@@ -922,6 +963,11 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
return False;
}
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
}
@@ -1011,6 +1057,21 @@ BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
rmap, num_entries, unix_only));
}
+NTSTATUS pdb_enum_group_memberships(const char *username, gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return pdb_context->pdb_enum_group_memberships(pdb_context, username,
+ primary_gid, sids, gids,
+ num_groups);
+}
+
BOOL pdb_find_alias(const char *name, DOM_SID *sid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1125,7 +1186,7 @@ BOOL pdb_enum_aliasmem(const DOM_SID *alias,
members, num_members));
}
-BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
+BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
DOM_SID **aliases, int *num)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1135,7 +1196,8 @@ BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_alias_memberships(pdb_context, sid,
+ pdb_enum_alias_memberships(pdb_context, members,
+ num_members,
aliases, num));
}
@@ -1222,6 +1284,7 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
(*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
(*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
+ (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
(*methods)->find_alias = pdb_default_find_alias;
(*methods)->create_alias = pdb_default_create_alias;
(*methods)->delete_alias = pdb_default_delete_alias;
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 9659cbd5652..a84b2f35b28 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -2199,6 +2199,115 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
return ldapsam_getgroup(methods, filter, map);
}
+static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)methods->private_data;
+ struct smbldap_state *conn = ldap_state->smbldap_state;
+ pstring filter;
+ char *attrs[] = { "gidNumber", "sambaSID", NULL };
+ char *escape_name;
+ int rc;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *entry;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ int num_sids, num_gids;
+ extern DOM_SID global_sid_NULL;
+
+ if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
+ return pdb_default_enum_group_memberships(methods, username,
+ primary_gid, sids,
+ gids, num_groups);
+
+ *sids = NULL;
+ num_sids = 0;
+
+ escape_name = escape_ldap_string_alloc(username);
+
+ if (escape_name == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ pstr_sprintf(filter, "(&(objectClass=posixGroup)"
+ "(|(memberUid=%s)(gidNumber=%d)))",
+ username, primary_gid);
+
+ rc = smbldap_search(conn, lp_ldap_group_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ num_gids = 0;
+ *gids = NULL;
+
+ num_sids = 0;
+ *sids = NULL;
+
+ /* We need to add the primary group as the first gid/sid */
+
+ add_gid_to_array_unique(primary_gid, gids, &num_gids);
+
+ /* This sid will be replaced later */
+
+ add_sid_to_array_unique(&global_sid_NULL, sids, &num_sids);
+
+ for (entry = ldap_first_entry(conn->ldap_struct, msg);
+ entry != NULL;
+ entry = ldap_next_entry(conn->ldap_struct, entry))
+ {
+ fstring str;
+ DOM_SID sid;
+ gid_t gid;
+ char *end;
+
+ if (!smbldap_get_single_attribute(conn->ldap_struct,
+ entry, "sambaSID",
+ str, sizeof(str)-1))
+ goto done;
+
+ if (!string_to_sid(&sid, str))
+ goto done;
+
+ if (!smbldap_get_single_attribute(conn->ldap_struct,
+ entry, "gidNumber",
+ str, sizeof(str)-1))
+ goto done;
+
+ gid = strtoul(str, &end, 10);
+
+ if (PTR_DIFF(end, str) != strlen(str))
+ goto done;
+
+ if (gid == primary_gid) {
+ sid_copy(&(*sids)[0], &sid);
+ } else {
+ add_gid_to_array_unique(gid, gids, &num_gids);
+ add_sid_to_array_unique(&sid, sids, &num_sids);
+ }
+ }
+
+ if (sid_compare(&global_sid_NULL, &(*sids)[0]) == 0) {
+ DEBUG(3, ("primary group not found\n"));
+ goto done;
+ }
+
+ *num_groups = num_sids;
+
+ result = NT_STATUS_OK;
+
+ done:
+
+ SAFE_FREE(escape_name);
+ if (msg != NULL)
+ ldap_msgfree(msg);
+
+ return result;
+}
+
/**********************************************************************
*********************************************************************/
@@ -2733,71 +2842,73 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
}
static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num)
+ const DOM_SID *members,
+ int num_members,
+ DOM_SID **aliases, int *num_aliases)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
+ LDAP *ldap_struct;
- fstring sid_string;
- const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
+ char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
LDAPMessage *result = NULL;
LDAPMessage *entry = NULL;
- int count;
+ int i;
int rc;
- pstring filter;
+ char *filter;
+ TALLOC_CTX *mem_ctx;
- sid_to_string(sid_string, sid);
- pstr_sprintf(filter, "(&(|(objectclass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_SID_LIST), sid_string);
+ mem_ctx = talloc_init("ldapsam_alias_memberships");
+
+ if (mem_ctx == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ /* This query could be further optimized by adding a
+ (&(sambaSID=<domain-sid>*)) so that only those aliases that are
+ asked for in the getuseraliases are returned. */
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(|(objectclass=%s)(objectclass=%s))(|",
+ LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY);
+
+ for (i=0; i<num_members; i++)
+ filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
+ filter,
+ sid_string_static(&members[i]));
+
+ filter = talloc_asprintf(mem_ctx, "%s))", filter);
rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+ talloc_destroy(mem_ctx);
+
if (rc != LDAP_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
*aliases = NULL;
- *num = 0;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- result);
-
- if (count < 1) {
- ldap_msgfree(result);
- return NT_STATUS_OK;
- }
+ *num_aliases = 0;
+ ldap_struct = ldap_state->smbldap_state->ldap_struct;
- for (entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- result);
+ for (entry = ldap_first_entry(ldap_struct, result);
entry != NULL;
- entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- entry))
+ entry = ldap_next_entry(ldap_struct, entry))
{
- DOM_SID alias;
- char **vals;
- vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
- entry, LDAP_ATTRIBUTE_SID);
+ fstring sid_str;
+ DOM_SID sid;
- if (vals == NULL)
+ if (!smbldap_get_single_attribute(ldap_struct, entry,
+ LDAP_ATTRIBUTE_SID,
+ sid_str,
+ sizeof(sid_str)-1))
continue;
- if (vals[0] == NULL) {
- ldap_value_free(vals);
+ if (!string_to_sid(&sid, sid_str))
continue;
- }
-
- if (!string_to_sid(&alias, vals[0])) {
- ldap_value_free(vals);
- continue;
- }
- add_sid_to_array(&alias, aliases, num);
- ldap_value_free(vals);
+ add_sid_to_array_unique(&sid, aliases, num_aliases);
}
ldap_msgfree(result);
@@ -2856,6 +2967,7 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
(*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
(*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
(*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
+ (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
/* TODO: Setup private data and free */
diff --git a/source/passdb/pdb_mysql.c b/source/passdb/pdb_mysql.c
index deed27dbe49..0e6a11d9326 100644
--- a/source/passdb/pdb_mysql.c
+++ b/source/passdb/pdb_mysql.c
@@ -111,11 +111,11 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
pdb_set_plaintext_passwd(u, row[22]);
pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET);
- pdb_set_logon_divs(u, xatol(row[25]), PDB_SET);
- pdb_set_hours_len(u, xatol(row[26]), PDB_SET);
- pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET);
- pdb_set_logon_count(u, xatol(row[28]), PDB_SET);
- pdb_set_unknown_6(u, xatol(row[29]), PDB_SET);
+ pdb_set_logon_divs(u, xatol(row[24]), PDB_SET);
+ pdb_set_hours_len(u, xatol(row[25]), PDB_SET);
+ pdb_set_bad_password_count(u, xatol(row[26]), PDB_SET);
+ pdb_set_logon_count(u, xatol(row[27]), PDB_SET);
+ pdb_set_unknown_6(u, xatol(row[28]), PDB_SET);
return NT_STATUS_OK;
}
diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c
index 1731c720a21..6578d3d192a 100644
--- a/source/passdb/pdb_pgsql.c
+++ b/source/passdb/pdb_pgsql.c
@@ -98,8 +98,9 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ;
pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ;
- pdb_set_logon_divs ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
- pdb_set_hours_len ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ;
+ pdb_set_logon_divs ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ;
+ pdb_set_hours_len ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
+ pdb_set_bad_password_count ( u, PQgetlong (r, row, 26 ), PDB_SET ) ;
pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ;
diff --git a/source/passdb/pdb_sql.c b/source/passdb/pdb_sql.c
index 7e8c682cb85..820280bcbf6 100644
--- a/source/passdb/pdb_sql.c
+++ b/source/passdb/pdb_sql.c
@@ -201,6 +201,9 @@ char *sql_account_query_select(const char *data, BOOL update, enum sql_search_fi
field_string = config_value_read(data, "username column",
CONFIG_USERNAME_DEFAULT);
break;
+ default:
+ field_string = "unknown";
+ break;
}
asprintf(&query,
diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c
index 6eff57d365e..6eb7761a3b4 100644
--- a/source/passdb/pdb_xml.c
+++ b/source/passdb/pdb_xml.c
@@ -28,7 +28,7 @@
*/
-#define XML_URL "http://samba.org/~jelmer/sambapdb.dtd"
+#define XML_URL "http://samba.org/samba/DTD/passdb"
#include "includes.h"
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index f316b225ff4..6be63e4f9d6 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -50,7 +50,7 @@ static void get_rand_seed(int *new_seed)
BOOL secrets_init(void)
{
pstring fname;
- char dummy;
+ unsigned char dummy;
if (tdb)
return True;
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
index 1d5fcaf0548..c93c3400bd0 100644
--- a/source/passdb/util_sam_sid.c
+++ b/source/passdb/util_sam_sid.c
@@ -327,3 +327,16 @@ void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
return;
}
+
+
+void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
+{
+ int i;
+
+ for (i=0; i<(*num_sids); i++) {
+ if (sid_compare(sid, &(*sids)[i]) == 0)
+ return;
+ }
+
+ add_sid_to_array(sid, sids, num_sids);
+}
diff --git a/source/po/de.msg b/source/po/de.msg
index b62a17d150f..f5dc79b7247 100644
--- a/source/po/de.msg
+++ b/source/po/de.msg
@@ -29,7 +29,7 @@ msgstr ""
#: ../web/swat.c:117
#, c-format
msgid "ERROR: Can't open %s"
-msgstr "ERRORE: Kann %s nicht öffnen"
+msgstr "ERROR: Kann %s nicht öffnen"
#: ../web/swat.c:200
msgid "Help"
@@ -37,12 +37,12 @@ msgstr "Hilfe"
#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
msgid "Set Default"
-msgstr "Setze Standardwerte"
+msgstr "Standardwert"
#: ../web/swat.c:408
#, c-format
msgid "failed to open %s for writing"
-msgstr ""
+msgstr "konnte %s nicht schreiben"
#: ../web/swat.c:431
#, c-format
@@ -72,7 +72,7 @@ msgstr "Drucker"
#: ../web/swat.c:510
msgid "Wizard"
-msgstr ""
+msgstr "Assistent"
#: ../web/swat.c:513
msgid "Status"
@@ -92,7 +92,7 @@ msgstr "Aktuelle Konfiguration"
#: ../web/swat.c:527 ../web/swat.c:530
msgid "Basic"
-msgstr "Basis Ansicht"
+msgstr "Einfache Ansicht"
#: ../web/swat.c:528 ../web/swat.c:531
msgid "Advanced"
@@ -100,7 +100,7 @@ msgstr "Erweiterte Ansicht"
#: ../web/swat.c:529
msgid "Change View To"
-msgstr "Ändere Passwort"
+msgstr "Ansicht anpassen"
#: ../web/swat.c:554
msgid "Current Config"
@@ -122,48 +122,48 @@ msgstr ""
#: ../web/swat.c:608
msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
+msgstr "Hinweis: smb.conf wurde gelesen und überschrieben"
#. Here we go ...
#: ../web/swat.c:716
msgid "Samba Configuration Wizard"
-msgstr ""
+msgstr "Samba Konfigurations-Assistent"
#: ../web/swat.c:720
msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
+msgstr "Der Button \"Passe smb.conf an\" wird alle Kommentare und Standardwerte aus der smb.conf löschen."
#: ../web/swat.c:721
msgid "The same will happen if you press the commit button."
-msgstr ""
+msgstr "Das gleiche passiert bei \"übernehmen\"."
#: ../web/swat.c:724
msgid "Rewrite smb.conf file"
-msgstr ""
+msgstr "Schreibe smb.conf neu"
#: ../web/swat.c:725
msgid "Commit"
-msgstr "Kommentar"
+msgstr "übernehmen"
#: ../web/swat.c:726
msgid "Edit Parameter Values"
-msgstr "Drucker Parameter"
+msgstr "Bearbeite Parameter"
#: ../web/swat.c:732
msgid "Server Type"
-msgstr ""
+msgstr "Server-Typ"
#: ../web/swat.c:733
msgid "Stand Alone"
-msgstr ""
+msgstr "Einzelserver"
#: ../web/swat.c:734
msgid "Domain Member"
-msgstr "Domänen master"
+msgstr "Domänen-Mitglied"
#: ../web/swat.c:735
msgid "Domain Controller"
-msgstr "Domänen master"
+msgstr "Domänen-Controller"
#: ../web/swat.c:738
msgid "Unusual Type in smb.conf - Please Select New Mode"
@@ -171,51 +171,51 @@ msgstr ""
#: ../web/swat.c:740
msgid "Configure WINS As"
-msgstr ""
+msgstr "Konfiguriere WINS"
#: ../web/swat.c:741
msgid "Not Used"
-msgstr "nicht hinabsteigen"
+msgstr "nicht benutzt"
#: ../web/swat.c:742
msgid "Server for client use"
-msgstr ""
+msgstr "WINS-Server"
#: ../web/swat.c:743
msgid "Client of another WINS server"
-msgstr ""
+msgstr "WINS-Client an anderem Server"
#: ../web/swat.c:745
msgid "Remote WINS Server"
-msgstr ""
+msgstr "Zuständiger WINS-Server:"
#: ../web/swat.c:756
msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
+msgstr "Fehler: WINS-Server und WINS-Client zugleich in smb.conf gesetzt"
#: ../web/swat.c:757
msgid "Please Select desired WINS mode above."
-msgstr ""
+msgstr "Bitte wählen Sie den WINS-Modus."
#: ../web/swat.c:759
msgid "Expose Home Directories"
-msgstr ""
+msgstr "Home-Verzeichnisse freigeben"
#: ../web/swat.c:774
msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
+msgstr "Diese Konfigurationsoptionen bearbeiten mehrere Parameter und dienen als Hilfe zur schnellen Samba-Einrichtung."
#: ../web/swat.c:787
msgid "Global Parameters"
-msgstr "Globale Variablen"
+msgstr "Globale Parameter"
#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
msgid "Commit Changes"
-msgstr "Speichere Änderungen"
+msgstr "Änderungen speichern"
#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
msgid "Reset Values"
-msgstr "Setze Werte zurück"
+msgstr "Werte zurücksetzen"
#: ../web/swat.c:844
msgid "Share Parameters"
@@ -247,19 +247,19 @@ msgstr " \"Benutzername\" muss angegeben werden "
#: ../web/swat.c:999
msgid " Must specify \"Old Password\" "
-msgstr " \"Altes Passwort\" muß angegeben werden "
+msgstr " \"Altes Passwort\" muss angegeben werden "
#: ../web/swat.c:1005
msgid " Must specify \"Remote Machine\" "
-msgstr " \"Remote Maschine\" muß angegeben werden "
+msgstr " \"Remote-Server\" muss angegeben werden "
#: ../web/swat.c:1012
msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Neues/Bestätige Passwort\" muß angegeben werden "
+msgstr " \"Neues/wiederholtes Passwort\" müssen angegeben werden "
#: ../web/swat.c:1018
msgid " Re-typed password didn't match new password "
-msgstr " Das bestätigte Passwort stimmt nicht mit dem neuen Passwort überein"
+msgstr " Das wiederholte Passwort stimmt nicht mit dem neuen Passwort überein"
#: ../web/swat.c:1048
#, c-format
@@ -269,7 +269,7 @@ msgstr " Das Passwort für '%s' wurde geändert."
#: ../web/swat.c:1051
#, c-format
msgid " The passwd for '%s' has NOT been changed."
-msgstr " Das Passwort für '%s' wurde nicht geändert."
+msgstr " Das Passwort für '%s' wurde NICHT geändert."
#: ../web/swat.c:1076
msgid "Server Password Management"
@@ -292,7 +292,7 @@ msgstr "Neues Passwort"
#: ../web/swat.c:1093 ../web/swat.c:1138
msgid "Re-type New Password"
-msgstr "Bestätige neues Passwort"
+msgstr "Wiederhole neues Passwort"
#: ../web/swat.c:1101 ../web/swat.c:1149
msgid "Change Password"
@@ -320,7 +320,7 @@ msgstr "Client/Server Passwort Verwaltung"
#: ../web/swat.c:1140
msgid "Remote Machine"
-msgstr "Remote Maschine"
+msgstr "Remote-Server"
#: ../web/swat.c:1179
msgid "Printer Parameters"
@@ -328,15 +328,15 @@ msgstr "Drucker Parameter"
#: ../web/swat.c:1181
msgid "Important Note:"
-msgstr "Wichtige Hinweise:"
+msgstr "Wichtiger Hinweis:"
#: ../web/swat.c:1182
msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Mit [*] gekennzeichnete Druckername in der Druckerauswahlliste"
+msgstr "Mit [*] gekennzeichnete Drucker in der Druckerauswahlliste"
#: ../web/swat.c:1183
msgid "are autoloaded printers from "
-msgstr "wurde automatisch geladen von :"
+msgstr "wurden automatisch geladen von :"
#: ../web/swat.c:1184
msgid "Printcap Name"
@@ -372,7 +372,7 @@ msgstr ""
#: ../web/statuspage.c:309
msgid "Server Status"
-msgstr "Server Status"
+msgstr "Server-Status"
#: ../web/statuspage.c:314
msgid "Auto Refresh"
@@ -384,7 +384,7 @@ msgstr "Aktualisierungsintervall: "
#: ../web/statuspage.c:319
msgid "Stop Refreshing"
-msgstr "Stop Aktualisierung"
+msgstr "Stoppe Aktualisierung"
#: ../web/statuspage.c:334
msgid "version:"
@@ -404,11 +404,11 @@ msgstr "inaktiv"
#: ../web/statuspage.c:341
msgid "Stop smbd"
-msgstr "Stopp smbd"
+msgstr "Stoppe smbd"
#: ../web/statuspage.c:343
msgid "Start smbd"
-msgstr "Start smbd"
+msgstr "Starte smbd"
#: ../web/statuspage.c:345
msgid "Restart smbd"
@@ -420,11 +420,11 @@ msgstr ""
#: ../web/statuspage.c:354
msgid "Stop nmbd"
-msgstr "Stopp nmbd"
+msgstr "Stoppe nmbd"
#: ../web/statuspage.c:356
msgid "Start nmbd"
-msgstr "Start nmbd"
+msgstr "Starte nmbd"
#: ../web/statuspage.c:358
msgid "Restart nmbd"
@@ -436,11 +436,11 @@ msgstr ""
#: ../web/statuspage.c:368
msgid "Stop winbindd"
-msgstr "Stopp winbindd"
+msgstr "Stoppe winbindd"
#: ../web/statuspage.c:370
msgid "Start winbindd"
-msgstr "Start winbindd"
+msgstr "Starte winbindd"
#: ../web/statuspage.c:372
msgid "Restart winbindd"
@@ -449,16 +449,16 @@ msgstr "Neustart winbindd"
#. stop, restart all
#: ../web/statuspage.c:381
msgid "Stop All"
-msgstr ""
+msgstr "Alle Stoppen"
#: ../web/statuspage.c:382
msgid "Restart All"
-msgstr "Neustart Alle"
+msgstr "Alle neu starten"
#. start all
#: ../web/statuspage.c:386
msgid "Start All"
-msgstr "Start Alle"
+msgstr "Alle Starten"
#: ../web/statuspage.c:393
msgid "Active Connections"
@@ -474,7 +474,7 @@ msgstr ""
#: ../web/statuspage.c:395
msgid "IP address"
-msgstr "IP Adresse"
+msgstr "IP-Adresse"
#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
msgid "Date"
@@ -482,7 +482,7 @@ msgstr "Datum"
#: ../web/statuspage.c:397
msgid "Kill"
-msgstr "Kill"
+msgstr "Killen"
#: ../web/statuspage.c:405
msgid "Active Shares"
@@ -518,7 +518,7 @@ msgstr ""
#: ../web/statuspage.c:416
msgid "File"
-msgstr ""
+msgstr "Datei"
#: ../web/statuspage.c:425
msgid "Show Client in col 1"
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index dd7164b06a5..3ffedcf1858 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -593,8 +593,7 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
for (n=0; n<*count; n++) {
- if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
- DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
+ if ( strequal((*list)[n].name, form_name) ) {
update=True;
break;
}
@@ -618,6 +617,9 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
(*list)[n].right=form->right;
(*list)[n].bottom=form->bottom;
+ DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
+ update ? "updated" : "added", form_name));
+
return True;
}
@@ -2711,9 +2713,12 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
printer->info_2->sharename);
/* publish it */
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+ ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+
+ if (!ADS_ERR_OK(ads_rc))
+ DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
talloc_destroy(ctx);
@@ -2835,11 +2840,9 @@ WERROR check_published_printers(void)
{
ADS_STATUS ads_rc;
ADS_STRUCT *ads = NULL;
- void *res = NULL;
int snum;
int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR win_rc;
ads = ads_init(NULL, NULL, NULL);
if (!ads) {
@@ -2863,27 +2866,12 @@ WERROR check_published_printers(void)
if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
continue;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
- lp_servicename(snum))) ||
- !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- goto next;
-
- DEBUG(5, ("checking directory for printer %s\n", printer->info_2->printername));
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer->info_2->sharename, global_myname());
- if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
- DEBUG(5, ("printer %s is in directory\n", printer->info_2->printername));
- goto next;
- }
+ if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
+ lp_servicename(snum))) &&
+ (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
+ nt_printer_publish_ads(ads, printer);
- win_rc = nt_printer_publish_ads(ads, printer);
- if (!W_ERROR_IS_OK(win_rc))
- DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, dos_errstr(win_rc)));
-
- next:
free_a_printer(&printer, 2);
- ads_msgfree(ads, res);
- res = NULL;
}
ads_destroy(&ads);
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index d2b1a90a204..5cc36d6e170 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -66,12 +66,10 @@ void cups_printer_fn(void (*fn)(char *, char *))
ipp_attribute_t *attr; /* Current attribute */
cups_lang_t *language; /* Default language */
char *name, /* printer-name attribute */
- *make_model, /* printer-make-and-model attribute */
*info; /* printer-info attribute */
static const char *requested[] =/* Requested attributes */
{
"printer-name",
- "printer-make-and-model",
"printer-info"
};
@@ -151,7 +149,6 @@ void cups_printer_fn(void (*fn)(char *, char *))
*/
name = NULL;
- make_model = NULL;
info = NULL;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
@@ -160,10 +157,6 @@ void cups_printer_fn(void (*fn)(char *, char *))
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
if (strcmp(attr->name, "printer-info") == 0 &&
attr->value_tag == IPP_TAG_TEXT)
info = attr->values[0].string.text;
@@ -178,12 +171,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
+ (*fn)(name, info);
}
ippDelete(response);
@@ -245,7 +233,6 @@ void cups_printer_fn(void (*fn)(char *, char *))
*/
name = NULL;
- make_model = NULL;
info = NULL;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
@@ -254,10 +241,6 @@ void cups_printer_fn(void (*fn)(char *, char *))
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
if (strcmp(attr->name, "printer-info") == 0 &&
attr->value_tag == IPP_TAG_TEXT)
info = attr->values[0].string.text;
@@ -272,12 +255,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
+ (*fn)(name, info);
}
ippDelete(response);
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 07b157bcd95..d9db500425e 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -88,9 +88,9 @@ static void populate_printers(void)
*tmp = '\0';
/* add it to the cache */
- if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
+ if ((ptmp = SMB_MALLOC_P(printer_t)) != NULL) {
ZERO_STRUCTP(ptmp);
- if((ptmp->name = strdup(name)) == NULL)
+ if((ptmp->name = SMB_STRDUP(name)) == NULL)
DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
ptmp->next = printers;
printers = ptmp;
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 6b0e992ced4..b5785440aeb 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -43,10 +43,12 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
jobids are assigned when a job starts spooling.
*/
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
+struct print_queue_update_context {
+ char* sharename;
+ enum printing_types printing_type;
+ char* lpqcommand;
+};
+
static TDB_CONTEXT *rap_tdb;
static uint16 next_rap_jobid;
@@ -55,6 +57,11 @@ struct rap_jobid_key {
uint32 jobid;
};
+/***************************************************************************
+ Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
+ bit RPC jobids.... JRA.
+***************************************************************************/
+
uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
{
uint16 rap_jobid;
@@ -837,7 +844,7 @@ static pid_t get_updating_pid(fstring sharename)
in the tdb.
****************************************************************************/
-static void set_updating_pid(const fstring sharename, BOOL delete)
+static void set_updating_pid(const fstring sharename, BOOL updating)
{
fstring keystr;
TDB_DATA key;
@@ -853,8 +860,12 @@ static void set_updating_pid(const fstring sharename, BOOL delete)
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
key.dptr = keystr;
key.dsize = strlen(keystr);
+
+ DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
+ updating ? "" : "not ",
+ sharename ));
- if (delete) {
+ if ( !updating ) {
tdb_delete(pdb->tdb, key);
release_print_db(pdb);
return;
@@ -978,11 +989,69 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid
}
}
-struct print_queue_update_context {
- fstring sharename;
- enum printing_types printing_type;
- pstring lpqcommand;
-};
+/****************************************************************************
+ Check if the print queue has been updated recently enough.
+****************************************************************************/
+
+static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
+{
+ fstring key;
+ time_t last_qscan_time, time_now = time(NULL);
+ struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ BOOL result = False;
+
+ if (!pdb)
+ return False;
+
+ snprintf(key, sizeof(key), "CACHE/%s", sharename);
+ last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
+
+ /*
+ * Invalidate the queue for 3 reasons.
+ * (1). last queue scan time == -1.
+ * (2). Current time - last queue scan time > allowed cache time.
+ * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
+ * This last test picks up machines for which the clock has been moved
+ * forward, an lpq scan done and then the clock moved back. Otherwise
+ * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
+ */
+
+ if (last_qscan_time == ((time_t)-1)
+ || (time_now - last_qscan_time) >= lp_lpqcachetime()
+ || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
+ {
+ time_t msg_pending_time;
+
+ DEBUG(4, ("print_cache_expired: cache expired for queue %s "
+ "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
+ sharename, (int)last_qscan_time, (int)time_now,
+ (int)lp_lpqcachetime() ));
+
+ /* check if another smbd has already sent a message to update the
+ queue. Give the pending message one minute to clear and
+ then send another message anyways. Make sure to check for
+ clocks that have been run forward and then back again. */
+
+ snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
+
+ if ( check_pending
+ && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time )
+ && msg_pending_time > 0
+ && msg_pending_time <= time_now
+ && (time_now - msg_pending_time) < 60 )
+ {
+ DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
+ sharename));
+ goto done;
+ }
+
+ result = True;
+ }
+
+done:
+ release_print_db(pdb);
+ return result;
+}
/****************************************************************************
main work for updating the lpq cahe for a printer queue
@@ -1003,12 +1072,20 @@ static void print_queue_update_internal( const char *sharename,
fstring keystr, cachestr;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
+ sharename, current_printif->type, lpq_command));
+
+ if ( !print_cache_expired(sharename, False) ) {
+ DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
+ return;
+ }
+
/*
* Update the cache time FIRST ! Stops others even
* attempting to get the lock and doing this
* if the lpq takes a long time.
*/
-
+
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
@@ -1019,8 +1096,8 @@ static void print_queue_update_internal( const char *sharename,
current_printif->type,
lpq_command, &queue, &status);
- DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
- "s" : "", sharename));
+ DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
+ qcount, (qcount != 1) ? "s" : "", sharename));
/* Sort the queue by submission time otherwise they are displayed
in hash order. */
@@ -1084,14 +1161,14 @@ static void print_queue_update_internal( const char *sharename,
SAFE_FREE(tstruct.queue);
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
+ DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
sharename, tstruct.total_jobs ));
tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
get_queue_status(sharename, &old_status);
if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
+ DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
old_status.qcount, qcount, sharename));
/* store the new queue status structure */
@@ -1112,6 +1189,20 @@ static void print_queue_update_internal( const char *sharename,
slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
+ /* clear the msg pending record for this queue */
+
+ snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
+
+ if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
+ /* log a message but continue on */
+
+ DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
+ sharename));
+ }
+
+ release_print_db( pdb );
+
+ return;
}
/****************************************************************************
@@ -1128,6 +1219,8 @@ static void print_queue_update_with_lock(int snum)
struct printif *current_printif = get_printer_fns( snum );
fstrcpy(sharename, lp_const_servicename(snum));
+
+ DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
pdb = get_print_db_byname(sharename);
if (!pdb)
return;
@@ -1147,7 +1240,7 @@ static void print_queue_update_with_lock(int snum)
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
/* Only wait 10 seconds for this. */
if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename));
+ DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
release_print_db(pdb);
return;
}
@@ -1172,7 +1265,7 @@ static void print_queue_update_with_lock(int snum)
*/
/* Tell others we're doing the update. */
- set_updating_pid(sharename, False);
+ set_updating_pid(sharename, True);
/*
* Allow others to enter and notice we're doing
@@ -1192,26 +1285,38 @@ static void print_queue_update_with_lock(int snum)
print_queue_update_internal( sharename, current_printif, lpq_command );
/* Delete our pid from the db. */
- set_updating_pid(sharename, True);
+ set_updating_pid(sharename, False);
release_print_db(pdb);
}
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
+static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
{
- struct print_queue_update_context *ctx;
+ struct print_queue_update_context ctx;
+ fstring sharename;
+ pstring lpqcommand;
+ size_t len;
+
+ len = tdb_unpack( buf, msglen, "fdP",
+ sharename,
+ &ctx.printing_type,
+ lpqcommand );
- if (len != sizeof(struct print_queue_update_context)) {
- DEBUG(1, ("Got invalid print queue update message\n"));
+ if ( len == -1 ) {
+ DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
return;
}
- ctx = (struct print_queue_update_context*)buf;
- print_queue_update_internal(ctx->sharename,
- get_printer_fns_from_type(ctx->printing_type),
- ctx->lpqcommand );
+ ctx.sharename = sharename;
+ ctx.lpqcommand = lpqcommand;
+
+ print_queue_update_internal(ctx.sharename,
+ get_printer_fns_from_type(ctx.printing_type),
+ ctx.lpqcommand );
+
+ return;
}
static pid_t background_lpq_updater_pid = -1;
@@ -1277,27 +1382,84 @@ update the internal database from the system print queue for a queue
static void print_queue_update(int snum)
{
struct print_queue_update_context ctx;
+ fstring key;
+ fstring sharename;
+ pstring lpqcommand;
+ char *buffer = NULL;
+ size_t len = 0;
+ size_t newlen;
+ struct tdb_print_db *pdb;
/*
* Make sure that the background queue process exists.
* Otherwise just do the update ourselves
*/
-
- if ( background_lpq_updater_pid != -1 ) {
- fstrcpy(ctx.sharename, lp_const_servicename(snum));
- ctx.printing_type = lp_printing(snum);
-
- pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum));
- pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) );
- standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) );
- become_root();
- message_send_pid(background_lpq_updater_pid,
- MSG_PRINTER_UPDATE, &ctx, sizeof(ctx),
- False);
- unbecome_root();
- } else
+ if ( background_lpq_updater_pid == -1 ) {
print_queue_update_with_lock( snum );
+ return;
+ }
+
+ fstrcpy( sharename, lp_const_servicename(snum));
+
+ ctx.printing_type = lp_printing(snum);
+
+ pstrcpy( lpqcommand, lp_lpqcommand(snum));
+ pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
+ standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+
+ ctx.sharename = SMB_STRDUP( sharename );
+ ctx.lpqcommand = SMB_STRDUP( lpqcommand );
+
+ /* get the length */
+
+ len = tdb_pack( buffer, len, "fdP",
+ ctx.sharename,
+ ctx.printing_type,
+ ctx.lpqcommand );
+
+ buffer = SMB_XMALLOC_ARRAY( char, len );
+
+ /* now pack the buffer */
+ newlen = tdb_pack( buffer, len, "fdP",
+ ctx.sharename,
+ ctx.printing_type,
+ ctx.lpqcommand );
+
+ SMB_ASSERT( newlen == len );
+
+ DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
+ "type = %d, lpq command = [%s]\n",
+ ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
+
+ /* here we set a msg pending record for other smbd processes
+ to throttle the number of duplicate print_queue_update msgs
+ sent. */
+
+ pdb = get_print_db_byname(sharename);
+ snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
+
+ if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
+ /* log a message but continue on */
+
+ DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
+ sharename));
+ }
+
+ release_print_db( pdb );
+
+ /* finally send the message */
+
+ become_root();
+ message_send_pid(background_lpq_updater_pid,
+ MSG_PRINTER_UPDATE, buffer, len, False);
+ unbecome_root();
+
+ SAFE_FREE( ctx.sharename );
+ SAFE_FREE( ctx.lpqcommand );
+ SAFE_FREE( buffer );
+
+ return;
}
/****************************************************************************
@@ -1897,45 +2059,6 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
}
/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static BOOL print_cache_expired(int snum)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
- last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
- DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
- (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
- return True;
- }
- release_print_db(pdb);
- return False;
-}
-
-/****************************************************************************
Get the queue status - do not update if db is out of date.
****************************************************************************/
@@ -1979,7 +2102,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
int len;
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* also fetch the queue status */
@@ -2294,7 +2417,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
pjob_store(sharename, jobid, pjob);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
return True;
@@ -2326,7 +2449,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
const char* sharename = lp_servicename(snum);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
*pcount = 0;
@@ -2447,7 +2570,7 @@ int print_queue_status(int snum,
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* return if we are done */
@@ -2547,7 +2670,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
}
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* Send a printer notify message */
diff --git a/source/profile/profile.c b/source/profile/profile.c
index 689f67da997..e6d34e68cda 100644
--- a/source/profile/profile.c
+++ b/source/profile/profile.c
@@ -22,7 +22,7 @@
#include "includes.h"
#ifdef WITH_PROFILE
-#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
+#define IPC_PERMS ((S_IRUSR | S_IWUSR) | S_IRGRP | S_IROTH)
#endif /* WITH_PROFILE */
#ifdef WITH_PROFILE
diff --git a/source/python/py_common.c b/source/python/py_common.c
index 02d22bbdab5..66f35759c3d 100644
--- a/source/python/py_common.c
+++ b/source/python/py_common.c
@@ -144,34 +144,34 @@ BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
password_obj = PyDict_GetItemString(creds, "password");
if (!username_obj) {
- *errstr = strdup("no username field in credential");
+ *errstr = SMB_STRDUP("no username field in credential");
return False;
}
if (!domain_obj) {
- *errstr = strdup("no domain field in credential");
+ *errstr = SMB_STRDUP("no domain field in credential");
return False;
}
if (!password_obj) {
- *errstr = strdup("no password field in credential");
+ *errstr = SMB_STRDUP("no password field in credential");
return False;
}
/* Check type of required fields */
if (!PyString_Check(username_obj)) {
- *errstr = strdup("username field is not string type");
+ *errstr = SMB_STRDUP("username field is not string type");
return False;
}
if (!PyString_Check(domain_obj)) {
- *errstr = strdup("domain field is not string type");
+ *errstr = SMB_STRDUP("domain field is not string type");
return False;
}
if (!PyString_Check(password_obj)) {
- *errstr = strdup("password field is not string type");
+ *errstr = SMB_STRDUP("password field is not string type");
return False;
}
@@ -226,7 +226,7 @@ struct cli_state *open_pipe_creds(char *server, PyObject *creds,
username, domain, password, 0, Undefined, NULL);
if (!NT_STATUS_IS_OK(result)) {
- *errstr = strdup("error connecting to IPC$ pipe");
+ *errstr = SMB_STRDUP("error connecting to IPC$ pipe");
return NULL;
}
diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c
index abb4af11e60..1a2174d58c6 100644
--- a/source/rpc_client/cli_ds.c
+++ b/source/rpc_client/cli_ds.c
@@ -163,5 +163,3 @@ done:
return result;
}
-
-
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 3fb032234f5..b88753a7ed0 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -654,6 +654,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
char *workstation_name_slash;
uint8 netlogon_sess_key[16];
static uint8 zeros[16];
+ int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -716,10 +717,15 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
memset(info3->user_sess_key, '\0', 16);
}
- if (memcmp(zeros, info3->padding, 16) != 0) {
- SamOEMhash(info3->padding, netlogon_sess_key, 16);
+ if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
+ SamOEMhash(info3->lm_sess_key, netlogon_sess_key, 8);
} else {
- memset(info3->padding, '\0', 16);
+ memset(info3->lm_sess_key, '\0', 8);
+ }
+
+ memset(&info3->acct_flags, '\0', 4);
+ for (i=0; i < 7; i++) {
+ memset(&info3->unknown[i], '\0', 4);
}
/* Return results */
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index c547a80415d..0ebc16581b7 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -921,7 +921,7 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
if (buf) {
rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
num_chars = strlen_w(str->buffer);
- if (flags == STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
+ if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
num_chars++;
}
}
@@ -1109,6 +1109,53 @@ BOOL init_unistr2_array(UNISTR2_ARRAY *array,
return True;
}
+BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
+ return False;
+ if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
+ return False;
+ if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
+ return False;
+
+ return True;
+}
+
+BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
+ depth++;
+
+ if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
+ return False;
+
+ if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
+ return False;
+ if(!prs_uint32("length", ps, depth, &account_lockout->length))
+ return False;
+
+ if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
+ return False;
+ if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
+ return False;
+ if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
+ return False;
+ if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
+ return False;
+#if 0
+ if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
+ return False;
+#endif
+
+ return True;
+}
+
/*******************************************************************
Reads or writes a UNISTR2_ARRAY structure.
********************************************************************/
@@ -1695,6 +1742,21 @@ BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
+reads or writes a BUFHDR4 structure.
+********************************************************************/
+BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_bufhdr4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(hdr->size));
+ prs_uint32("buffer", ps, depth, &(hdr->buffer));
+
+ return True;
+}
+
+/*******************************************************************
reads or writes a BUFFER4 structure.
********************************************************************/
BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 97ca0d406b4..5f1d4b622e3 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1454,12 +1454,16 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
- memset((char *)usr->padding, '\0', sizeof(usr->padding));
+ memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key));
+ memset(&usr->acct_flags, '\0', sizeof(usr->acct_flags));
-#if 0 /* JRATEST - exchange auth test. */
- if (lm_session_key != NULL)
- memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key));
-#endif
+ for (i=0; i<7; i++) {
+ memset(&usr->unknown[i], '\0', sizeof(usr->unknown));
+ }
+
+ if (lm_session_key != NULL) {
+ memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key));
+ }
num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
@@ -1580,9 +1584,19 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
return False;
- if(!prs_uint8s (False, "padding ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
+
+ if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */
return False;
+ if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags */
+ return False;
+
+ for (i = 0; i < 7; i++)
+ {
+ if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */
+ return False;
+ }
+
if (validation_level == 3) {
if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
return False;
@@ -1923,15 +1937,26 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
return False;
if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
return False;
-
- if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
- return False;
-
- if (ps->data_offset + 40 > ps->buffer_size)
- return False;
- ps->data_offset += 40;
+ if (!prs_uint32("security_information", ps, depth, &info->security_information))
+ return False;
+ if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
+ return False;
+ if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
+ return False;
+ if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
+ return False;
+ if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
+ return False;
+ if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
+ return False;
if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
info->hdr_dom_name.buffer, ps, depth))
@@ -1943,9 +1968,20 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
info->hdr_sec_desc.buffer, ps, depth))
return False;
- if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
- info->hdr_unknown.buffer, ps, depth))
- return False;
+
+ if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout,
+ info->hdr_account_lockout.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2,
+ info->hdr_unknown2.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3,
+ info->hdr_unknown3.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4,
+ info->hdr_unknown4.buffer, ps, depth))
+ return False;
return True;
}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index cdb31906859..8d5fee68e0b 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -592,6 +592,40 @@ static BOOL sam_io_unk_info7(const char *desc, SAM_UNK_INFO_7 * u_7,
inits a structure.
********************************************************************/
+void init_unk_info8(SAM_UNK_INFO_8 * u_8, uint32 seq_num)
+{
+ unix_to_nt_time(&u_8->domain_create_time, 0);
+ u_8->seq_num.low = seq_num;
+ u_8->seq_num.high = 0x0000;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_unk_info8(const char *desc, SAM_UNK_INFO_8 * u_8,
+ prs_struct *ps, int depth)
+{
+ if (u_8 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info8");
+ depth++;
+
+ if (!prs_uint64("seq_num", ps, depth, &u_8->seq_num))
+ return False;
+
+ if(!smb_io_time("domain_create_time", &u_8->domain_create_time, ps, depth))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+inits a structure.
+********************************************************************/
+
void init_unk_info12(SAM_UNK_INFO_12 * u_12, NTTIME nt_lock_duration, NTTIME nt_reset_time, uint16 lockout)
{
u_12->duration.low = nt_lock_duration.low;
@@ -662,17 +696,15 @@ inits a structure.
********************************************************************/
void init_unk_info2(SAM_UNK_INFO_2 * u_2,
- const char *domain, const char *server,
- uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias)
+ const char *comment, const char *domain, const char *server,
+ uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias, NTTIME nt_logout)
{
- u_2->unknown_0 = 0x00000000;
- u_2->unknown_1 = 0x80000000;
- u_2->unknown_2 = 0x00000000;
+ u_2->logout.low = nt_logout.low;
+ u_2->logout.high = nt_logout.high;
- u_2->ptr_0 = 1;
+ u_2->seq_num.low = seq_num;
+ u_2->seq_num.high = 0x00000000;
- u_2->seq_num = seq_num;
- u_2->unknown_3 = 0x00000000;
u_2->unknown_4 = 0x00000001;
u_2->unknown_5 = 0x00000003;
@@ -683,6 +715,8 @@ void init_unk_info2(SAM_UNK_INFO_2 * u_2,
memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
+ init_unistr2(&u_2->uni_comment, comment, UNI_FLAGS_NONE);
+ init_uni_hdr(&u_2->hdr_comment, &u_2->uni_comment);
init_unistr2(&u_2->uni_domain, domain, UNI_FLAGS_NONE);
init_uni_hdr(&u_2->hdr_domain, &u_2->uni_domain);
init_unistr2(&u_2->uni_server, server, UNI_FLAGS_NONE);
@@ -702,14 +736,9 @@ static BOOL sam_io_unk_info2(const char *desc, SAM_UNK_INFO_2 * u_2,
prs_debug(ps, depth, desc, "sam_io_unk_info2");
depth++;
- if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
+ if(!smb_io_time("logout", &u_2->logout, ps, depth))
return False;
- if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2)) /* 0x0000 0000 */
- return False;
-
- if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0))
+ if(!smb_io_unihdr("hdr_comment", &u_2->hdr_comment, ps, depth))
return False;
if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth))
return False;
@@ -720,9 +749,7 @@ static BOOL sam_io_unk_info2(const char *desc, SAM_UNK_INFO_2 * u_2,
pointer is referring to
*/
- if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num)) /* 0x0000 0099 or 0x1000 0000 */
- return False;
- if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3)) /* 0x0000 0000 */
+ if(!prs_uint64("seq_num ", ps, depth, &u_2->seq_num))
return False;
if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4)) /* 0x0000 0001 */
@@ -738,15 +765,8 @@ static BOOL sam_io_unk_info2(const char *desc, SAM_UNK_INFO_2 * u_2,
if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps))
return False;
- if (u_2->ptr_0) {
- /* this was originally marked as 'padding'. It isn't
- padding, it is some sort of optional 12 byte
- structure. When it is present it contains zeros
- !? */
- if(!prs_uint8s(False, "unknown", ps, depth, u_2->padding,sizeof(u_2->padding)))
- return False;
- }
-
+ if(!smb_io_unistr2("uni_comment", &u_2->uni_comment, u_2->hdr_comment.buffer, ps, depth))
+ return False;
if(!smb_io_unistr2("uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth))
return False;
if(!smb_io_unistr2("uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth))
@@ -854,6 +874,10 @@ BOOL samr_io_r_query_dom_info(const char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
return False;
break;
+ case 0x08:
+ if(!sam_io_unk_info8("unk_inf8",&r_u->ctr->info.inf8, ps,depth))
+ return False;
+ break;
case 0x07:
if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth))
return False;
@@ -1662,7 +1686,7 @@ NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_en
}
init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
+ init_unistr2(&sam->str[i].uni_srv_desc, acct_desc, UNI_FLAGS_NONE);
init_sam_entry2(&sam->sam[i], start_idx + i + 1,
&sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 8a5e17669a4..84c45b59014 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -3309,7 +3309,7 @@ BOOL srv_io_r_net_disk_enum(const char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_stru
DISK_INFO *dinfo;
if(!(dinfo = PRS_ALLOC_MEM(ps, DISK_INFO, entries_read3)))
- return False;
+ return False;
r_n->disk_enum_ctr.disk_info = dinfo;
}
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index d73e503173c..fcd574971f7 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -279,8 +279,8 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
}
dom_idx = init_dom_ref(ref, dom_name, &find_sid);
- DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
- "referenced list.\n", dom_name, name ));
+ DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
+ sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index c913a7dcb8f..820c8e7a3c2 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -1938,11 +1938,16 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
+ struct passwd *passwd;
DOM_SID sid;
+ DOM_SID *sids;
DOM_GID *gids = NULL;
int num_groups = 0;
+ gid_t *unix_gids;
+ int i, num_gids, num_sids;
uint32 acc_granted;
BOOL ret;
+ NTSTATUS result;
/*
* from the SID in the request:
@@ -1981,19 +1986,52 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
-
- if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
+
+ passwd = getpwnam_alloc(pdb_get_username(sam_pass));
+ if (passwd == NULL) {
pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_GROUP;
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ sids = NULL;
+ num_sids = 0;
+
+ become_root();
+ result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
+ passwd->pw_gid,
+ &sids, &unix_gids, &num_groups);
+ unbecome_root();
+
+ pdb_free_sam(&sam_pass);
+ passwd_free(&passwd);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ SAFE_FREE(unix_gids);
+
+ gids = NULL;
+ num_gids = 0;
+
+ for (i=0; i<num_groups; i++) {
+ uint32 rid;
+
+ if (!sid_peek_check_rid(get_global_sam_sid(),
+ &(sids[i]), &rid))
+ continue;
+
+ gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
+ gids[num_gids].attr=7;
+ gids[num_gids].g_rid = rid;
+ num_gids += 1;
}
+ SAFE_FREE(sids);
/* construct the response. lkclXXXX: gids are not copied! */
init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
- pdb_free_sam(&sam_pass);
-
return r_u->status;
}
@@ -2075,10 +2113,15 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
}
num_groups=info->disp_info.num_group_account;
free_samr_db(info);
-
+
+ account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ u_logout = account_policy_temp;
+
+ unix_to_nt_time_abs(&nt_logout, u_logout);
+
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
- num_users, num_groups, num_aliases);
+ init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
+ num_users, num_groups, num_aliases, nt_logout);
break;
case 0x03:
account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
@@ -2095,6 +2138,9 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
case 0x07:
init_unk_info7(&ctr->info.inf7);
break;
+ case 0x08:
+ init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp * 60;
@@ -3114,31 +3160,19 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
- int num_groups = 0, tmp_num_groups=0;
- uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
+ int num_groups = 0;
+ uint32 *rids=NULL;
struct samr_info *info = NULL;
- int i,j;
+ int i;
NTSTATUS ntstatus1;
NTSTATUS ntstatus2;
- /* until i see a real useraliases query, we fack one up */
+ DOM_SID *members;
+ DOM_SID *aliases;
+ int num_aliases;
+ BOOL res;
- /* I have seen one, JFM 2/12/2001 */
- /*
- * Explanation of what this call does:
- * for all the SID given in the request:
- * return a list of alias (local groups)
- * that have those SID as members.
- *
- * and that's the alias in the domain specified
- * in the policy_handle
- *
- * if the policy handle is on an incorrect sid
- * for example a user's sid
- * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
- */
-
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
@@ -3161,40 +3195,42 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
!sid_check_is_builtin(&info->sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
- for (i=0; i<q_u->num_sids1; i++) {
+ if (members == NULL)
+ return NT_STATUS_NO_MEMORY;
- r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
+ for (i=0; i<q_u->num_sids1; i++)
+ sid_copy(&members[i], &q_u->sid[i].sid);
- /*
- * if there is an error, we just continue as
- * it can be an unfound user or group
- */
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
- continue;
- }
+ become_root();
+ res = pdb_enum_alias_memberships(members,
+ q_u->num_sids1, &aliases,
+ &num_aliases);
+ unbecome_root();
+
+ if (!res)
+ return NT_STATUS_UNSUCCESSFUL;
+
+ rids = NULL;
+ num_groups = 0;
- if (tmp_num_groups==0) {
- DEBUG(10,("_samr_query_useraliases: no groups found\n"));
+ for (i=0; i<num_aliases; i++) {
+ uint32 rid;
+
+ if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
continue;
- }
- new_rids=TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+tmp_num_groups);
- if (new_rids==NULL) {
- DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
+ rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
+
+ if (rids == NULL)
return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
- for (j=0; j<tmp_num_groups; j++)
- rids[j+num_groups]=tmp_rids[j];
-
- safe_free(tmp_rids);
-
- num_groups+=tmp_num_groups;
+ rids[num_groups] = rid;
+ num_groups += 1;
}
-
+ SAFE_FREE(aliases);
+
init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
return NT_STATUS_OK;
}
@@ -4329,9 +4365,14 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
num_groups=info->disp_info.num_group_account;
free_samr_db(info);
+ account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ u_logout = account_policy_temp;
+
+ unix_to_nt_time_abs(&nt_logout, u_logout);
+
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
- num_users, num_groups, num_aliases);
+ init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
+ num_users, num_groups, num_aliases, nt_logout);
break;
case 0x03:
account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
@@ -4350,6 +4391,9 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
case 0x07:
init_unk_info7(&ctr->info.inf7);
break;
+ case 0x08:
+ init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp * 60;
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 7336e429afa..a3424fe73be 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -512,24 +512,14 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
/* Search all sharenames first as this is easier than pulling
the printer_info_2 off of disk */
-
- for (snum=0; !found && snum<n_services; snum++) {
-
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
- continue;
-
- /* ------ sharename ------ */
-
- fstrcpy(sname, lp_servicename(snum));
-
- DEBUGADD(10, ("share: %s\n",sname));
-
- if ( strequal(sname, aprinter) ) {
- found = True;
- }
+
+ snum = find_service(aprinter);
+
+ if ( lp_snum_ok(snum) && lp_print_ok(snum) ) {
+ found = True;
+ fstrcpy( sname, aprinter );
}
-
/* do another loop to look for printernames */
for (snum=0; !found && snum<n_services; snum++) {
@@ -5857,7 +5847,6 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
- struct current_user user;
WERROR result;
int snum;
@@ -5870,6 +5859,17 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
result = WERR_BADFID;
goto done;
}
+
+ /* Check the user has permissions to change the security
+ descriptor. By experimentation with two NT machines, the user
+ requires Full Access to the printer to change security
+ information. */
+
+ if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
+ DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
/* NT seems to like setting the security descriptor even though
nothing may have actually changed. */
@@ -5919,20 +5919,6 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
goto done;
}
- /* Work out which user is performing the operation */
-
- get_current_user(&user, p);
-
- /* Check the user has permissions to change the security
- descriptor. By experimentation with two NT machines, the user
- requires Full Access to the printer to change security
- information. */
-
- if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
done:
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index c4b6adbbb4a..af4c94800a5 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -356,15 +356,12 @@ out:
static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
{
- int len_net_name;
pstring remark;
- char *net_name = lp_servicename(snum);
+ const char *net_name = lp_servicename(snum);
pstrcpy(remark, lp_comment(snum));
standard_sub_conn(p->conn, remark, sizeof(remark));
- len_net_name = strlen(net_name);
-
init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
}
@@ -375,7 +372,6 @@ static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501,
static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
{
- int len_net_name;
pstring net_name;
pstring remark;
pstring path;
@@ -401,7 +397,6 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
string_replace(path, '/', '\\');
pstrcpy(passwd, "");
- len_net_name = strlen(net_name);
sd = get_share_security(ctx, snum, &sd_size);
@@ -2139,8 +2134,8 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
r_u->disk_enum_ctr.unknown = 0;
if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
- return WERR_NOMEM;
- }
+ return WERR_NOMEM;
+ }
r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 0d8a1d10999..802e7673a40 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -79,240 +79,6 @@ static const rid_name domain_group_rids[] =
{ 0 , NULL }
};
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid)
-{
- SAM_ACCOUNT *sam_pass=NULL;
- int i, cur_rid=0;
- gid_t gid;
- gid_t *groups = NULL;
- int num_groups;
- GROUP_MAP map;
- DOM_SID tmp_sid;
- fstring user_name;
- fstring str_domsid, str_qsid;
- uint32 rid,grid;
- uint32 *rids=NULL, *new_rids=NULL;
- gid_t winbind_gid_low, winbind_gid_high;
- BOOL ret;
- BOOL winbind_groups_exist;
-
- *prids=NULL;
- *numgroups=0;
-
- winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
-
-
- DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n",
- sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid)));
-
- pdb_init_sam(&sam_pass);
- become_root();
- ret = pdb_getsampwsid(sam_pass, q_sid);
- unbecome_root();
- if (ret == False) {
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- fstrcpy(user_name, pdb_get_username(sam_pass));
- grid=pdb_get_group_rid(sam_pass);
- if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = getgroups_user(user_name, &groups, &num_groups);
- if (!ret) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: getgroups_user failed\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- for (i=0;i<num_groups;i++) {
-
- become_root();
- ret = get_group_from_gid(groups[i], &map);
- unbecome_root();
-
- if ( !ret ) {
- DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
- continue;
- }
-
- /* if it's not an alias, continue */
- if (map.sid_name_use != SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- continue;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- continue;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name));
- continue;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name));
- continue;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- free(groups);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
- break;
- }
-
- if(num_groups)
- free(groups);
-
- /* now check for the user's gid (the primary group rid) */
- for (i=0; i<cur_rid && grid!=rids[i]; i++)
- ;
-
- /* the user's gid is already there */
- if (i!=cur_rid) {
- DEBUG(10,("get_alias_user_groups: user is already in the list. good.\n"));
- goto done;
- }
-
- DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name));
-
- if(!get_group_from_gid(gid, &map)) {
- DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your "
- "/etc/passwd and /etc/group files\n", user_name));
- goto done;
- }
-
- /* the primary group isn't an alias */
- if (map.sid_name_use!=SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- goto done;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- goto done;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name ));
- goto done;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name ));
- goto done;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
-
-done:
- *prids=rids;
- *numgroups=cur_rid;
- pdb_free_sam(&sam_pass);
-
- return NT_STATUS_OK;
-}
-
-
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass)
-{
-
- const char *username = pdb_get_username(sam_pass);
- int n_unix_groups;
- int i,j;
- gid_t *unix_groups;
-
- *numgroups = 0;
- *pgids = NULL;
-
- if (!getgroups_user(username, &unix_groups, &n_unix_groups)) {
- return False;
- }
-
- /* now setup the space for storing the SIDS */
-
- if (n_unix_groups > 0) {
-
- *pgids = TALLOC_ARRAY(ctx, DOM_GID, n_unix_groups);
-
- if (!*pgids) {
- DEBUG(0, ("get_user_group: malloc() failed for DOM_GID list!\n"));
- SAFE_FREE(unix_groups);
- return False;
- }
- }
-
- become_root();
- j = 0;
- for (i = 0; i < n_unix_groups; i++) {
- GROUP_MAP map;
- uint32 rid;
-
- if (!pdb_getgrgid(&map, unix_groups[i])) {
- DEBUG(3, ("get_user_groups: failed to convert gid %ld to a domain group!\n",
- (long int)unix_groups[i+1]));
- if (i == 0) {
- DEBUG(1,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", username));
- DEBUGADD(1,("get_domain_user_groups: You should fix it, NT doesn't like that\n"));
- }
- } else if ((map.sid_name_use == SID_NAME_DOM_GRP)
- && sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)) {
- (*pgids)[j].attr=7;
- (*pgids)[j].g_rid=rid;
- j++;
- }
- }
- unbecome_root();
-
- *numgroups = j;
-
- SAFE_FREE(unix_groups);
-
- return True;
-}
/*******************************************************************
gets a domain user's groups from their already-calculated NT_USER_TOKEN
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 3bd55aff065..91296a49678 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -153,21 +153,37 @@ static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
printf("Server:\t%s\n", name);
+ unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
+ printf("Comment:\t%s\n", name);
+
printf("Total Users:\t%d\n", info2->num_domain_usrs);
printf("Total Groups:\t%d\n", info2->num_domain_grps);
printf("Total Aliases:\t%d\n", info2->num_local_grps);
- printf("Sequence No:\t%d\n", info2->seq_num);
-
- printf("Unknown 0:\t0x%x\n", info2->unknown_0);
- printf("Unknown 1:\t0x%x\n", info2->unknown_1);
- printf("Unknown 2:\t0x%x\n", info2->unknown_2);
- printf("Unknown 3:\t0x%x\n", info2->unknown_3);
+ printf("Sequence No:\t%d\n", info2->seq_num.low);
+
+ printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
+
printf("Unknown 4:\t0x%x\n", info2->unknown_4);
printf("Unknown 5:\t0x%x\n", info2->unknown_5);
printf("Unknown 6:\t0x%x\n", info2->unknown_6);
}
+static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
+{
+ printf("Sequence No:\t%d\n", info8->seq_num.low);
+ printf("Domain Create Time:\t%s\n",
+ http_timestring(nt_time_to_unix(&info8->domain_create_time)));
+
+}
+
+static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
+{
+ printf("Bad password lockout duration: %s\n", display_time(info12->duration));
+ printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
+ printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
+}
+
static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
{
fstring tmp;
@@ -1121,6 +1137,12 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
case 2:
display_sam_unk_info_2(&ctr.info.inf2);
break;
+ case 8:
+ display_sam_unk_info_8(&ctr.info.inf8);
+ break;
+ case 12:
+ display_sam_unk_info_12(&ctr.info.inf12);
+ break;
default:
printf("cannot display domain info for switch value %d\n",
switch_level);
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 3824881c18b..0b0d015238e 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -1709,7 +1709,7 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS,
+ PRINTER_ALL_ACCESS,
servername, cli->user_name, &handle);
if (!W_ERROR_IS_OK(werror))
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
index d83c0bdc4d8..28fdbab77e5 100644
--- a/source/sam/idmap_ldap.c
+++ b/source/sam/idmap_ldap.c
@@ -466,7 +466,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
ldap_mods_free( mods, True );
if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
+ DEBUG(1,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
type));
goto out;
}
diff --git a/source/sam/idmap_rid.c b/source/sam/idmap_rid.c
index 48b38fb0d85..e1e45514435 100644
--- a/source/sam/idmap_rid.c
+++ b/source/sam/idmap_rid.c
@@ -159,6 +159,7 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
char **trusted_domain_names;
DOM_SID *trusted_domain_sids;
uint32 enum_ctx = 0;
+ DOM_SID builtin_sid;
/* put the results together */
*num_domains = 1;
@@ -271,18 +272,23 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
}
/* put the results together */
- *num_domains = trusted_num_domains + 1;
- *domain_names = (fstring *) realloc(domain_names, sizeof(fstring) * *num_domains);
- *domain_sids = (DOM_SID *) realloc(domain_sids, sizeof(DOM_SID) * *num_domains);
+ *num_domains = trusted_num_domains + 2;
+ *domain_names = (fstring *) realloc(*domain_names, sizeof(fstring) * *num_domains);
+ *domain_sids = (DOM_SID *) realloc(*domain_sids, sizeof(DOM_SID) * *num_domains);
- /* first add myself at the end*/
+ /* first add myself */
fstrcpy((*domain_names)[0], domain_name);
sid_copy(&(*domain_sids)[0], domain_sid);
+ /* then add BUILTIN */
+ string_to_sid(&builtin_sid, "S-1-5-32");
+ fstrcpy((*domain_names)[1], "BUILTIN");
+ sid_copy(&(*domain_sids)[1], &builtin_sid);
+
/* add trusted domains */
for (i=0; i<trusted_num_domains; i++) {
- fstrcpy((*domain_names)[i+1], trusted_domain_names[i]);
- sid_copy(&((*domain_sids)[i+1]), &(trusted_domain_sids[i]));
+ fstrcpy((*domain_names)[i+2], trusted_domain_names[i]);
+ sid_copy(&((*domain_sids)[i+2]), &(trusted_domain_sids[i]));
}
/* show complete domain list */
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index c91f8599c96..540acfc2250 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -753,9 +753,8 @@ static NTSTATUS check_oem_password(const char *user,
uint16 acct_ctrl;
uint32 new_pw_len;
uchar new_nt_hash[16];
- uchar old_nt_hash_plain[16];
uchar new_lm_hash[16];
- uchar old_lm_hash_plain[16];
+ uchar verifier[16];
char no_pw[2];
BOOL ret;
@@ -784,7 +783,7 @@ static NTSTATUS check_oem_password(const char *user,
return NT_STATUS_ACCOUNT_DISABLED;
}
- if (acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) {
+ if ((acct_ctrl & ACB_PWNOTREQ) && lp_null_passwords()) {
/* construct a null password (in case one is needed */
no_pw[0] = 0;
no_pw[1] = 0;
@@ -818,9 +817,14 @@ static NTSTATUS check_oem_password(const char *user,
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
} else if (lm_pass_set) {
- DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
- user));
- pdb_free_sam(&sampass);
+ if (lp_lanman_auth()) {
+ DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
+ user));
+ } else {
+ DEBUG(1, ("LM password change supplied for user %s, but we have disabled LanMan authentication\n",
+ user));
+ }
+ pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
} else {
DEBUG(1, ("password change requested for user %s, but no password supplied!\n",
@@ -854,12 +858,10 @@ static NTSTATUS check_oem_password(const char *user,
if (nt_pw) {
/*
- * Now use new_nt_hash as the key to see if the old
- * password matches.
+ * check the NT verifier
*/
- D_P16(new_nt_hash, old_nt_hash_encrypted, old_nt_hash_plain);
-
- if (memcmp(nt_pw, old_nt_hash_plain, 16)) {
+ E_old_pw_hash(new_nt_hash, nt_pw, verifier);
+ if (memcmp(verifier, old_nt_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
@@ -884,12 +886,10 @@ static NTSTATUS check_oem_password(const char *user,
if (lanman_pw) {
/*
- * Now use new_nt_hash as the key to see if the old
- * LM password matches.
+ * check the lm verifier
*/
- D_P16(new_nt_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
+ E_old_pw_hash(new_nt_hash, lanman_pw, verifier);
+ if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
@@ -908,12 +908,10 @@ static NTSTATUS check_oem_password(const char *user,
E_deshash(new_passwd, new_lm_hash);
/*
- * Now use new_lm_hash as the key to see if the old
- * password matches.
+ * check the lm verifier
*/
- D_P16(new_lm_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
+ E_old_pw_hash(new_lm_hash, lanman_pw, verifier);
+ if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index fc5fe9d7418..32e2f058fc2 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -217,7 +217,8 @@ BOOL register_message_flags(BOOL doreg, uint32 msg_flags)
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) {
- DEBUG(0,("register_message_flags: tdb_fetch failed\n"));
+ DEBUG(0,("register_message_flags: tdb_fetch failed: %s\n",
+ tdb_errorstr(tdb)));
return False;
}
@@ -228,7 +229,7 @@ BOOL register_message_flags(BOOL doreg, uint32 msg_flags)
pcrec->bcast_msg_flags &= ~msg_flags;
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("register_message_flags: tdb_store failed with error %s.\n",
+ DEBUG(0,("register_message_flags: tdb_store failed: %s.\n",
tdb_errorstr(tdb) ));
SAFE_FREE(dbuf.dptr);
return False;
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 7199b3ebbf3..fefcaca09d5 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -23,7 +23,7 @@
/****************************************************************************
Change a dos mode to a unix mode.
Base permission for files:
- if inheriting
+ if creating file and inheriting
apply read/write bits from parent directory.
else
everybody gets read bit set
@@ -43,7 +43,7 @@
}
****************************************************************************/
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname)
+mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
@@ -52,7 +52,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname)
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
- if (fname && lp_inherit_perms(SNUM(conn))) {
+ if (fname && creating_file && lp_inherit_perms(SNUM(conn))) {
char *dname;
SMB_STRUCT_STAT sbuf;
@@ -329,7 +329,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
chmod a file - but preserve some bits.
********************************************************************/
-int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st)
+int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file)
{
SMB_STRUCT_STAT st1;
int mask=0;
@@ -338,7 +338,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
int ret = -1;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
- if (!st) {
+ if (!st || (st && !VALID_STAT(*st))) {
st = &st1;
if (SMB_VFS_STAT(conn,fname,st))
return(-1);
@@ -359,7 +359,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
return 0;
}
- unixmode = unix_mode(conn,dosmode,fname);
+ unixmode = unix_mode(conn,dosmode,fname, creating_file);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index bc62683eaee..a21bd69a36c 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -130,6 +130,20 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
if (ret != -1) {
fsp->pos += ret;
+ /*
+ * It turns out that setting the last write time from a Windows
+ * client stops any subsequent writes from updating the write time.
+ * Doing this after the write gives a race condition here where
+ * a stat may see the changed write time before we reset it here,
+ * but it's cheaper than having to store the write time in shared
+ * memory and look it up using dev/inode across all running smbd's.
+ * The 99% solution will hopefully be good enough in this case. JRA.
+ */
+
+ if (fsp->pending_modtime) {
+ set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime);
+ }
+
/* Yes - this is correct - writes don't update this. JRA. */
/* Found by Samba4 tests. */
#if 0
@@ -177,7 +191,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
fsp->size = (SMB_BIG_UINT)st.st_size;
if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
- file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
+ file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False);
}
/*
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index ec8176e1234..9fcd39b5002 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -502,7 +502,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
goto bad_param;
if (pcnt) {
- if (pdisp+pcnt >= tpscnt)
+ if (pdisp+pcnt > tpscnt)
goto bad_param;
if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
goto bad_param;
@@ -518,7 +518,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
if (dcnt) {
- if (ddisp+dcnt >= tdscnt)
+ if (ddisp+dcnt > tdscnt)
goto bad_param;
if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
goto bad_param;
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index f4dad2ddb9c..4af11da7844 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -760,18 +760,10 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
return(True);
}
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum))
- return(False);
-
+ snum = find_service(QueueName);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+ return False;
+
if (uLevel==52) {
count = get_printerdrivernumber(snum);
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
@@ -1501,6 +1493,8 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
data_len = fixed_len = string_len = 0;
for (i=0;i<count;i++) {
fstring servicename_dos;
+ if (!(lp_browseable(i) && lp_snum_ok(i)))
+ continue;
push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
@@ -1529,6 +1523,8 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
for( i = 0; i < count; i++ )
{
fstring servicename_dos;
+ if (!(lp_browseable(i) && lp_snum_ok(i)))
+ continue;
push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
@@ -1740,13 +1736,15 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
int count=0;
SAM_ACCOUNT *sampw = NULL;
BOOL ret = False;
- DOM_GID *gids = NULL;
- int num_groups = 0;
+ DOM_SID *sids;
+ gid_t *gids;
+ int num_groups;
int i;
fstring grp_domain;
fstring grp_name;
enum SID_NAME_USE grp_type;
- DOM_SID sid, dom_sid;
+ struct passwd *passwd;
+ NTSTATUS result;
*rparam_len = 8;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
@@ -1777,6 +1775,11 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
/* Lookup the user information; This should only be one of
our accounts (not remote domains) */
+
+ passwd = getpwnam_alloc(UserName);
+
+ if (passwd == NULL)
+ return False;
pdb_init_sam( &sampw );
@@ -1785,35 +1788,26 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
if ( !pdb_getsampwnam(sampw, UserName) )
goto out;
- /* this next set of code is horribly inefficient, but since
- it is rarely called, I'm going to leave it like this since
- it easier to follow --jerry */
-
- /* get the list of group SIDs */
-
- if ( !get_domain_user_groups(conn->mem_ctx, &num_groups, &gids, sampw) ) {
- DEBUG(1,("api_NetUserGetGroups: get_domain_user_groups() failed!\n"));
+ sids = NULL;
+ num_groups = 0;
+
+ result = pdb_enum_group_memberships(pdb_get_username(sampw),
+ passwd->pw_gid,
+ &sids, &gids, &num_groups);
+
+ if (!NT_STATUS_IS_OK(result))
goto out;
- }
- /* convert to names (we don't support universal groups so the domain
- can only be ours) */
-
- sid_copy( &dom_sid, get_global_sam_sid() );
for (i=0; i<num_groups; i++) {
- /* make the DOM_GID into a DOM_SID and then lookup
- the name */
-
- sid_copy( &sid, &dom_sid );
- sid_append_rid( &sid, gids[i].g_rid );
-
- if ( lookup_sid(&sid, grp_domain, grp_name, &grp_type) ) {
+ if ( lookup_sid(&sids[i], grp_domain, grp_name, &grp_type) ) {
pstrcpy(p, grp_name);
p += 21;
count++;
}
}
+
+ SAFE_FREE(sids);
*rdata_len = PTR_DIFF(p,*rdata);
@@ -1826,6 +1820,7 @@ out:
unbecome_root(); /* END ROOT BLOCK */
pdb_free_sam( &sampw );
+ passwd_free(&passwd);
return ret;
}
@@ -2142,6 +2137,12 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
goto out;
}
+ snum = lp_servicenumber( sharename);
+ if (snum == -1) {
+ errcode = NERR_DestNotFound;
+ goto out;
+ }
+
errcode = NERR_notsupported;
switch (function) {
@@ -2967,6 +2968,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
+ snum = lp_servicenumber( sharename);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
count = print_queue_status(snum,&queue,&status);
@@ -3037,20 +3039,18 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
/* check it's a supported variant */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(name);
- if (snum < 0 && pcap_printername_ok(name,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(name,pnum);
- snum = lp_servicenumber(name);
- }
- }
+ if (strcmp(str1,"zWrLeh") != 0)
+ return False;
+
+ if (uLevel > 2)
+ return False; /* defined only for uLevel 0,1,2 */
+
+ if (!check_printjob_info(&desc,uLevel,str2))
+ return False;
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
+ snum = find_service(name);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+ return False;
count = print_queue_status(snum,&queue,&status);
if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
@@ -3153,16 +3153,8 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
if (strcmp(str1,"zWrLh") != 0) return False;
if (!check_printdest_info(&desc,uLevel,str2)) return False;
- snum = lp_servicenumber(PrinterName);
- if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(PrinterName,pnum);
- snum = lp_servicenumber(PrinterName);
- }
- }
-
- if (snum < 0) {
+ snum = find_service(PrinterName);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
*rdata_len = 0;
desc.errcode = NERR_DestNotFound;
desc.neededlen = 0;
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 447073acd84..9aaa818c62a 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -20,7 +20,7 @@
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int max_recv;
BOOL global_encrypted_passwords_negotiated = False;
BOOL global_spnego_negotiated = False;
@@ -523,6 +523,12 @@ int reply_negprot(connection_struct *conn,
/* possibly reload - change of architecture */
reload_services(True);
+
+ /* moved from the netbios session setup code since we don't have that
+ when the client connects to port 445. Of course there is a small
+ window where we are listening to messages -- jerry */
+
+ claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 755b5abb160..2395d0d8db5 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -21,7 +21,7 @@
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int smb_read_error;
extern int global_oplock_break;
extern struct current_user current_user;
@@ -1144,7 +1144,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
pstring fname;
char *params = *ppparams;
@@ -1662,7 +1662,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
/* Grrr. We have to do this as open_file_shared1 adds aARCH when it
creates the file. This isn't the correct thing to do in the copy case. JRA */
- file_set_dosmode(conn, newname, fmode, &sbuf2);
+ file_set_dosmode(conn, newname, fmode, &sbuf2, True);
if (ret < (SMB_OFF_T)sbuf1.st_size) {
return NT_STATUS_DISK_FULL;
@@ -1783,7 +1783,7 @@ int reply_nttranss(connection_struct *conn,
static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *setup = *ppsetup;
files_struct *fsp;
@@ -1819,7 +1819,7 @@ name = %s\n", fsp->fsp_name ));
static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params = *ppparams;
pstring new_name;
@@ -1886,9 +1886,8 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
char *data = *ppdata;
prs_struct pd;
@@ -1998,7 +1997,7 @@ security descriptor.\n"));
static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params= *ppparams;
char *data = *ppdata;
@@ -2039,7 +2038,7 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb
static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
uint32 function;
uint16 fidnum;
@@ -2116,7 +2115,6 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* Allocate the correct amount and return the pointer to let
* it be deallocated when we return.
*/
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
SHADOW_COPY_DATA *shadow_data = NULL;
TALLOC_CTX *shadow_mem_ctx = NULL;
BOOL labels = False;
@@ -2289,10 +2287,9 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
NTSTATUS nt_status = NT_STATUS_OK;
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
char *pdata = *ppdata;
char *entry;
@@ -2543,7 +2540,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params = *ppparams;
char *pdata = *ppdata;
@@ -2662,10 +2659,10 @@ int reply_nttrans(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#if 0 /* Not used. */
uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#endif /* Not used. */
uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
@@ -2711,7 +2708,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
goto bad_param;
}
-
+
/* Don't allow more than 128mb for each value. */
if ((total_parameter_count > (1024*1024*128)) || (total_data_count > (1024*1024*128))) {
END_PROFILE(SMBnttrans);
@@ -2836,7 +2833,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
}
if (parameter_count) {
- if (parameter_displacement + parameter_count >= total_parameter_count)
+ if (parameter_displacement + parameter_count > total_parameter_count)
goto bad_param;
if ((parameter_displacement + parameter_count < parameter_displacement) ||
(parameter_displacement + parameter_count < parameter_count))
@@ -2853,7 +2850,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
}
if (data_count) {
- if (data_displacement + data_count >= total_data_count)
+ if (data_displacement + data_count > total_data_count)
goto bad_param;
if ((data_displacement + data_count < data_displacement) ||
(data_displacement + data_count < data_count))
@@ -2882,7 +2879,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_create);
break;
case NT_TRANSACT_IOCTL:
@@ -2891,7 +2888,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_ioctl);
break;
case NT_TRANSACT_SET_SECURITY_DESC:
@@ -2900,7 +2897,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_set_security_desc);
break;
case NT_TRANSACT_NOTIFY_CHANGE:
@@ -2909,7 +2906,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_notify_change);
break;
case NT_TRANSACT_RENAME:
@@ -2918,7 +2915,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_rename);
break;
@@ -2928,7 +2925,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_query_security_desc);
break;
#ifdef HAVE_SYS_QUOTAS
@@ -2938,7 +2935,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_get_user_quota);
break;
case NT_TRANSACT_SET_USER_QUOTA:
@@ -2947,7 +2944,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
length, bufsize,
&setup, setup_count,
&params, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_set_user_quota);
break;
#endif /* HAVE_SYS_QUOTAS */
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 278c195f10f..bf3fbf7fecd 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -979,7 +979,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
struct pending_message_list *pml = NULL;
uint16 mid = get_current_mid();
/* We add aARCH to this as this mode is only used if the file is created new. */
- mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
+ mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname, True);
if (oplock_request == INTERNAL_OPEN_ONLY) {
internal_only_open = True;
@@ -1376,6 +1376,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
(*Access) = open_mode;
}
+ action = 0;
+
if (file_existed && !(flags2 & O_TRUNC))
action = FILE_WAS_OPENED;
if (file_existed && (flags2 & O_TRUNC))
@@ -1438,7 +1440,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
/* Files should be initially set as archive */
if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
- file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
+ file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL, True);
}
}
@@ -1599,7 +1601,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return NULL;
}
- if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
+ if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname, True)) < 0) {
DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index f7e9c595c13..6c7faa4c056 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -241,6 +241,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
p->pnum, smb_mincnt, smb_maxcnt, nread));
+ /* Ensure we set up the message length to include the data length read. */
+ set_message_bcc(outbuf,nread);
return chain_reply(inbuf,outbuf,length,bufsize);
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 321d5e20ab4..903b9435225 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -1867,7 +1867,7 @@ static mode_t create_default_mode(files_struct *fsp, BOOL interitable_mode)
int snum = SNUM(fsp->conn);
mode_t and_bits = (mode_t)0;
mode_t or_bits = (mode_t)0;
- mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name) : S_IRUSR;
+ mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name, False) : S_IRUSR;
if (fsp->is_directory)
mode |= (S_IWUSR|S_IXUSR);
@@ -2641,10 +2641,10 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
size_t sd_size = 0;
SEC_ACL *psa = NULL;
size_t num_acls = 0;
- size_t num_dir_acls = 0;
+ size_t num_def_acls = 0;
size_t num_aces = 0;
SMB_ACL_T posix_acl = NULL;
- SMB_ACL_T dir_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
@@ -2672,8 +2672,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
*/
if(fsp->is_directory) {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
- dir_acl = free_empty_sys_acl(conn, dir_acl);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl = free_empty_sys_acl(conn, def_acl);
}
} else {
@@ -2690,7 +2690,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
posix_acl ? "present" : "absent",
- dir_acl ? "present" : "absent" ));
+ def_acl ? "present" : "absent" ));
pal = load_inherited_info(fsp);
@@ -2728,8 +2728,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
return 0;
}
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ if (fsp->is_directory && def_acl) {
+ dir_ace = canonicalise_acl(fsp, def_acl, &sbuf,
&global_sid_Creator_Owner,
&global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
}
@@ -2793,15 +2793,15 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
}
num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
+ num_def_acls = count_canon_ace_list(dir_ace);
/* Allocate the ace list. */
- if ((nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE, num_acls + num_profile_acls + num_dir_acls)) == NULL) {
+ if ((nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE,num_acls + num_profile_acls + num_def_acls)) == NULL) {
DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
goto done;
}
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+ memset(nt_ace_list, '\0', (num_acls + num_def_acls) * sizeof(SEC_ACE) );
/*
* Create the NT ACE list from the canonical ace lists.
@@ -2827,7 +2827,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
ace = dir_ace;
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ for (i = 0; i < num_def_acls; i++, ace = ace->next) {
SEC_ACCESS acc;
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
@@ -2883,9 +2883,11 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
* inherited at file create time, so ACLs never contain
* any ACEs that are inherited dynamically. The DACL_PROTECTED
* flag doesn't seem to bother Windows NT.
+ * Always set this if map acl inherit is turned off.
*/
- if (get_protected_flag(pal))
+ if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) {
psd->type |= SE_DESC_DACL_PROTECTED;
+ }
}
if (psd->dacl)
@@ -2897,8 +2899,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
if (posix_acl)
SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
- if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl)
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
free_inherited_info(pal);
@@ -3376,14 +3378,378 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
BOOL directory_has_default_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
- BOOL has_acl = False;
- SMB_ACL_ENTRY_T entry;
+ SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ BOOL has_acl = False;
+ SMB_ACL_ENTRY_T entry;
- if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
- has_acl = True;
+ if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
+ has_acl = True;
+ }
- if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
return has_acl;
}
+
+/****************************************************************************
+ Map from wire type to permset.
+****************************************************************************/
+
+static BOOL unix_ex_wire_to_permset(connection_struct *conn, unsigned char wire_perm, SMB_ACL_PERMSET_T *p_permset)
+{
+ if (wire_perm & ~(SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE)) {
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) == -1) {
+ return False;
+ }
+
+ if (wire_perm & SMB_POSIX_ACL_READ) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1) {
+ return False;
+ }
+ }
+ if (wire_perm & SMB_POSIX_ACL_WRITE) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1) {
+ return False;
+ }
+ }
+ if (wire_perm & SMB_POSIX_ACL_EXECUTE) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1) {
+ return False;
+ }
+ }
+ return True;
+}
+
+/****************************************************************************
+ Map from wire type to tagtype.
+****************************************************************************/
+
+static BOOL unix_ex_wire_to_tagtype(unsigned char wire_tt, SMB_ACL_TAG_T *p_tt)
+{
+ switch (wire_tt) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ *p_tt = SMB_ACL_USER_OBJ;
+ break;
+ case SMB_POSIX_ACL_USER:
+ *p_tt = SMB_ACL_USER;
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ *p_tt = SMB_ACL_GROUP_OBJ;
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ *p_tt = SMB_ACL_GROUP;
+ break;
+ case SMB_POSIX_ACL_MASK:
+ *p_tt = SMB_ACL_MASK;
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ *p_tt = SMB_ACL_OTHER;
+ break;
+ default:
+ return False;
+ }
+ return True;
+}
+
+/****************************************************************************
+ Create a new POSIX acl from wire permissions.
+ FIXME ! How does the share mask/mode fit into this.... ?
+****************************************************************************/
+
+static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, uint16 num_acls, const char *pdata)
+{
+ unsigned int i;
+ SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, num_acls);
+
+ if (the_acl == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < num_acls; i++) {
+ SMB_ACL_ENTRY_T the_entry;
+ SMB_ACL_PERMSET_T the_permset;
+ SMB_ACL_TAG_T tag_type;
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to create entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ if (!unix_ex_wire_to_tagtype(CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), &tag_type)) {
+ DEBUG(0,("create_posix_acl_from_wire: invalid wire tagtype %u on entry %u.\n",
+ CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), i ));
+ goto fail;
+ }
+
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, tag_type) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set tagtype on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ /* Get the permset pointer from the new ACL entry. */
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to get permset on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ /* Map from wire to permissions. */
+ if (!unix_ex_wire_to_permset(conn, CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+1), &the_permset)) {
+ DEBUG(0,("create_posix_acl_from_wire: invalid permset %u on entry %u.\n",
+ CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE) + 1), i ));
+ goto fail;
+ }
+
+ /* Now apply to the new ACL entry. */
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to add permset on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ if (tag_type == SMB_ACL_USER) {
+ uint32 uidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ uid_t uid = (uid_t)uidval;
+ if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&uid) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set uid %u on entry %u. (%s)\n",
+ (unsigned int)uid, i, strerror(errno) ));
+ goto fail;
+ }
+ }
+
+ if (tag_type == SMB_ACL_GROUP) {
+ uint32 gidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ gid_t gid = (uid_t)gidval;
+ if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&gid) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set gid %u on entry %u. (%s)\n",
+ (unsigned int)gid, i, strerror(errno) ));
+ goto fail;
+ }
+ }
+ }
+
+ return the_acl;
+
+ fail:
+
+ if (the_acl != NULL) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
+ }
+ return NULL;
+}
+
+/****************************************************************************
+ Calls from UNIX extensions - Default POSIX ACL set.
+ If num_def_acls == 0 and not a directory just return. If it is a directory
+ and num_def_acls == 0 then remove the default acl. Else set the default acl
+ on the directory.
+****************************************************************************/
+
+BOOL set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
+ uint16 num_def_acls, const char *pdata)
+{
+ SMB_ACL_T def_acl = NULL;
+
+ if (num_def_acls && !S_ISDIR(psbuf->st_mode)) {
+ DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
+ errno = EISDIR;
+ return False;
+ }
+
+ if (!num_def_acls) {
+ /* Remove the default ACL. */
+ if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fname) == -1) {
+ DEBUG(5,("set_unix_posix_default_acl: acl_delete_def_file failed on directory %s (%s)\n",
+ fname, strerror(errno) ));
+ return False;
+ }
+ return True;
+ }
+
+ if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) {
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
+ DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ return False;
+ }
+
+ DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ return True;
+}
+
+/****************************************************************************
+ Remove an ACL from a file. As we don't have acl_delete_entry() available
+ we must read the current acl and copy all entries except MASK, USER and GROUP
+ to a new acl, then set that. This (at least on Linux) causes any ACL to be
+ removed.
+ FIXME ! How does the share mask/mode fit into this.... ?
+****************************************************************************/
+
+static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname)
+{
+ SMB_ACL_T file_acl = NULL;
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+ BOOL ret = False;
+ /* Create a new ACL with only 3 entries, u/g/w. */
+ SMB_ACL_T new_file_acl = SMB_VFS_SYS_ACL_INIT(conn, 3);
+ SMB_ACL_ENTRY_T user_ent = NULL;
+ SMB_ACL_ENTRY_T group_ent = NULL;
+ SMB_ACL_ENTRY_T other_ent = NULL;
+
+ if (new_file_acl == NULL) {
+ DEBUG(5,("remove_posix_acl: failed to init new ACL with 3 entries for file %s.\n", fname));
+ return False;
+ }
+
+ /* Now create the u/g/w entries. */
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &user_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create user entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, user_ent, SMB_ACL_USER_OBJ) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set user entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &group_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create group entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, group_ent, SMB_ACL_GROUP_OBJ) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set group entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &other_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create other entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, other_ent, SMB_ACL_OTHER) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set other entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ /* Get the current file ACL. */
+ if (fsp && fsp->fd != -1) {
+ file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
+ } else {
+ file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
+ }
+
+ if (file_acl == NULL) {
+ /* This is only returned if an error occurred. Even for a file with
+ no acl a u/g/w acl should be returned. */
+ DEBUG(5,("remove_posix_acl: failed to get ACL from file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, file_acl, entry_id, &entry) == 1) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY)
+ entry_id = SMB_ACL_NEXT_ENTRY;
+
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to get tagtype from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to get permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (tagtype == SMB_ACL_USER_OBJ) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, user_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ } else if (tagtype == SMB_ACL_GROUP_OBJ) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, group_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ } else if (tagtype == SMB_ACL_OTHER) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, other_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ }
+ }
+
+ ret = True;
+
+ done:
+
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (new_file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, new_file_acl);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ Calls from UNIX extensions - POSIX ACL set.
+ If num_def_acls == 0 then read/modify/write acl after removing all entries
+ except SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER.
+****************************************************************************/
+
+BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16 num_acls, const char *pdata)
+{
+ SMB_ACL_T file_acl = NULL;
+
+ if (!num_acls) {
+ /* Remove the ACL from the file. */
+ return remove_posix_acl(conn, fsp, fname);
+ }
+
+ if ((file_acl = create_posix_acl_from_wire(conn, num_acls, pdata)) == NULL) {
+ return False;
+ }
+
+ if (fsp && fsp->fd != -1) {
+ /* The preferred way - use an open fd. */
+ if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, file_acl) == -1) {
+ DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return False;
+ }
+ } else {
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
+ DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return False;
+ }
+ }
+
+ DEBUG(10,("set_unix_posix_acl: set acl for file %s\n", fname ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return True;
+}
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 8adc5c2e665..1372ebbf458 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -1177,8 +1177,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
int outsize2;
char inbuf_saved[smb_wct];
char outbuf_saved[smb_wct];
- int wct = CVAL(outbuf,smb_wct);
- int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+ int outsize = smb_len(outbuf) + 4;
/* maybe its not chained */
if (smb_com2 == 0xFF) {
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index 3c4d4319f63..a96f50ad02f 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -471,7 +471,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
len=strcspn(mnttype, ":");
pathname=strstr(mnttype, ":");
- cutstr = (char *) malloc(len+1);
+ cutstr = (char *) SMB_MALLOC(len+1);
if (!cutstr)
return False;
@@ -1000,7 +1000,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
len=strcspn(mnttype, ":");
pathname=strstr(mnttype, ":");
- cutstr = (char *) malloc(len+1);
+ cutstr = (char *) SMB_MALLOC(len+1);
if (!cutstr)
return False;
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 6135c36580b..26a0c9e7a9b 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -27,12 +27,13 @@
#include "includes.h"
/* look in server.c for some explanation of these variables */
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int max_send;
extern int max_recv;
extern char magic_char;
extern int global_oplock_break;
unsigned int smb_echo_count = 0;
+extern uint32 global_client_caps;
extern BOOL global_encrypted_passwords_negotiated;
@@ -258,8 +259,6 @@ int reply_special(char *inbuf,char *outbuf)
reload_services(True);
reopen_logs();
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
-
already_got_session = True;
break;
@@ -718,7 +717,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
mode &= ~aDIR;
if (check_name(fname,conn)) {
- ok = (file_set_dosmode(conn,fname,mode,NULL) == 0);
+ ok = (file_set_dosmode(conn,fname,mode,&sbuf,False) == 0);
}
} else {
ok = True;
@@ -1716,7 +1715,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
Fail for readbraw.
****************************************************************************/
-void fail_readraw(void)
+static void fail_readraw(void)
{
pstring errstr;
slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
@@ -1724,12 +1723,46 @@ void fail_readraw(void)
exit_server(errstr);
}
+#if defined(WITH_SENDFILE)
+/****************************************************************************
+ Fake (read/write) sendfile. Returns -1 on read or write fail.
+****************************************************************************/
+
+static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize)
+{
+ ssize_t ret=0;
+
+ /* Paranioa check... */
+ if (nread > bufsize) {
+ fail_readraw();
+ }
+
+ if (nread > 0) {
+ ret = read_file(fsp,buf,startpos,nread);
+ if (ret == -1) {
+ return -1;
+ }
+ }
+
+ /* If we had a short read, fill with zeros. */
+ if (ret < nread) {
+ memset(buf, '\0', nread - ret);
+ }
+
+ if (write_data(smbd_server_fd(),buf,nread) != nread) {
+ return -1;
+ }
+
+ return (ssize_t)nread;
+}
+#endif
+
/****************************************************************************
Use sendfile in readbraw.
****************************************************************************/
void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
- ssize_t mincount, char *outbuf)
+ ssize_t mincount, char *outbuf, int out_buffsize)
{
ssize_t ret=0;
@@ -1750,13 +1783,27 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
header.free = NULL;
if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_readbraw;
+ }
+
/*
- * Special hack for broken Linux with no 64 bit clean sendfile. If we
- * return ENOSYS then pretend we just got a normal read.
+ * Special hack for broken Linux with no working sendfile. If we
+ * return EINTR we sent the header but not the rest of the data.
+ * Fake this up by doing read/write calls.
*/
- if (errno == ENOSYS) {
+ if (errno == EINTR) {
+ /* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
- goto normal_read;
+ DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
+
+ if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
+ DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readbraw fake_sendfile failed");
+ }
+ return;
}
DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
@@ -1766,7 +1813,8 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
}
- normal_read:
+ normal_readbraw:
+
#endif
if (nread > 0) {
@@ -1789,7 +1837,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
Reply to a readbraw (core+ protocol).
****************************************************************************/
-int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
+int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
{
extern struct current_user current_user;
ssize_t maxcount,mincount;
@@ -1878,7 +1926,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
- if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
SMB_OFF_T size = fsp->size;
SMB_OFF_T sizeneeded = startpos + maxcount;
@@ -1904,7 +1952,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
(int)maxcount, (int)mincount, (int)nread ) );
- send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
+ send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
DEBUG(5,("readbraw finished\n"));
END_PROFILE(SMBreadbraw);
@@ -2038,7 +2086,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
data = smb_buf(outbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBread);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2068,9 +2116,10 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
Reply to a read and X - possibly using sendfile.
****************************************************************************/
-int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
+int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
{
+ int outsize = 0;
ssize_t nread = -1;
char *data = smb_buf(outbuf);
@@ -2107,6 +2156,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,smb_maxcnt);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1));
SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
SCVAL(outbuf,smb_vwv0,0xFF);
set_message(outbuf,12,smb_maxcnt,False);
@@ -2114,14 +2164,33 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
header.length = data - outbuf;
header.free = NULL;
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_read;
+ }
+
/*
- * Special hack for broken Linux with no 64 bit clean sendfile. If we
- * return ENOSYS then pretend we just got a normal read.
+ * Special hack for broken Linux with no working sendfile. If we
+ * return EINTR we sent the header but not the rest of the data.
+ * Fake this up by doing read/write calls.
*/
- if (errno == ENOSYS) {
+
+ if (errno == EINTR) {
+ /* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
- goto normal_read;
+ DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
+
+ if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
+ len_outbuf - (data-outbuf))) == -1) {
+ DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readX: fake_sendfile failed");
+ }
+ DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
+ fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning -1 here means successful sendfile. */
+ return -1;
}
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
@@ -2131,6 +2200,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning -1 here means successful sendfile. */
return -1;
}
@@ -2145,15 +2215,18 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
+ outsize = set_message(outbuf,12,nread,False);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
SSVAL(smb_buf(outbuf),-2,nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- return nread;
+ /* Returning the number of bytes we want to send back - including header. */
+ return outsize;
}
/****************************************************************************
@@ -2183,6 +2256,18 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
set_message(outbuf,12,0,True);
+ if (global_client_caps & CAP_LARGE_READX) {
+ if (SVAL(inbuf,smb_vwv7) == 1) {
+ smb_maxcnt |= (1<<16);
+ }
+ if (smb_maxcnt > BUFFER_SIZE) {
+ DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
+ (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE));
+ END_PROFILE(SMBreadX);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
if(CVAL(inbuf,smb_wct) == 12) {
#ifdef LARGE_SMB_OFF_T
/*
@@ -2207,12 +2292,12 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
- if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadX);
return ERROR_DOS(ERRDOS,ERRlock);
}
- nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
+ nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
if (nread != -1)
nread = chain_reply(inbuf,outbuf,length,bufsize);
@@ -2263,7 +2348,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
SCVAL(inbuf,smb_com,SMBwritec);
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwritebraw);
return(ERROR_DOS(ERRDOS,ERRlock));
}
@@ -2378,8 +2463,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
- WRITE_LOCK,False)) {
+ if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteunlock);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2447,7 +2531,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwrite);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2558,7 +2642,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteX);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2829,7 +2913,7 @@ int reply_writeclose(connection_struct *conn,
mtime = make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteclose);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -3223,7 +3307,7 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
}
if (check_name(directory, conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
if (ret == -1) {
if(errno == ENOENT) {
@@ -4518,7 +4602,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
/* we don't support these - and CANCEL_LOCK makes w2k
and XP reboot so I don't really want to be
compatible! (tridge) */
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
}
if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
@@ -4733,7 +4817,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadBmpx);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -4859,7 +4943,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
not an SMBwritebmpx - set this up now so we don't forget */
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
END_PROFILE(SMBwriteBmpx);
return(ERROR_DOS(ERRDOS,ERRlock));
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index bf1da1a0c87..724a49321a2 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -186,6 +186,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
+ int maxfd = 0;
int i;
char *ports;
@@ -241,7 +242,9 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
unsigned port = atoi(tok);
- if (port == 0) continue;
+ if (port == 0) {
+ continue;
+ }
s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
if(s == -1)
return False;
@@ -259,6 +262,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
return False;
}
FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
num_sockets++;
if (num_sockets >= FD_SETSIZE) {
@@ -301,6 +305,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
fd_listenset[num_sockets] = s;
FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
num_sockets++;
@@ -335,7 +340,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
- num = sys_select(FD_SETSIZE,&lfds,NULL,NULL,NULL);
+ num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
if (num == -1 && errno == EINTR) {
if (got_sig_term) {
@@ -482,9 +487,10 @@ BOOL reload_services(BOOL test)
return(True);
lp_killunused(conn_snum_used);
-
+
ret = lp_load(dyn_CONFIGFILE, False, False, True);
+ remove_stale_printers();
load_printers();
/* perhaps the config filename is now set */
@@ -780,6 +786,9 @@ void build_options(BOOL screen);
init_structs();
+ if (!init_guest_info())
+ return -1;
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
DEBUG(0,("ERROR: failed to setup profiling\n"));
@@ -855,7 +864,7 @@ void build_options(BOOL screen);
smbd is launched via inetd and we fork a copy of
ourselves here */
- if ( is_daemon )
+ if ( is_daemon && !interactive )
start_background_queue();
if (!open_sockets_smbd(is_daemon, interactive, ports))
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 4d111e0ea35..3dcd803a7ce 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -152,10 +152,9 @@ int find_service(fstring service)
int iPrinterService;
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
- char *pszTemp;
+ const char *pszTemp = lp_printcapname();
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- pszTemp = lp_printcapname();
if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
DEBUG(3,("%s is a valid printer name\n", service));
DEBUG(3,("adding %s as a printer service\n", service));
@@ -877,12 +876,21 @@ void remove_stale_printers( void )
iNumServices = lp_numservices();
printersServiceNum = lp_servicenumber( PRINTERS_NAME);
for( snum = 0; snum < iNumServices; snum++) {
+
/* Never remove PRINTERS_NAME */
+
if ( snum == printersServiceNum)
continue;
pname = lp_printername( snum);
- /* Is snum a print service and still in the printing subsystem? */
- if ( lp_print_ok( snum) && !pcap_printername_ok( pname, NULL)) {
+
+ /* Is snum an autoloaded print service and still
+ in the printing subsystem? */
+
+ if ( lp_snum_ok(snum)
+ && lp_print_ok(snum)
+ && lp_autoloaded(snum)
+ && !pcap_printername_ok( pname, NULL))
+ {
DEBUG( 3, ( "Removing printer: %s\n", pname));
lp_killservice( snum);
}
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index 0122b662ebf..cff7d7371c6 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -633,7 +633,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
static BOOL done_sesssetup = False;
extern BOOL global_encrypted_passwords_negotiated;
extern BOOL global_spnego_negotiated;
- extern int Protocol;
+ extern enum protocol_types Protocol;
extern int max_send;
auth_usersupplied_info *user_info = NULL;
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 720ede9c767..7269ab91579 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -23,7 +23,7 @@
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
@@ -584,7 +584,8 @@ static int send_trans2_replies(char *outbuf,
****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
int16 open_mode;
@@ -962,8 +963,13 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
adate &= ~1;
}
- if(mode & aDIR)
+ if(mode & aDIR) {
+ /* This is necessary, as otherwise the
+ * desktop.ini file in this folder is
+ * ignored */
+ mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
file_size = 0;
+ }
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
@@ -1317,21 +1323,22 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
****************************************************************************/
static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
- uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
int dirtype = SVAL(params,0);
int maxentries = SVAL(params,2);
- BOOL close_after_first = BITSETW(params+4,0);
- BOOL close_if_end = BITSETW(params+4,1);
- BOOL requires_resume_key = BITSETW(params+4,2);
+ uint16 findfirst_flags = SVAL(params,4);
+ BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
+ BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+ BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
int info_level = SVAL(params,6);
pstring directory;
pstring mask;
@@ -1541,24 +1548,25 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
****************************************************************************/
static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
int dptr_num = SVAL(params,0);
int maxentries = SVAL(params,2);
uint16 info_level = SVAL(params,4);
uint32 resume_key = IVAL(params,6);
- BOOL close_after_request = BITSETW(params+10,0);
- BOOL close_if_end = BITSETW(params+10,1);
- BOOL requires_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
+ uint16 findnext_flags = SVAL(params,10);
+ BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
+ BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+ BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
+ BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
pstring resume_name;
pstring mask;
pstring directory;
@@ -1807,11 +1815,10 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
-static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *pdata = *ppdata;
char *params = *pparams;
uint16 info_level = SVAL(params,0);
@@ -2084,7 +2091,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
data_len = 12;
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
- SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
+ SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
break;
case SMB_MAC_QUERY_FS_INFO:
@@ -2115,9 +2122,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
-static int call_trans2setfsinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *pdata = *ppdata;
char *params = *pparams;
@@ -2225,8 +2232,8 @@ static int call_trans2setfsinfo(connection_struct *conn,
#endif /* HAVE_SYS_QUOTAS */
/****************************************************************************
- * Utility function to set bad path error.
- ****************************************************************************/
+ Utility function to set bad path error.
+****************************************************************************/
int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
{
@@ -2244,16 +2251,129 @@ int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint
}
/****************************************************************************
+ Utility function to count the number of entries in a POSIX acl.
+****************************************************************************/
+
+static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
+{
+ unsigned int ace_count = 0;
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+
+ while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY) {
+ entry_id = SMB_ACL_NEXT_ENTRY;
+ }
+ ace_count++;
+ }
+ return ace_count;
+}
+
+/****************************************************************************
+ Utility function to marshall a POSIX acl into wire format.
+****************************************************************************/
+
+static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
+{
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+
+ while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+ unsigned char perms = 0;
+ unsigned int own_grp;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY) {
+ entry_id = SMB_ACL_NEXT_ENTRY;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
+ return False;
+ }
+
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
+
+ SCVAL(pdata,1,perms);
+
+ switch (tagtype) {
+ case SMB_ACL_USER_OBJ:
+ SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
+ own_grp = (unsigned int)pst->st_uid;
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ case SMB_ACL_USER:
+ {
+ uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ if (!puid) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
+ }
+ own_grp = (unsigned int)*puid;
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
+ SCVAL(pdata,0,SMB_POSIX_ACL_USER);
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ }
+ case SMB_ACL_GROUP_OBJ:
+ SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
+ own_grp = (unsigned int)pst->st_gid;
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ case SMB_ACL_GROUP:
+ {
+ gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ if (!pgid) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
+ }
+ own_grp = (unsigned int)*pgid;
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
+ SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ }
+ case SMB_ACL_MASK:
+ SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
+ SIVAL(pdata,2,0xFFFFFFFF);
+ SIVAL(pdata,6,0xFFFFFFFF);
+ break;
+ case SMB_ACL_OTHER:
+ SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
+ SIVAL(pdata,2,0xFFFFFFFF);
+ SIVAL(pdata,6,0xFFFFFFFF);
+ break;
+ default:
+ DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
+ return False;
+ }
+ pdata += SMB_POSIX_ACL_ENTRY_SIZE;
+ }
+
+ return True;
+}
+
+/****************************************************************************
Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
file name or file id).
****************************************************************************/
-static int call_trans2qfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
uint16 tran_call = SVAL(inbuf, smb_setup0);
@@ -2392,8 +2512,12 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
fullpathname = fname;
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(fsp,&sbuf);
- if (mode & aDIR)
+ if (mode & aDIR) {
+ /* This is necessary, as otherwise the desktop.ini file in
+ * this folder is ignored */
+ mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
file_size = 0;
+ }
params = SMB_REALLOC(*pparams,2);
if (params == NULL)
@@ -2416,6 +2540,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ if (fsp && fsp->pending_modtime) {
+ /* the pending modtime overrides the current modtime */
+ sbuf.st_mtime = fsp->pending_modtime;
+ }
+
if (lp_dos_filetime_resolution(SNUM(conn))) {
c_time &= ~1;
sbuf.st_atime &= ~1;
@@ -2800,6 +2929,83 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
}
+ case SMB_QUERY_POSIX_ACL:
+ {
+ SMB_ACL_T file_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
+ uint16 num_file_acls = 0;
+ uint16 num_def_acls = 0;
+
+ if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
+ file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
+ } else {
+ file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
+ }
+
+ if (file_acl == NULL && no_acl_syscall_error(errno)) {
+ DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
+ fname ));
+ return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
+ }
+
+ if (S_ISDIR(sbuf.st_mode)) {
+ if (fsp && fsp->is_directory) {
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ } else {
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
+ }
+ def_acl = free_empty_sys_acl(conn, def_acl);
+ }
+
+ num_file_acls = count_acl_entries(conn, file_acl);
+ num_def_acls = count_acl_entries(conn, def_acl);
+
+ if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
+ DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
+ data_size,
+ (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
+ SMB_POSIX_ACL_HEADER_SIZE) ));
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
+ }
+
+ SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
+ SSVAL(pdata,2,num_file_acls);
+ SSVAL(pdata,4,num_def_acls);
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ }
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ }
+
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
+ break;
+ }
+
default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
@@ -2981,9 +3187,9 @@ NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newnam
Reply to a TRANS2_SETFILEINFO (set file info by fileid).
****************************************************************************/
-static int call_trans2setfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
char *pdata = *ppdata;
@@ -3103,7 +3309,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
SSVAL(params,0,0);
- if (fsp) {
+ if (fsp && fsp->pending_modtime) {
/* the pending modtime overrides the current modtime */
sbuf.st_mtime = fsp->pending_modtime;
}
@@ -3607,6 +3813,57 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
}
+
+ case SMB_SET_POSIX_ACL:
+ {
+ uint16 posix_acl_version;
+ uint16 num_file_acls;
+ uint16 num_def_acls;
+ BOOL valid_file_acls = True;
+ BOOL valid_def_acls = True;
+
+ if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+ posix_acl_version = SVAL(pdata,0);
+ num_file_acls = SVAL(pdata,2);
+ num_def_acls = SVAL(pdata,4);
+
+ if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_file_acls = False;
+ num_file_acls = 0;
+ }
+
+ if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_def_acls = False;
+ num_def_acls = 0;
+ }
+
+ if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+
+ if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+
+ if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+
default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
@@ -3652,10 +3909,12 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if(fsp != NULL) {
/*
* This was a setfileinfo on an open file.
- * NT does this a lot. It's actually pointless
- * setting the time here, as it will be overwritten
- * on the next write, so we save the request
- * away and will set it on file close. JRA.
+ * NT does this a lot. We also need to
+ * set the time here, as it can be read by
+ * FindFirst/FindNext and with the patch for bug #2045
+ * in smbd/fileio.c it ensures that this timestamp is
+ * kept sticky even after a write. We save the request
+ * away and will set it on file close and after a write. JRA.
*/
if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
@@ -3663,12 +3922,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
fsp->pending_modtime = tvs.modtime;
}
- } else {
-
DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
- if(file_utime(conn, fname, &tvs)!=0)
+ if(file_utime(conn, fname, &tvs)!=0) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
}
}
@@ -3677,7 +3935,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
- if(file_set_dosmode(conn, fname, dosmode, NULL)) {
+ if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -3733,9 +3991,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/
-static int call_trans2mkdir(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
pstring directory;
@@ -3762,7 +4020,7 @@ static int call_trans2mkdir(connection_struct *conn,
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
if (check_name(directory,conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
if(ret < 0) {
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
@@ -3787,9 +4045,9 @@ static int call_trans2mkdir(connection_struct *conn,
We don't actually do this - we just send a null response.
****************************************************************************/
-static int call_trans2findnotifyfirst(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
static uint16 fnf_handle = 257;
char *params = *pparams;
@@ -3834,9 +4092,9 @@ static int call_trans2findnotifyfirst(connection_struct *conn,
changes). Currently this does nothing.
****************************************************************************/
-static int call_trans2findnotifynext(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
@@ -3860,9 +4118,9 @@ static int call_trans2findnotifynext(connection_struct *conn,
Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
pstring pathname;
@@ -3896,9 +4154,9 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
Reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/
-static int call_trans2ioctl(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
@@ -4002,9 +4260,9 @@ int reply_trans2(connection_struct *conn,
int outsize = 0;
unsigned int total_params = SVAL(inbuf, smb_tpscnt);
unsigned int total_data =SVAL(inbuf, smb_tdscnt);
+ unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
#if 0
unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
- unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
BOOL close_tid = BITSETW(inbuf+smb_flags,0);
BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
@@ -4159,7 +4417,7 @@ int reply_trans2(connection_struct *conn,
goto bad_param;
if (num_params) {
- if (param_disp + num_params >= total_params)
+ if (param_disp + num_params > total_params)
goto bad_param;
if ((param_disp + num_params < param_disp) ||
(param_disp + num_params < num_params))
@@ -4175,7 +4433,7 @@ int reply_trans2(connection_struct *conn,
memcpy( &params[param_disp], smb_base(inbuf) + param_off, num_params);
}
if (num_data) {
- if (data_disp + num_data >= total_data)
+ if (data_disp + num_data > total_data)
goto bad_param;
if ((data_disp + num_data < data_disp) ||
(data_disp + num_data < num_data))
@@ -4202,28 +4460,28 @@ int reply_trans2(connection_struct *conn,
case TRANSACT2_OPEN:
START_PROFILE_NESTED(Trans2_open);
outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_open);
break;
case TRANSACT2_FINDFIRST:
START_PROFILE_NESTED(Trans2_findfirst);
outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findfirst);
break;
case TRANSACT2_FINDNEXT:
START_PROFILE_NESTED(Trans2_findnext);
outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnext);
break;
case TRANSACT2_QFSINFO:
START_PROFILE_NESTED(Trans2_qfsinfo);
outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
@@ -4231,7 +4489,7 @@ int reply_trans2(connection_struct *conn,
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
#endif
@@ -4239,47 +4497,47 @@ int reply_trans2(connection_struct *conn,
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);
outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_qpathinfo);
break;
case TRANSACT2_SETPATHINFO:
case TRANSACT2_SETFILEINFO:
START_PROFILE_NESTED(Trans2_setpathinfo);
outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_setpathinfo);
break;
case TRANSACT2_FINDNOTIFYFIRST:
START_PROFILE_NESTED(Trans2_findnotifyfirst);
outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnotifyfirst);
break;
case TRANSACT2_FINDNOTIFYNEXT:
START_PROFILE_NESTED(Trans2_findnotifynext);
outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnotifynext);
break;
case TRANSACT2_MKDIR:
START_PROFILE_NESTED(Trans2_mkdir);
outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_mkdir);
break;
case TRANSACT2_GET_DFS_REFERRAL:
START_PROFILE_NESTED(Trans2_get_dfs_referral);
outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_get_dfs_referral);
break;
case TRANSACT2_IOCTL:
START_PROFILE_NESTED(Trans2_ioctl);
outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_ioctl);
break;
default:
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 5393dfc7556..abc17a37a23 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -93,21 +93,44 @@ DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const c
DIR *result;
START_PROFILE(syscall_opendir);
- result = opendir(fname);
+ result = sys_opendir(fname);
END_PROFILE(syscall_opendir);
return result;
}
-struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
START_PROFILE(syscall_readdir);
- result = readdir(dirp);
+ result = sys_readdir(dirp);
END_PROFILE(syscall_readdir);
return result;
}
+void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ START_PROFILE(syscall_seekdir);
+ sys_seekdir(dirp, offset);
+ END_PROFILE(syscall_seekdir);
+}
+
+long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ long result;
+ START_PROFILE(syscall_telldir);
+ result = sys_telldir(dirp);
+ END_PROFILE(syscall_telldir);
+ return result;
+}
+
+void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ START_PROFILE(syscall_rewinddir);
+ sys_rewinddir(dirp);
+ END_PROFILE(syscall_rewinddir);
+}
+
int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
int result;
@@ -152,7 +175,7 @@ int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *di
int result;
START_PROFILE(syscall_closedir);
- result = closedir(dirp);
+ result = sys_closedir(dirp);
END_PROFILE(syscall_closedir);
return result;
}
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 68a6dca31dd..0102739fe39 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -62,6 +62,9 @@ static struct vfs_ops default_vfs = {
vfswrap_opendir,
vfswrap_readdir,
+ vfswrap_seekdir,
+ vfswrap_telldir,
+ vfswrap_rewinddir,
vfswrap_mkdir,
vfswrap_rmdir,
vfswrap_closedir,
@@ -611,13 +614,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
char *vfs_readdirname(connection_struct *conn, void *p)
{
- struct dirent *ptr= NULL;
+ SMB_STRUCT_DIRENT *ptr= NULL;
char *dname;
if (!p)
return(NULL);
- ptr = (struct dirent *)SMB_VFS_READDIR(conn,p);
+ ptr = SMB_VFS_READDIR(conn,p);
if (!ptr)
return(NULL);
@@ -894,7 +897,8 @@ BOOL reduce_name(connection_struct *conn, const pstring fname)
}
default:
DEBUG(1,("reduce_name: couldn't get realpath for %s\n", fname));
- errno = saved_errno;
+ /* Don't restore the saved errno. We need to return the error that
+ realpath caused here as it was not one of the cases we handle. JRA. */
return False;
}
}
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 0ddacdf8ba5..bf60c2bc68c 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -546,7 +546,7 @@ struct smbw_server *smbw_server(char *server, char *share)
DEBUG(4,(" tconx ok\n"));
- srv = (struct smbw_server *)malloc(sizeof(*srv));
+ srv = SMB_MALLOC_P(struct smbw_server);
if (!srv) {
errno = ENOMEM;
goto failed;
@@ -558,25 +558,25 @@ struct smbw_server *smbw_server(char *server, char *share)
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
- srv->server_name = strdup(server);
+ srv->server_name = SMB_STRDUP(server);
if (!srv->server_name) {
errno = ENOMEM;
goto failed;
}
- srv->share_name = strdup(share);
+ srv->share_name = SMB_STRDUP(share);
if (!srv->share_name) {
errno = ENOMEM;
goto failed;
}
- srv->workgroup = strdup(workgroup);
+ srv->workgroup = SMB_STRDUP(workgroup);
if (!srv->workgroup) {
errno = ENOMEM;
goto failed;
}
- srv->username = strdup(username);
+ srv->username = SMB_STRDUP(username);
if (!srv->username) {
errno = ENOMEM;
goto failed;
@@ -664,7 +664,7 @@ int smbw_open(const char *fname, int flags, mode_t mode)
return fd;
}
- file = (struct smbw_file *)malloc(sizeof(*file));
+ file = SMB_MALLOC_P(struct smbw_file);
if (!file) {
errno = ENOMEM;
goto failed;
@@ -672,7 +672,7 @@ int smbw_open(const char *fname, int flags, mode_t mode)
ZERO_STRUCTP(file);
- file->f = (struct smbw_filedes *)malloc(sizeof(*(file->f)));
+ file->f = SMB_MALLOC_P(struct smbw_filedes);
if (!file->f) {
errno = ENOMEM;
goto failed;
@@ -681,7 +681,7 @@ int smbw_open(const char *fname, int flags, mode_t mode)
ZERO_STRUCTP(file->f);
file->f->cli_fd = fd;
- file->f->fname = strdup(path);
+ file->f->fname = SMB_STRDUP(path);
if (!file->f->fname) {
errno = ENOMEM;
goto failed;
@@ -1288,7 +1288,7 @@ int smbw_dup(int fd)
goto failed;
}
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
+ file2 = SMB_MALLOC_P(struct smbw_file);
if (!file2) {
close(fd2);
errno = ENOMEM;
@@ -1340,7 +1340,7 @@ int smbw_dup2(int fd, int fd2)
goto failed;
}
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
+ file2 = SMB_MALLOC_P(struct smbw_file);
if (!file2) {
close(fd2);
errno = ENOMEM;
diff --git a/source/smbwrapper/smbw_cache.c b/source/smbwrapper/smbw_cache.c
index fcb0eda8050..cfa8ab1f76c 100644
--- a/source/smbwrapper/smbw_cache.c
+++ b/source/smbwrapper/smbw_cache.c
@@ -65,14 +65,14 @@ static void add_cached_names(const char *name, uint32 stype,
struct name_list **name_list = (struct name_list **)state;
struct name_list *new_name;
- new_name = (struct name_list *)malloc(sizeof(struct name_list));
+ new_name = SMB_MALLOC_P(struct name_list);
if (!new_name) return;
ZERO_STRUCTP(new_name);
- new_name->name = strdup(name);
+ new_name->name = SMB_STRDUP(name);
new_name->stype = stype;
- new_name->comment = strdup(comment);
+ new_name->comment = SMB_STRDUP(comment);
DLIST_ADD(*name_list, new_name);
}
@@ -117,8 +117,7 @@ BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
/* No names cached for this workgroup */
if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
+ new_names = SMB_MALLOC_P(struct cached_names);
ZERO_STRUCTP(new_names);
DLIST_ADD(cached_names, new_names);
@@ -139,7 +138,7 @@ BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
new_names->cache_timeout = now;
new_names->result = result;
- new_names->key = strdup(key);
+ new_names->key = SMB_STRDUP(key);
names = new_names;
}
@@ -173,8 +172,7 @@ int smbw_RNetShareEnum(struct cli_state *cli,
/* No names cached for this server */
if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
+ new_names = SMB_MALLOC_P(struct cached_names);
ZERO_STRUCTP(new_names);
DLIST_ADD(cached_names, new_names);
@@ -193,7 +191,7 @@ int smbw_RNetShareEnum(struct cli_state *cli,
&new_names->name_list);
new_names->cache_timeout = now;
- new_names->key = strdup(key);
+ new_names->key = SMB_STRDUP(key);
names = new_names;
}
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
index 43661f1d6cb..04c40db72e4 100644
--- a/source/torture/cmd_vfs.c
+++ b/source/torture/cmd_vfs.c
@@ -285,7 +285,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
vfs->files[fd] = (struct files_struct *)malloc(sizeof(struct files_struct));
- vfs->files[fd]->fsp_name = strdup(argv[1]);
+ vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]);
vfs->files[fd]->fd = fd;
vfs->files[fd]->conn = vfs->conn;
printf("open: fd=%d\n", fd);
diff --git a/source/torture/torture.c b/source/torture/torture.c
index 6c3860e233e..72a391dbdbb 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -70,7 +70,7 @@ void *shm_setup(int size)
int shmid;
void *ret;
- shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+ shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
if (shmid == -1) {
printf("can't get shared memory\n");
exit(1);
@@ -870,7 +870,7 @@ static BOOL run_locktest1(int dummy)
lock_timeout = (1 + (random() % 20));
printf("Testing lock timeout with timeout=%u\n", lock_timeout);
t1 = time(NULL);
- if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 500, WRITE_LOCK)) {
+ if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
printf("lock3 succeeded! This is a locking bug\n");
return False;
} else {
diff --git a/source/utils/editreg.c b/source/utils/editreg.c
index a0cfa2bb07d..9123de18c87 100644
--- a/source/utils/editreg.c
+++ b/source/utils/editreg.c
@@ -302,6 +302,7 @@ Hope this helps.... (Although it was "fun" for me to uncover this things,
*************************************************************************/
+#ifdef STANDALONE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -315,6 +316,10 @@ Hope this helps.... (Although it was "fun" for me to uncover this things,
#define False 0
#define True 1
+#else /* STANDALAONE */
+#include "includes.h"
+#endif /* STANDALONE */
+
#define REG_KEY_LIST_SIZE 10
/*
@@ -743,7 +748,7 @@ int nt_key_iterator(REGF *regf, REG_KEY *key_tree, int bf, const char *path,
return 0;
}
- new_path = (char *)malloc(path_len + 1 + strlen(key_tree->name) + 1);
+ new_path = (char *)SMB_MALLOC(path_len + 1 + strlen(key_tree->name) + 1);
if (!new_path) return 0; /* Errors? */
new_path[0] = '\0';
strcat(new_path, path);
@@ -812,7 +817,7 @@ REG_KEY *nt_find_key_by_name(REG_KEY *tree, char *key)
if (!tree || !key || !*key) return NULL;
- lname = strdup(key);
+ lname = SMB_STRDUP(key);
if (!lname) return NULL;
/*
@@ -1041,7 +1046,7 @@ void *str_to_val(int type, char *val, int *len)
return (void *)val;
case REG_TYPE_DWORD:
- dwordp = (unsigned int *)malloc(sizeof(unsigned int));
+ dwordp = SMB_MALLOC_P(unsigned int);
if (!dwordp) return NULL;
/* Allow for ddddd and 0xhhhhh and 0ooooo */
if (strncmp(val, "0x", 2) == 0 || strncmp(val, "0X", 2) == 0) {
@@ -1096,11 +1101,11 @@ VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
* If we get here, the name was not found, so insert it
*/
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
+ tmp = SMB_MALLOC_P(VAL_KEY);
if (!tmp) goto error;
memset(tmp, 0, sizeof(VAL_KEY));
- tmp->name = strdup(name);
+ tmp->name = SMB_STRDUP(name);
tmp->has_name = True;
if (!tmp->name) goto error;
tmp->data_type = type;
@@ -1113,7 +1118,7 @@ VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
* Allocate some more space
*/
- if ((key->values = (VAL_LIST *)realloc(key->values, sizeof(VAL_LIST) +
+ if ((key->values = (VAL_LIST *)SMB_REALLOC_ARRAY(key->values, sizeof(VAL_LIST) +
key->values->val_count - 1 +
REG_KEY_LIST_SIZE))) {
key->values->max_vals += REG_KEY_LIST_SIZE;
@@ -1178,7 +1183,7 @@ int sid_string_to_sid(sid_t **sid, const char *sid_str)
int i = 0, auth;
const char *lstr;
- *sid = (sid_t *)malloc(sizeof(sid_t));
+ *sid = SMB_MALLOC_P(sid_t);
if (!*sid) return 0;
memset(*sid, 0, sizeof(sid_t));
@@ -1221,7 +1226,7 @@ ACE *nt_create_ace(int type, int flags, unsigned int perms, const char *sid)
{
ACE *ace;
- ace = (ACE *)malloc(sizeof(ACE));
+ ace = SMB_MALLOC_P(ACE);
if (!ace) goto error;
ace->type = type;
ace->flags = flags;
@@ -1243,7 +1248,7 @@ ACL *nt_create_default_acl(REGF *regf)
{
ACL *acl;
- acl = (ACL *)malloc(sizeof(ACL) + 7*sizeof(ACE *));
+ acl = (ACL *)SMB_MALLOC(sizeof(ACL) + 7*sizeof(ACE *));
if (!acl) goto error;
acl->rev = 2;
@@ -1282,7 +1287,7 @@ SEC_DESC *nt_create_def_sec_desc(REGF *regf)
{
SEC_DESC *tmp;
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
+ tmp = SMB_MALLOC_P(SEC_DESC);
if (!tmp) return NULL;
tmp->rev = 1;
@@ -1321,7 +1326,7 @@ KEY_SEC_DESC *nt_create_init_sec(REGF *regf)
{
KEY_SEC_DESC *tsec = NULL;
- tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tsec = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tsec) return NULL;
tsec->ref_cnt = 1;
@@ -1349,13 +1354,13 @@ REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create)
list = key->sub_keys;
if (!list) { /* Create an empty list */
- list = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *));
+ list = (KEY_LIST *)SMB_MALLOC(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *));
list->key_count = 0;
list->max_keys = REG_KEY_LIST_SIZE;
}
- lname = strdup(name);
+ lname = SMB_STRDUP(name);
if (!lname) return NULL;
c1 = lname;
@@ -1382,7 +1387,7 @@ REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create)
list->key_count++;
}
else { /* Create more space in the list ... */
- if (!(list = (KEY_LIST *)realloc(list, sizeof(KEY_LIST) +
+ if (!(list = (KEY_LIST *)SMB_REALLOC(list, sizeof(KEY_LIST) +
(list->max_keys + REG_KEY_LIST_SIZE - 1)
* sizeof(REG_KEY *))))
goto error;
@@ -1400,11 +1405,11 @@ REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create)
* We want to create the key, and then do the rest
*/
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
memset(tmp, 0, sizeof(REG_KEY));
- tmp->name = strdup(c1);
+ tmp->name = SMB_STRDUP(c1);
if (!tmp->name) goto error;
tmp->owner = key;
tmp->type = REG_SUB_KEY;
@@ -1447,7 +1452,7 @@ REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create)
*/
if (!regf || !name || !*name) return NULL;
- lname = strdup(name);
+ lname = SMB_STRDUP(name);
if (!lname) return NULL;
c1 = lname;
@@ -1464,10 +1469,10 @@ REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create)
if (!regf->root) {
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
if (!tmp) goto error;
memset(tmp, 0, sizeof(REG_KEY));
- tmp->name = strdup(c1);
+ tmp->name = SMB_STRDUP(c1);
if (!tmp->name) goto error;
tmp->security = nt_create_init_sec(regf);
if (!tmp->security) goto error;
@@ -1638,13 +1643,13 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent);
static
int nt_set_regf_input_file(REGF *regf, char *filename)
{
- return ((regf->regfile_name = strdup(filename)) != NULL);
+ return ((regf->regfile_name = SMB_STRDUP(filename)) != NULL);
}
static
int nt_set_regf_output_file(REGF *regf, char *filename)
{
- return ((regf->outfile_name = strdup(filename)) != NULL);
+ return ((regf->outfile_name = SMB_STRDUP(filename)) != NULL);
}
/* Create a regf structure and init it */
@@ -1652,7 +1657,7 @@ int nt_set_regf_output_file(REGF *regf, char *filename)
static
REGF *nt_create_regf(void)
{
- REGF *tmp = (REGF *)malloc(sizeof(REGF));
+ REGF *tmp = SMB_MALLOC_P(REGF);
if (!tmp) return tmp;
memset(tmp, 0, sizeof(REGF));
tmp->owner_sid_str = def_owner_sid_str;
@@ -1746,7 +1751,7 @@ static
SK_MAP *alloc_sk_map_entry(REGF *regf, KEY_SEC_DESC *tmp, int sk_off)
{
if (!regf->sk_map) { /* Allocate a block of 10 */
- regf->sk_map = (SK_MAP *)malloc(sizeof(SK_MAP) * 10);
+ regf->sk_map = SMB_MALLOC_ARRAY(SK_MAP, 10);
if (!regf->sk_map) {
free(tmp);
return NULL;
@@ -1759,7 +1764,7 @@ SK_MAP *alloc_sk_map_entry(REGF *regf, KEY_SEC_DESC *tmp, int sk_off)
else { /* Simply allocate a new slot, unless we have to expand the list */
int ndx = regf->sk_count;
if (regf->sk_count >= regf->sk_map_size) {
- regf->sk_map = (SK_MAP *)realloc(regf->sk_map,
+ regf->sk_map = (SK_MAP *)SMB_REALLOC(regf->sk_map,
(regf->sk_map_size + 10)*sizeof(SK_MAP));
if (!regf->sk_map) {
free(tmp);
@@ -1811,7 +1816,7 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
return tmp;
}
else { /* Allocate a new one */
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tmp = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tmp) {
return NULL;
}
@@ -1831,7 +1836,7 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
static
sid_t *dup_sid(sid_t *sid)
{
- sid_t *tmp = (sid_t *)malloc(sizeof(sid_t));
+ sid_t *tmp = SMB_MALLOC_P(sid_t);
int i;
if (!tmp) return NULL;
@@ -1854,7 +1859,7 @@ ACE *dup_ace(REG_ACE *ace)
{
ACE *tmp = NULL;
- tmp = (ACE *)malloc(sizeof(ACE));
+ tmp = SMB_MALLOC_P(ACE);
if (!tmp) return NULL;
@@ -1877,7 +1882,7 @@ ACL *dup_acl(REG_ACL *acl)
num_aces = IVAL(&acl->num_aces);
- tmp = (ACL *)malloc(sizeof(ACL) + (num_aces - 1)*sizeof(ACE *));
+ tmp = (ACL *)SMB_MALLOC(sizeof(ACL) + (num_aces - 1)*sizeof(ACE *));
if (!tmp) return NULL;
tmp->num_aces = num_aces;
@@ -1900,7 +1905,7 @@ SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc)
{
SEC_DESC *tmp = NULL;
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
+ tmp = SMB_MALLOC_P(SEC_DESC);
if (!tmp) {
return NULL;
@@ -1989,7 +1994,7 @@ KEY_SEC_DESC *process_sk(REGF *regf, SK_HDR *sk_hdr, int sk_off, int size)
*/
if (!tmp) {
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tmp = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tmp) return NULL;
memset(tmp, 0, sizeof(KEY_SEC_DESC));
@@ -2055,7 +2060,7 @@ VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size)
dat_len = IVAL(&vk_hdr->dat_len); /* If top bit, offset contains data */
dat_off = IVAL(&vk_hdr->dat_off);
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
+ tmp = SMB_MALLOC_P(VAL_KEY);
if (!tmp) {
goto error;
}
@@ -2065,7 +2070,7 @@ VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size)
if (flag & 0x01) {
strncpy(val_name, vk_hdr->dat_name, nam_len);
- tmp->name = strdup(val_name);
+ tmp->name = SMB_STRDUP(val_name);
if (!tmp->name) {
goto error;
}
@@ -2079,7 +2084,7 @@ VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size)
if (dat_len) {
- char *dtmp = (char *)malloc(dat_len&0x7FFFFFFF);
+ char *dtmp = (char *)SMB_MALLOC(dat_len&0x7FFFFFFF);
if (!dtmp) {
goto error;
@@ -2138,7 +2143,7 @@ VAL_LIST *process_vl(REGF *regf, VL_TYPE vl, int count, int size)
return NULL;
}
- tmp = (VAL_LIST *)malloc(sizeof(VAL_LIST) + (count - 1) * sizeof(VAL_KEY *));
+ tmp = (VAL_LIST *)SMB_MALLOC(sizeof(VAL_LIST) + (count - 1) * sizeof(VAL_KEY *));
if (!tmp) {
goto error;
}
@@ -2188,7 +2193,7 @@ KEY_LIST *process_lf(REGF *regf, LF_HDR *lf_hdr, int size, REG_KEY *parent)
/* Now, we should allocate a KEY_LIST struct and fill it in ... */
- tmp = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (count - 1) * sizeof(REG_KEY *));
+ tmp = (KEY_LIST *)SMB_MALLOC(sizeof(KEY_LIST) + (count - 1) * sizeof(REG_KEY *));
if (!tmp) {
goto error;
}
@@ -2266,7 +2271,7 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
assert(name_len < sizeof(key_name));
/* Allocate the key struct now */
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
if (!tmp) return tmp;
memset(tmp, 0, sizeof(REG_KEY));
@@ -2277,7 +2282,7 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
if (verbose) fprintf(stdout, "Key name: %s\n", key_name);
- tmp->name = strdup(key_name);
+ tmp->name = SMB_STRDUP(key_name);
if (!tmp->name) {
goto error;
}
@@ -2305,7 +2310,7 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
* XXX: FIXME
*/
- tmp->class_name = strdup(cls_name);
+ tmp->class_name = SMB_STRDUP(cls_name);
if (!tmp->class_name) {
goto error;
}
@@ -2493,10 +2498,10 @@ HBIN_BLK *nt_create_hbin_blk(REGF *regf, int size)
size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1);
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
+ tmp = (HBIN_BLK *)SMB_MALLOC_P(HBIN_BLK);
memset(tmp, 0, sizeof(HBIN_BLK));
- tmp->data = malloc(size);
+ tmp->data = SMB_MALLOC(size);
if (!tmp->data) goto error;
memset(tmp->data, 0, size); /* Make it pristine */
@@ -2983,13 +2988,13 @@ REGF_HDR *nt_get_reg_header(REGF *regf)
{
HBIN_BLK *tmp = NULL;
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
+ tmp = SMB_MALLOC_P(HBIN_BLK);
if (!tmp) return 0;
memset(tmp, 0, sizeof(HBIN_BLK));
tmp->type = REG_OUTBLK_HDR;
tmp->size = REGF_HDR_BLKSIZ;
- tmp->data = malloc(REGF_HDR_BLKSIZ);
+ tmp->data = SMB_MALLOC(REGF_HDR_BLKSIZ);
if (!tmp->data) goto error;
memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */
@@ -3163,7 +3168,7 @@ void print_line(struct cmd_line *cl)
if (!cl) return;
- if ((pl = malloc(cl->line_len + 1)) == NULL) {
+ if ((pl = SMB_MALLOC(cl->line_len + 1)) == NULL) {
fprintf(stderr, "Unable to allocate space to print line: %s\n",
strerror(errno));
exit(1);
@@ -3187,7 +3192,7 @@ void print_line(struct cmd_line *cl)
static
struct cmd_line *get_cmd_line(int fd)
{
- struct cmd_line *cl = (CMD_LINE *)malloc(sizeof(CMD_LINE));
+ struct cmd_line *cl = SMB_MALLOC_P(CMD_LINE);
int i = 0, rc;
unsigned char ch;
@@ -3203,7 +3208,7 @@ struct cmd_line *get_cmd_line(int fd)
* Allocate some space for the line. We extend later if needed.
*/
- if ((cl->line = (char *)malloc(INIT_ALLOC)) == NULL) {
+ if ((cl->line = (char *)SMB_MALLOC(INIT_ALLOC)) == NULL) {
fprintf(stderr, "Unable to allocate initial space for line: %s\n",
strerror(errno));
exit(1);
@@ -3220,7 +3225,7 @@ struct cmd_line *get_cmd_line(int fd)
/*
* Allocate some more memory
*/
- if ((cl->line = realloc(cl->line, cl->len + INIT_ALLOC)) == NULL) {
+ if ((cl->line = SMB_REALLOC(cl->line, cl->len + INIT_ALLOC)) == NULL) {
fprintf(stderr, "Unable to realloc space for line: %s\n",
strerror(errno));
exit(1);
@@ -3260,7 +3265,7 @@ static
char *dup_str(char *s, int len)
{
char *nstr;
- nstr = (char *)malloc(len + 1);
+ nstr = (char *)SMB_MALLOC(len + 1);
if (nstr) {
memcpy(nstr, s, len);
nstr[len] = 0;
@@ -3406,7 +3411,7 @@ char *parse_key(struct cmd_line *cl, int *cmd)
start = 2;
*cmd = CMD_DEL_KEY;
}
- tmp = malloc(cl->line_len - 1 - start + 1);
+ tmp = SMB_MALLOC(cl->line_len - 1 - start + 1);
if (!tmp) return tmp; /* Bail out on no mem ... FIXME */
strncpy(tmp, &cl->line[start], cl->line_len - 1 - start);
tmp[cl->line_len - 1 - start] = 0;
@@ -3545,7 +3550,7 @@ CMD *regedit4_get_cmd(int fd)
struct cmd_line *cl = NULL;
struct val_spec_list *vl = NULL;
- if ((cmd = (struct command_s *)malloc(sizeof(struct command_s))) == NULL) {
+ if ((cmd = SMB_MALLOC_P(struct command_s)) == NULL) {
fprintf(stderr, "Unable to malloc space for command: %s\n",
strerror(errno));
exit(1);
@@ -3593,7 +3598,7 @@ CMD *regedit4_get_cmd(int fd)
* There could be a \ on the end which we need to
* handle at some time
*/
- vl = (struct val_spec_list *)malloc(sizeof(struct val_spec_list));
+ vl = SMB_MALLOC_P(struct val_spec_list);
if (!vl) goto error;
vl->next = NULL;
vl->val = NULL;
@@ -3718,7 +3723,7 @@ CMD_FILE *cmd_file_create(char *file)
return NULL;
}
- tmp = (CMD_FILE *)malloc(sizeof(CMD_FILE));
+ tmp = SMB_MALLOC_P(CMD_FILE);
if (!tmp) {
return NULL;
}
@@ -3727,7 +3732,7 @@ CMD_FILE *cmd_file_create(char *file)
* Let's fill in some of the fields;
*/
- tmp->name = strdup(file);
+ tmp->name = SMB_STRDUP(file);
if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) {
free(tmp);
@@ -3985,7 +3990,7 @@ int main(int argc, char *argv[])
break;
case 'O':
- def_owner_sid_str = strdup(optarg);
+ def_owner_sid_str = SMB_STRDUP(optarg);
regf_opt += 2;
if (!sid_string_to_sid(&lsid, def_owner_sid_str)) {
fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n",
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
index 3431196b1e6..c6391a65feb 100644
--- a/source/utils/net_groupmap.c
+++ b/source/utils/net_groupmap.c
@@ -113,6 +113,9 @@ static int net_groupmap_list(int argc, const char **argv)
int i;
fstring ntgroup = "";
fstring sid_string = "";
+
+ if (opt_verbose || opt_long_list_entries)
+ long_list = True;
/* get the options */
for ( i=0; i<argc; i++ ) {
@@ -689,7 +692,7 @@ static int net_groupmap_memberships(int argc, const char **argv)
return -1;
}
- if (!pdb_enum_alias_memberships(&member, &aliases, &num)) {
+ if (!pdb_enum_alias_memberships(&member, 1, &aliases, &num)) {
d_printf("Could not list memberships for sid %s: %s\n",
argv[0], nt_errstr(result));
return -1;
diff --git a/source/utils/net_help.c b/source/utils/net_help.c
index cc5208b821f..8286e853216 100644
--- a/source/utils/net_help.c
+++ b/source/utils/net_help.c
@@ -100,6 +100,7 @@ int net_help_group(int argc, const char **argv)
net_common_flags_usage(argc, argv);
d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
+ d_printf("\t-L or --localgroup\t\tWhen adding groups, create a local group (alias)\n");
return -1;
}
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
index b4f4cdb0a8c..f7ebd94f346 100644
--- a/source/utils/net_idmap.c
+++ b/source/utils/net_idmap.c
@@ -235,6 +235,57 @@ static int net_idmap_restore(int argc, const char **argv)
return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1;
}
+/***********************************************************
+ Delete a SID mapping from a winbindd_idmap.tdb
+ **********************************************************/
+static int net_idmap_delete(int argc, const char **argv)
+{
+ TDB_CONTEXT *idmap_tdb;
+ TDB_DATA key, data;
+ fstring sid;
+
+ if (argc != 2)
+ return net_help_idmap(argc, argv);
+
+ idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDWR, 0);
+
+ if (idmap_tdb == NULL) {
+ d_printf("Could not open idmap: %s\n", argv[0]);
+ return -1;
+ }
+
+ fstrcpy(sid, argv[1]);
+
+ if (strncmp(sid, "S-1-5-", strlen("S-1-5-")) != 0) {
+ d_printf("Can only delete SIDs, %s is does not start with "
+ "S-1-5-\n", sid);
+ return -1;
+ }
+
+ key.dptr = sid;
+ key.dsize = strlen(key.dptr)+1;
+
+ data = tdb_fetch(idmap_tdb, key);
+
+ if (data.dptr == NULL) {
+ d_printf("Could not find sid %s\n", argv[1]);
+ return -1;
+ }
+
+ if (tdb_delete(idmap_tdb, key) != 0) {
+ d_printf("Could not delete key %s\n", argv[1]);
+ return -1;
+ }
+
+ if (tdb_delete(idmap_tdb, data) != 0) {
+ d_printf("Could not delete key %s\n", data.dptr);
+ return -1;
+ }
+
+ return 0;
+}
+
+
int net_help_idmap(int argc, const char **argv)
{
d_printf("net idmap dump filename"\
@@ -243,6 +294,8 @@ int net_help_idmap(int argc, const char **argv)
d_printf("net idmap restore"\
"\n Restore entries from stdin to current local idmap\n");
+ /* Deliberately *not* document net idmap delete */
+
return -1;
}
@@ -254,6 +307,7 @@ int net_idmap(int argc, const char **argv)
struct functable func[] = {
{"dump", net_idmap_dump},
{"restore", net_idmap_restore},
+ {"delete", net_idmap_delete},
{"help", net_help_idmap},
{NULL, NULL}
};
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index e40eeb44f72..4c5544aa973 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -3974,9 +3974,10 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
result = cli_shutdown_abort(cli, mem_ctx);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown successfully aborted\n");
DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
- else
+ } else
DEBUG(5,("cmd_shutdown_abort: query failed\n"));
return result;
@@ -4009,9 +4010,10 @@ static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
result = cli_reg_abort_shutdown(cli, mem_ctx);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown successfully aborted\n");
DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
- else
+ } else
DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
return result;
@@ -4044,7 +4046,7 @@ static int rpc_shutdown_abort(int argc, const char **argv)
}
/**
- * Shut down a remote RPC Server
+ * Shut down a remote RPC Server via initshutdown pipe
*
* All parameters are provided by the run_rpc_command function, except for
* argc, argv which are passes through.
@@ -4059,10 +4061,57 @@ static int rpc_shutdown_abort(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ const char *msg = "This machine will be shutdown shortly";
+ uint32 timeout = 20;
+
+ if (opt_comment) {
+ msg = opt_comment;
+ }
+ if (opt_timeout) {
+ timeout = opt_timeout;
+ }
+
+ /* create an entry */
+ result = cli_shutdown_init(cli, mem_ctx, msg, timeout, opt_reboot,
+ opt_force);
+
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown of remote machine succeeded\n");
+ DEBUG(5,("Shutdown of remote machine succeeded\n"));
+ } else
+ DEBUG(0,("Shutdown of remote machine failed!\n"));
+
+ return result;
+}
+
+/**
+ * Shut down a remote RPC Server via winreg pipe
+ *
+ * All parameters are provided by the run_rpc_command function, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *msg = "This machine will be shutdown shortly";
@@ -4102,8 +4151,10 @@ static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid,
/* create an entry */
result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown of remote machine succeeded\n");
DEBUG(5,("Shutdown of remote machine succeeded\n"));
+ }
else
DEBUG(0,("Shutdown of remote machine failed!\n"));
@@ -4122,7 +4173,15 @@ static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid,
static int rpc_shutdown(int argc, const char **argv)
{
- return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
+ int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
+ rpc_init_shutdown_internals,
+ argc, argv);
+ if (rc == 0)
+ return rc;
+
+ DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
+
+ return run_rpc_command(NULL, PI_WINREG, 0, rpc_reg_shutdown_internals,
argc, argv);
}
diff --git a/source/utils/net_rpc_printer.c b/source/utils/net_rpc_printer.c
index a48fd9fb11b..456a29287fd 100644
--- a/source/utils/net_rpc_printer.c
+++ b/source/utils/net_rpc_printer.c
@@ -305,7 +305,7 @@ net_copy_fileattr(TALLOC_CTX *mem_ctx,
int fnum_dst = 0;
SEC_DESC *sd = NULL;
uint16 attr;
- time_t atime, ctime, mtime;
+ time_t f_atime, f_ctime, f_mtime;
if (!copy_timestamps && !copy_acls && !copy_attrs)
@@ -346,7 +346,7 @@ net_copy_fileattr(TALLOC_CTX *mem_ctx,
/* get file attributes */
if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL,
- &ctime, &atime, &mtime)) {
+ &f_ctime, &f_atime, &f_mtime)) {
DEBUG(0,("failed to get file-attrs: %s\n",
cli_errstr(cli_share_src)));
nt_status = cli_nt_error(cli_share_src);
@@ -368,7 +368,7 @@ net_copy_fileattr(TALLOC_CTX *mem_ctx,
if (copy_timestamps) {
/* set timestamps */
- if (!cli_setattrE(cli_share_dst, fnum_dst, ctime, atime, mtime)) {
+ if (!cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime)) {
DEBUG(0,("failed to set file-attrs (timestamps): %s\n",
cli_errstr(cli_share_dst)));
nt_status = cli_nt_error(cli_share_dst);
@@ -1312,7 +1312,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
POLICY_HND hnd;
BOOL got_hnd = False;
WERROR result;
- char *action_str;
+ const char *action_str;
if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
return nt_status;
@@ -1348,6 +1348,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
action_str = "unpublished";
break;
default:
+ action_str = "unknown action";
printf("unkown action: %d\n", action);
break;
}
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index b31087927a1..e8a110d083e 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -36,6 +36,45 @@ static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
d_printf("\n");
}
+
+static const char *display_time(NTTIME *nttime)
+{
+ static fstring string;
+
+ float high;
+ float low;
+ int sec;
+ int days, hours, mins, secs;
+ int offset = 1;
+
+ if (nttime->high==0 && nttime->low==0)
+ return "Now";
+
+ if (nttime->high==0x80000000 && nttime->low==0)
+ return "Never";
+
+ high = 65536;
+ high = high/10000;
+ high = high*65536;
+ high = high/1000;
+ high = high * (~nttime->high);
+
+ low = ~nttime->low;
+ low = low/(1000*1000*10);
+
+ sec=high+low;
+ sec+=offset;
+
+ days=sec/(60*60*24);
+ hours=(sec - (days*60*60*24)) / (60*60);
+ mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
+ secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
+
+ fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
+ return (string);
+}
+
+
static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a)
{
d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name));
@@ -81,7 +120,25 @@ static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a)
static void display_domain_info(SAM_DOMAIN_INFO *a)
{
+ time_t u_logout;
+
+ u_logout = nt_time_to_unix_abs((NTTIME *)&a->force_logoff);
+
d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name));
+
+ d_printf("Minimal Password Length: %d\n", a->min_pwd_len);
+ d_printf("Password History Length: %d\n", a->pwd_history_len);
+
+ d_printf("Force Logoff: %d\n", (int)u_logout);
+
+ d_printf("Max Password Age: %s\n", display_time((NTTIME *)&a->max_pwd_age));
+ d_printf("Min Password Age: %s\n", display_time((NTTIME *)&a->min_pwd_age));
+
+ d_printf("Lockout Time: %s\n", display_time((NTTIME *)&a->account_lockout.lockout_duration));
+ d_printf("Lockout Reset Time: %s\n", display_time((NTTIME *)&a->account_lockout.reset_count));
+
+ d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout);
+ d_printf("User must logon to change password: %d\n", a->logon_chgpass);
}
static void display_group_info(uint32 rid, SAM_GROUP_INFO *a)
@@ -322,6 +379,14 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
pdb_set_profile_path(account, new_string, PDB_CHANGED);
}
+ if (delta->hdr_parameters.buffer) {
+ old_string = pdb_get_munged_dial(account);
+ new_string = unistr2_static(&delta->uni_parameters);
+
+ if (STRING_CHANGED)
+ pdb_set_munged_dial(account, new_string, PDB_CHANGED);
+ }
+
/* User and group sid */
if (pdb_get_user_rid(account) != delta->user_rid)
pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED);
@@ -347,8 +412,11 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED);
/* TODO: logon hours */
- /* TODO: bad password count */
- /* TODO: logon count */
+ if (pdb_get_bad_password_count(account) != delta->bad_pwd_count)
+ pdb_set_bad_password_count(account, delta->bad_pwd_count, PDB_CHANGED);
+
+ if (pdb_get_logon_count(account) != delta->logon_count)
+ pdb_set_logon_count(account, delta->logon_count, PDB_CHANGED);
if (!nt_time_is_zero(&delta->pwd_last_set_time)) {
unix_time = nt_time_to_unix(&delta->pwd_last_set_time);
@@ -795,7 +863,7 @@ fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
return NT_STATUS_NO_MEMORY;
}
- nt_members = talloc_zero(t, sizeof(char *) * delta->num_members);
+ nt_members = TALLOC_ZERO_ARRAY(t, char *, delta->num_members);
for (i=0; i<delta->num_members; i++) {
NTSTATUS nt_status;
@@ -886,6 +954,58 @@ fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
return NT_STATUS_OK;
}
+static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta)
+{
+ time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ pstring domname;
+
+ u_max_age = nt_time_to_unix_abs((NTTIME *)&delta->max_pwd_age);
+ u_min_age = nt_time_to_unix_abs((NTTIME *)&delta->min_pwd_age);
+ u_logout = nt_time_to_unix_abs((NTTIME *)&delta->force_logoff);
+ u_lockoutreset = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.reset_count);
+ u_lockouttime = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.lockout_duration);
+
+ unistr2_to_ascii(domname, &delta->uni_dom_name, sizeof(domname) - 1);
+
+ /* we don't handle BUILTIN account policies */
+ if (!strequal(domname, get_global_sam_name())) {
+ printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname);
+ return NT_STATUS_OK;
+ }
+
+
+ if (!account_policy_set(AP_PASSWORD_HISTORY, delta->pwd_history_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_LEN, delta->min_pwd_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ return nt_status;
+
+ if (!account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout))
+ return nt_status;
+
+ if (!account_policy_set(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
+ return nt_status;
+
+ return NT_STATUS_OK;
+}
+
+
static void
fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
DOM_SID dom_sid)
@@ -911,10 +1031,11 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
fetch_alias_mem(hdr_delta->target_rid,
&delta->als_mem_info, dom_sid);
break;
- /* The following types are recognised but not handled */
case SAM_DELTA_DOMAIN_INFO:
- d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
+ fetch_domain_info(hdr_delta->target_rid,
+ &delta->domain_info);
break;
+ /* The following types are recognised but not handled */
case SAM_DELTA_RENAME_GROUP:
d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
break;
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 3d55c373558..0468b671afa 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -753,7 +753,7 @@ static void offer_gss_spnego_mechs(void) {
/* Server negTokenInit (mech offerings) */
spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(char *, 3);
+ spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 3);
#ifdef HAVE_KRB5
spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index 2e8d0d6d96f..ff08642f407 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -26,8 +26,8 @@
#define BIT_BACKEND 0x00000004
#define BIT_VERBOSE 0x00000008
#define BIT_SPSTYLE 0x00000010
-#define BIT_RESERV_1 0x00000020
-#define BIT_RESERV_2 0x00000040
+#define BIT_CAN_CHANGE 0x00000020
+#define BIT_MUST_CHANGE 0x00000040
#define BIT_RESERV_3 0x00000080
#define BIT_FULLNAME 0x00000100
#define BIT_HOMEDIR 0x00000200
@@ -52,7 +52,7 @@
#define BIT_LOGONHOURS 0x10000000
#define MASK_ALWAYS_GOOD 0x0000001F
-#define MASK_USER_GOOD 0x00401F00
+#define MASK_USER_GOOD 0x00401F60
/*********************************************************
Add all currently available users to another db
@@ -302,7 +302,8 @@ static int set_user_info (struct pdb_context *in, const char *username,
const char *drive, const char *script,
const char *profile, const char *account_control,
const char *user_sid, const char *group_sid,
- const BOOL badpw, const BOOL hours)
+ const BOOL badpw, const BOOL hours,
+ time_t pwd_can_change, time_t pwd_must_change)
{
BOOL updated_autolock = False, updated_badpw = False;
SAM_ACCOUNT *sam_pwent=NULL;
@@ -326,7 +327,15 @@ static int set_user_info (struct pdb_context *in, const char *username,
pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
}
-
+
+ if (pwd_can_change != -1) {
+ pdb_set_pass_can_change_time(sam_pwent, pwd_can_change, PDB_CHANGED);
+ }
+
+ if (pwd_must_change != -1) {
+ pdb_set_pass_must_change_time(sam_pwent, pwd_must_change, PDB_CHANGED);
+ }
+
if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
DEBUG(2,("pdb_update_autolock_flag failed.\n"));
}
@@ -650,6 +659,9 @@ int main (int argc, char **argv)
BOOL account_policy_value_set = False;
static BOOL badpw_reset = False;
static BOOL hours_reset = False;
+ static char *pwd_can_change_time = NULL;
+ static char *pwd_must_change_time = NULL;
+ static char *pwd_time_format = NULL;
struct pdb_context *bin;
struct pdb_context *bout;
@@ -682,6 +694,9 @@ int main (int argc, char **argv)
{"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
{"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
{"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
+ {"pwd-can-change-time", 0, POPT_ARG_STRING, &pwd_can_change_time, 0, "Set password can change time (unix time if time format no provided)", NULL },
+ {"pwd-must-change-time", 0, POPT_ARG_STRING, &pwd_must_change_time, 0, "Set password can change time (unix time if time format no provided)", NULL },
+ {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
POPT_COMMON_SAMBA
POPT_TABLEEND
};
@@ -736,7 +751,9 @@ int main (int argc, char **argv)
(backend_in ? BIT_IMPORT : 0) +
(backend_out ? BIT_EXPORT : 0) +
(badpw_reset ? BIT_BADPWRESET : 0) +
- (hours_reset ? BIT_LOGONHOURS : 0);
+ (hours_reset ? BIT_LOGONHOURS : 0) +
+ (pwd_can_change_time ? BIT_CAN_CHANGE: 0) +
+ (pwd_must_change_time ? BIT_MUST_CHANGE: 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
@@ -887,13 +904,71 @@ int main (int argc, char **argv)
/* account modification operations */
if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
+ time_t pwd_can_change = -1;
+ time_t pwd_must_change = -1;
+ char *errstr;
+
+ if (pwd_can_change_time) {
+ errstr = "can";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_can_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_can_change = mktime(&tm);
+
+ if (pwd_can_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_can_change = strtol(pwd_can_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
+ if (pwd_must_change_time) {
+ errstr = "must";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_must_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_must_change = mktime(&tm);
+
+ if (pwd_must_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_must_change = strtol(pwd_must_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
return set_user_info (bdef, user_name, full_name,
home_dir,
home_drive,
logon_script,
profile_path, account_control,
user_sid, group_sid,
- badpw_reset, hours_reset);
+ badpw_reset, hours_reset,
+ pwd_can_change, pwd_must_change);
+error:
+ fprintf (stderr, "Error parsing the time in pwd-%s-change-time!\n", errstr);
+ return -1;
}
}
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 3963adb9f0c..048ec8dc3ef 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -657,6 +657,14 @@ static int cacl_set(struct cli_state *cli, char *filename,
}
}
+ if (sd->owner_sid) {
+ old->owner_sid = sd->owner_sid;
+ }
+
+ if (sd->grp_sid) {
+ old->grp_sid = sd->grp_sid;
+ }
+
break;
case SMB_ACL_ADD:
@@ -674,7 +682,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
sort_acl(old->dacl);
/* Create new security descriptor and set it */
- sd = make_sec_desc(ctx,old->revision, old->type, NULL, NULL,
+ sd = make_sec_desc(ctx,old->revision, old->type, old->owner_sid, old->grp_sid,
NULL, old->dacl, &sd_size);
fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS);
@@ -761,7 +769,7 @@ static struct cli_state *connect_one(const char *share)
ctx=talloc_init("main");
- /* set default debug level to 0 regardless of what smb.conf sets */
+ /* set default debug level to 1 regardless of what smb.conf sets */
setup_logging( "smbcacls", True );
DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
dbf = x_stderr;
diff --git a/source/utils/smbget.c b/source/utils/smbget.c
index 64630bba8fd..2aca3001a36 100644
--- a/source/utils/smbget.c
+++ b/source/utils/smbget.c
@@ -128,7 +128,7 @@ int smb_download_dir(const char *base, const char *name, int resume)
while(*relname == '/')relname++;
mkdir(relname, 0755);
- tmpname = strdup(name);
+ tmpname = SMB_STRDUP(name);
while((dirent = smbc_readdir(dirhandle))) {
char *newname;
@@ -231,7 +231,7 @@ void print_progress(const char *name, time_t start, time_t now, off_t start_pos,
int required = strlen(name), available = columns - len - strlen("[] ");
if(required > available) asprintf(&filename, "...%s", name + required - available + 3);
else filename = strndup(name, available);
- } else filename = strdup(name);
+ } else filename = SMB_STRDUP(name);
fprintf(stderr, "\r[%s] %s", filename, status);
@@ -376,7 +376,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
offset_check = 0;
}
- readbuf = malloc(blocksize);
+ readbuf = SMB_MALLOC(blocksize);
/* Now, download all bytes from offset_download to the end */
for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) {
@@ -487,7 +487,7 @@ int readrcfile(const char *name, const struct poptOption long_options[])
break;
case POPT_ARG_STRING:
stringdata = (char **)long_options[i].arg;
- *stringdata = strdup(val);
+ *stringdata = SMB_STRDUP(val);
break;
default:
fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name);
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 74480f5fc53..90c3ce4d2e2 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -433,7 +433,8 @@ static int process_root(int local_flags)
pdb_init_sam(&sampass);
ret = pdb_getsampwnam(sampass, user_name);
- if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) {
+ if((ret) &&
+ (pdb_get_lanman_passwd(sampass) == NULL)) {
local_flags |= LOCAL_SET_PASSWORD;
}
pdb_free_sam(&sampass);
diff --git a/source/utils/status.c b/source/utils/status.c
index 122c6193f91..cae4e07975a 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -36,7 +36,7 @@
#include "includes.h"
#define SMB_MAXPIDS 2048
-static pstring Ucrit_username = ""; /* added by OH */
+static uid_t Ucrit_uid = 0; /* added by OH */
static pid_t Ucrit_pid[SMB_MAXPIDS]; /* Ugly !!! */ /* added by OH */
static int Ucrit_MaxPid=0; /* added by OH */
static unsigned int Ucrit_IsActive = 0; /* added by OH */
@@ -46,24 +46,23 @@ static int shares_only = 0; /* Added by RJS */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
static int show_brl;
+static BOOL numeric_only = False;
const char *username = NULL;
/* added by OH */
-static void Ucrit_addUsername(const char *username)
+static void Ucrit_addUid(uid_t uid)
{
- pstrcpy(Ucrit_username, username);
-
- if ( strlen(Ucrit_username) > 0 )
- Ucrit_IsActive = 1;
+ Ucrit_uid = uid;
+ Ucrit_IsActive = 1;
}
-static unsigned int Ucrit_checkUsername(const char *username)
+static unsigned int Ucrit_checkUid(uid_t uid)
{
if ( !Ucrit_IsActive )
return 1;
- if ( strcmp(Ucrit_username,username) == 0 )
+ if ( uid == Ucrit_uid )
return 1;
return 0;
@@ -91,7 +90,7 @@ static BOOL Ucrit_addPid( pid_t pid )
if ( Ucrit_MaxPid >= SMB_MAXPIDS ) {
d_printf("ERROR: More than %d pids for user %s!\n",
- SMB_MAXPIDS, Ucrit_username);
+ SMB_MAXPIDS, uidtoname(Ucrit_uid));
return False;
}
@@ -538,7 +537,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
if (crec.cnum == -1)
return 0;
- if (!process_exists(crec.pid) || !Ucrit_checkUsername(uidtoname(crec.uid))) {
+ if (!process_exists(crec.pid) || !Ucrit_checkUid(crec.uid)) {
return 0;
}
@@ -553,21 +552,27 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
struct sessionid sessionid;
+ fstring uid_str, gid_str;
if (dbuf.dsize != sizeof(sessionid))
return 0;
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
- if (!process_exists(sessionid.pid) || !Ucrit_checkUsername(uidtoname(sessionid.uid))) {
+ if (!process_exists(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
return 0;
}
Ucrit_addPid( sessionid.pid );
+ fstr_sprintf(uid_str, "%d", sessionid.uid);
+ fstr_sprintf(gid_str, "%d", sessionid.gid);
+
d_printf("%5d %-12s %-12s %-12s (%s)\n",
- (int)sessionid.pid, uidtoname(sessionid.uid), gidtoname(sessionid.gid),
- sessionid.remote_machine, sessionid.hostname);
+ (int)sessionid.pid,
+ numeric_only ? uid_str : uidtoname(sessionid.uid),
+ numeric_only ? gid_str : gidtoname(sessionid.gid),
+ sessionid.remote_machine, sessionid.hostname);
return 0;
}
@@ -594,6 +599,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
{"profile", 'P', POPT_ARG_NONE, &profile_only, 'P', "Do profiling" },
#endif /* WITH_PROFILE */
{"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"},
+ {"numeric", 'n', POPT_ARG_NONE, &numeric_only, 'n', "Numeric uid/gid"},
POPT_COMMON_SAMBA
POPT_TABLEEND
};
@@ -613,7 +619,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
while ((c = poptGetNextOpt(pc)) != -1) {
switch (c) {
case 'u':
- Ucrit_addUsername(poptGetOptArg(pc));
+ Ucrit_addUid(nametouid(poptGetOptArg(pc)));
break;
}
}
@@ -625,7 +631,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
show_shares = !(processes_only || locks_only || profile_only) || shares_only;
if ( username )
- Ucrit_addUsername( username );
+ Ucrit_addUid( nametouid(username) );
if (verbose) {
d_printf("using configfile = %s\n", dyn_CONFIGFILE);
diff --git a/source/wrepld/server.c b/source/wrepld/server.c
index d78e0b206f3..9d035a6cbff 100644
--- a/source/wrepld/server.c
+++ b/source/wrepld/server.c
@@ -164,7 +164,7 @@ void exit_server(const char *reason)
plus the broadcast sockets.
***************************************************************************/
-static BOOL create_listen_fdset(void)
+static BOOL create_listen_fdset( int *maxfd)
{
int i;
int num_interfaces = iface_count();
@@ -221,6 +221,7 @@ static BOOL create_listen_fdset(void)
}
add_fd_to_sock_array(s);
FD_SET(s, listen_set);
+ *maxfd = MAX( *maxfd, s);
}
} else {
/* Just bind to 0.0.0.0 - accept connections from anywhere. */
@@ -243,6 +244,7 @@ static BOOL create_listen_fdset(void)
add_fd_to_sock_array(s);
FD_SET(s, listen_set);
+ *maxfd = MAX( *maxfd, s);
}
return True;
@@ -346,10 +348,11 @@ static BOOL listen_for_wins_packets(void)
int num_interfaces = iface_count();
fd_set fds;
int i, num, s, new_s;
+ static int maxfd = 0;
struct timeval timeout;
if(listen_set == NULL) {
- if(!create_listen_fdset()) {
+ if(!create_listen_fdset( &maxfd)) {
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
@@ -364,7 +367,7 @@ static BOOL listen_for_wins_packets(void)
BlockSignals(False, SIGTERM);
- num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ num = sys_select(maxfd+1, &fds, NULL, NULL, &timeout);
/* We can only take signals when we are in the select - block them again here. */
@@ -397,6 +400,7 @@ static BOOL listen_for_wins_packets(void)
set_socket_options(new_s, user_socket_options);
FD_SET(new_s, listen_set);
add_fd_to_sock_array(new_s);
+ maxfd = MAX( maxfd, new_s);
}
}