Samba-3.0.x This release turned into maintenance mode since we
released 3.2.
-Samba-3.2.x This is the current stable Samba 3 release intended
+Samba-3.4.x This is the current stable Samba 3 release intended
for all Samba production server.
Samba-4 Danger Will Robinson, a big code clean up with major
o Changed the way smbd handles untrusted domain names given during user
authentication
-net Command Changes:
-o parameter syntax made more consistent
-
Authentication Changes
======================
parameter "map untrusted to domain" can be enabled to revert to the legacy
behavior.
-net Command Changes
-===================
-
-The net command now accepts the common command line parameters most other Samba
-command line utilities use, with a couple of remaining differences:
-
--l still gives long output for net commands supporting the --long flag. This was
-more useful than the common --log-base parameter.
-
--i still tells net to read data from stdin (like --stdin) instead of toggling
-the common --scope flag.
-
--S still tells net the server to connect to (like --server) instead of
-negotiating the common --signing flag. As -S is probably used by most scripts
-doing net rpc commands, this would have been a high-impact change for little
-gain.
-
-This change was mainly done to unify the authentification options. Here, one
-flag changed it's meaning and one useful flag was added.
-
--N used to be the short version of --ntname. It now matches the Samba default of
---no-pass. Use this to stop net from prompting for a password if you want
-anonymous authentication.
-
--A --authentication-file now takes an authentication file with the username and
-password you want net to use, avoiding a password prompt as with plain -U user
-or having to give a password on the command line as in -U user%pass.
-
-Last but not least net now always falls back to your local unix username if no
--U is specified and a username is needed. net rpc commands will now prompt for a
-password unless one is specified using either -U user%pass or -A auth_file.
-
######################################################################
Reporting bugs & Development Discussion
#######################################
/*
* CIFS user-space helper.
* Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
+* Copyright (C) Jeff Layton (jlayton@redhat.com) 2009
*
* Used by /sbin/request-key for handling
* cifs upcall for kerberos authorization of access to share and
MS_KRB5
} secType_t;
+/*
+ * given a process ID, get the value of the KRB5CCNAME environment variable
+ * in the context of that process. On error, just return NULL.
+ */
+static char *
+get_krb5_ccname(pid_t pid)
+{
+ int fd;
+ ssize_t len, left;
+
+ /*
+ * FIXME: sysconf for ARG_MAX instead? Kernel seems to be limited to a
+ * page however, so it may not matter.
+ */
+ char buf[4096];
+ char *p, *value = NULL;
+
+ buf[4095] = '\0';
+ snprintf(buf, 4095, "/proc/%d/environ", pid);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ /* FIXME: don't assume that we get it all in the first read? */
+ len = read(fd, buf, 4096);
+ close(fd);
+ if (len < 0)
+ return NULL;
+
+ left = len;
+ p = buf;
+
+ /* can't have valid KRB5CCNAME if there are < 13 bytes left */
+ while (left > 12) {
+ if (strncmp("KRB5CCNAME=", p, 11)) {
+ p += strnlen(p, left);
+ ++p;
+ left = buf + len - p;
+ continue;
+ }
+ p += 11;
+ left -= 11;
+ value = SMB_STRNDUP(p, left);
+ break;
+ }
+ return value;
+}
+
/*
* Prepares AP-REQ data for mechToken and gets session key
* Uses credentials from cache. It will not ask for password
* ret: 0 - success, others - failure
*/
static int
-handle_krb5_mech(const char *oid, const char *principal,
- DATA_BLOB * secblob, DATA_BLOB * sess_key)
+handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob,
+ DATA_BLOB *sess_key, const char *ccname)
{
int retval;
DATA_BLOB tkt, tkt_wrapped;
/* get a kerberos ticket for the service and extract the session key */
- retval = cli_krb5_get_ticket(principal, 0,
- &tkt, sess_key, 0, NULL, NULL);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname,
+ NULL);
if (retval)
return retval;
#define DKD_HAVE_IPV4 8
#define DKD_HAVE_IPV6 16
#define DKD_HAVE_UID 32
+#define DKD_HAVE_PID 64
#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
static int
-decode_key_description(const char *desc, int *ver, secType_t * sec,
- char **hostname, uid_t * uid)
+decode_key_description(const char *desc, int *ver, secType_t *sec,
+ char **hostname, uid_t *uid, pid_t *pid)
{
int retval = 0;
char *pos;
/* BB: do we need it if we have hostname already? */
} else if (strncmp(tkn, "ipv6=", 5) == 0) {
/* BB: do we need it if we have hostname already? */
+ } else if (strncmp(tkn, "pid=", 4) == 0) {
+ errno = 0;
+ *pid = strtol(tkn + 4, NULL, 0);
+ if (errno != 0) {
+ syslog(LOG_WARNING, "Invalid pid format: %s",
+ strerror(errno));
+ return 1;
+ } else {
+ retval |= DKD_HAVE_PID;
+ }
} else if (strncmp(tkn, "sec=", 4) == 0) {
if (strncmp(tkn + 4, "krb5", 4) == 0) {
retval |= DKD_HAVE_SEC;
size_t datalen;
long rc = 1;
uid_t uid = 0;
+ pid_t pid = 0;
int kernel_upcall_version = 0;
int c, use_cifs_service_prefix = 0;
- char *buf, *hostname = NULL;
+ char *buf, *ccname = NULL, *hostname = NULL;
const char *oid;
openlog(prog, 0, LOG_DAEMON);
}
rc = decode_key_description(buf, &kernel_upcall_version, §ype,
- &hostname, &uid);
+ &hostname, &uid, &pid);
if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
syslog(LOG_WARNING,
"unable to get from description necessary params");
goto out;
}
+ if (rc & DKD_HAVE_PID)
+ ccname = get_krb5_ccname(pid);
+
if (rc & DKD_HAVE_UID) {
rc = setuid(uid);
if (rc == -1) {
}
}
- /* BB: someday upcall SPNEGO blob could be checked here to decide
- * what mech to use */
-
// do mech specific authorization
switch (sectype) {
case MS_KRB5:
else
oid = OID_KERBEROS5;
- rc = handle_krb5_mech(oid, princ, &secblob, &sess_key);
+ rc = handle_krb5_mech(oid, princ, &secblob, &sess_key,
+ ccname);
SAFE_FREE(princ);
break;
}
keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
data_blob_free(&secblob);
data_blob_free(&sess_key);
+ SAFE_FREE(ccname);
SAFE_FREE(hostname);
SAFE_FREE(keydata);
return rc;
attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
# "refuse machine password change"
attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPassword' DESC 'Clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTextPassword' DESC 'Previous clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
##
#######################################################################
## objectClasses: used by Samba 3.0 schema ##
## DESC 'Samba Privilege'
## MUST ( sambaSID )
## MAY ( sambaPrivilegeList ) )
+##
+## Trusted Domain Relationships
+##
+objectClasses: ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassword' SUP top STRUCTURAL DESC 'Samba Trusted Domain Password' MUST ( sambaDomainName $ sambaSID $ sambaClearTextPassword $ sambaPwdLastSet ) MAY ( sambaPreviousClearTextPassword ) )
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-09-19'
+timestamp='2009-04-27'
# 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
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
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" ; } ||
+ { tmp=`(umask 077 && mktemp -d "$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 ; } ;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
macppc:MirBSD:*:*)
- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
- i*:MINGW*:*)
+ *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- x86:Interix*:[34]*)
- echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
- exit ;;
+ *:Interix*:[3456]*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T | authenticamd | genuineintel)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
LIBC=gnulibc1
# endif
#else
- #ifdef __INTEL_COMPILER
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
LIBC=dietlibc
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-07-08'
+timestamp='2009-04-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
#
# 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
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
# 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* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
- kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
-hiux*)
os=-hiuxwe2
;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
| 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 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
+ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
- | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
- | ms1 \
+ | moxie \
+ | mt \
| msp430 \
+ | nios | nios2 \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b \
- | strongarm \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
- | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m32c)
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* \
+ | avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
- | m32r-* | m32rle-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
- | ms1-* \
+ | mt-* \
| msp430-* \
+ | nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
;;
- m32c-*)
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16c)
- basic_machine=cr16c-unknown
+ cr16)
+ basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
basic_machine=i386-pc
os=-mingw32
;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
miniframe)
basic_machine=m68000-convergent
;;
basic_machine=i386-pc
os=-msdos
;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
basic_machine=i586-unknown
os=-pw32
;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
sei)
basic_machine=mips-sei
os=-seiux
basic_machine=sh-hitachi
os=-hms
;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
sh64)
basic_machine=sh64-unknown
;;
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv8 | sparcv9 | sparcv9b)
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
| -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* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -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* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
-none)
;;
*)
# system, and we'll never get to this point.
case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
m68*-cisco)
os=-aout
;;
+ mep-*)
+ os=-elf
+ ;;
mips*-cisco)
os=-elf
;;
AC_CHECK_HEADERS(stdarg.h vararg.h)
AC_CHECK_HEADERS(sys/mount.h mntent.h)
AC_CHECK_HEADERS(stropts.h)
+AC_CHECK_HEADERS(unix.h)
AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
int rep_lchown(const char *fname,uid_t uid,gid_t gid);
#endif
+#ifdef HAVE_UNIX_H
+#include <unix.h>
+#endif
+
#ifndef HAVE_SETLINEBUF
#define setlinebuf rep_setlinebuf
void rep_setlinebuf(FILE *);
*/
int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
{
- if (tdb->have_transaction_lock || tdb->global_lock.count) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 0) {
+ tdb->transaction_lock_count++;
return 0;
}
+
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
F_SETLKW, 0, 1) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
tdb->ecode = TDB_ERR_LOCK;
return -1;
}
- tdb->have_transaction_lock = 1;
+ tdb->transaction_lock_count++;
return 0;
}
int tdb_transaction_unlock(struct tdb_context *tdb)
{
int ret;
- if (!tdb->have_transaction_lock) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 1) {
+ tdb->transaction_lock_count--;
return 0;
}
ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
if (ret == 0) {
- tdb->have_transaction_lock = 0;
+ tdb->transaction_lock_count = 0;
}
return ret;
}
struct tdb_transaction *transaction;
int page_size;
int max_dead_records;
- bool have_transaction_lock;
+ int transaction_lock_count;
volatile sig_atomic_t *interrupt_sig_ptr;
};
{
struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
int ret;
- bool in_transaction = (tdb->transaction != NULL);
/* we need to get a read lock on the transaction lock here to
cope with the lock ordering semantics of solaris10 */
- if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_RDLCK)) {
- return -1;
- }
+ if (tdb_transaction_lock(tdb, F_RDLCK)) {
+ return -1;
}
tdb->traverse_read++;
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_read--;
- if (!in_transaction) {
- tdb_transaction_unlock(tdb);
- }
+ tdb_transaction_unlock(tdb);
return ret;
}
{
struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
int ret;
- bool in_transaction = (tdb->transaction != NULL);
if (tdb->read_only || tdb->traverse_read) {
return tdb_traverse_read(tdb, fn, private_data);
}
- if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_WRLCK)) {
- return -1;
- }
+ if (tdb_transaction_lock(tdb, F_WRLCK)) {
+ return -1;
}
tdb->traverse_write++;
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_write--;
- if (!in_transaction) {
- tdb_transaction_unlock(tdb);
- }
+ tdb_transaction_unlock(tdb);
return ret;
}
const char *backend = (const char *)test_data;
int alarm_count=0, info_count=0;
struct tevent_fd *fde;
- struct signal_event *se1, *se2, *se3;
+#ifdef SA_RESTART
+ struct tevent_signal *se1 = NULL;
+#endif
+ struct tevent_signal *se2 = NULL;
+#ifdef SA_SIGINFO
+ struct tevent_signal *se3 = NULL;
+#endif
int finished=0;
struct timeval t;
char c = 0;
event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0),
finished_handler, &finished);
+#ifdef SA_RESTART
se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count);
+#endif
se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count);
#ifdef SA_SIGINFO
se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count);
torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
+#ifdef SA_RESTART
talloc_free(se1);
+#endif
torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
return NULL;
}
- data = talloc_size(req, data_size);
+ data = talloc_zero_size(req, data_size);
if (data == NULL) {
talloc_free(req);
return NULL;
if (subtorture == NULL)
return NULL;
- subtorture->level = parent->level+1;
subtorture->ev = talloc_reference(subtorture, parent->ev);
subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx);
subtorture->outputdir = talloc_reference(subtorture, parent->outputdir);
struct torture_suite *tsuite;
char *old_testname;
- context->level++;
if (context->results->ui_ops->suite_start)
context->results->ui_ops->suite_start(context, suite);
if (context->results->ui_ops->suite_finish)
context->results->ui_ops->suite_finish(context, suite);
- context->level--;
-
return ret;
}
char *old_testname;
struct torture_test *test;
- context->level++;
-
context->active_tcase = tcase;
if (context->results->ui_ops->tcase_start)
context->results->ui_ops->tcase_start(context, tcase);
if (context->results->ui_ops->tcase_finish)
context->results->ui_ops->tcase_finish(context, tcase);
- context->level--;
-
return ret;
}
/** Directory used for temporary test data */
const char *outputdir;
- /** Indentation level */
- int level;
-
/** Event context */
struct tevent_context *ev;
static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
struct sockaddr *sa,
- socklen_t sa_len,
+ socklen_t sa_socklen,
struct tsocket_address **_addr,
const char *location)
{
switch (sa->sa_family) {
case AF_UNIX:
- if (sa_len < sizeof(struct sockaddr_un)) {
+ if (sa_socklen < sizeof(struct sockaddr_un)) {
errno = EINVAL;
return -1;
}
break;
case AF_INET:
- if (sa_len < sizeof(struct sockaddr_in)) {
+ if (sa_socklen < sizeof(struct sockaddr_in)) {
errno = EINVAL;
return -1;
}
break;
#ifdef HAVE_IPV6
case AF_INET6:
- if (sa_len < sizeof(struct sockaddr_in6)) {
+ if (sa_socklen < sizeof(struct sockaddr_in6)) {
errno = EINVAL;
return -1;
}
return -1;
}
- if (sa_len > sizeof(struct sockaddr_storage)) {
+ if (sa_socklen > sizeof(struct sockaddr_storage)) {
errno = EINVAL;
return -1;
}
ZERO_STRUCTP(bsda);
- memcpy(&bsda->u.ss, sa, sa_len);
+ memcpy(&bsda->u.ss, sa, sa_socklen);
*_addr = addr;
return 0;
struct tsocket_address_bsd *bsda;
ssize_t ret;
struct sockaddr *sa = NULL;
- socklen_t sa_len = 0;
+ socklen_t sa_socklen = 0;
int err;
bool retry;
ZERO_STRUCTP(bsda);
sa = &bsda->u.sa;
- sa_len = sizeof(bsda->u.ss);
+ sa_socklen = sizeof(bsda->u.ss);
/*
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
if (bsda->u.sa.sa_family == AF_UNIX) {
- sa_len = sizeof(bsda->u.un);
+ sa_socklen = sizeof(bsda->u.un);
}
- ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_len);
+ ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
struct tdgram_context *dgram = state->dgram;
struct tdgram_bsd *bsds = tdgram_context_data(dgram, struct tdgram_bsd);
struct sockaddr *sa = NULL;
- socklen_t sa_len = 0;
+ socklen_t sa_socklen = 0;
ssize_t ret;
int err;
bool retry;
struct tsocket_address_bsd);
sa = &bsda->u.sa;
- sa_len = sizeof(bsda->u.ss);
+ sa_socklen = sizeof(bsda->u.ss);
/*
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
if (bsda->u.sa.sa_family == AF_UNIX) {
- sa_len = sizeof(bsda->u.un);
+ sa_socklen = sizeof(bsda->u.un);
}
}
- ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_len);
+ ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
int ret;
bool do_bind = false;
bool do_reuseaddr = false;
- socklen_t sa_len = sizeof(lbsda->u.ss);
+ socklen_t sa_socklen = sizeof(lbsda->u.ss);
if (remote) {
rbsda = talloc_get_type_abort(remote->private_data,
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
- sa_len = sizeof(lbsda->u.un);
+ sa_socklen = sizeof(lbsda->u.un);
break;
case AF_INET:
if (lbsda->u.in.sin_port != 0) {
}
if (do_bind) {
- ret = bind(fd, &lbsda->u.sa, sa_len);
+ ret = bind(fd, &lbsda->u.sa, sa_socklen);
if (ret == -1) {
int saved_errno = errno;
talloc_free(dgram);
}
if (rbsda) {
- ret = connect(fd, &rbsda->u.sa, sa_len);
+ ret = connect(fd, &rbsda->u.sa, sa_socklen);
if (ret == -1) {
int saved_errno = errno;
talloc_free(dgram);
bool retry;
bool do_bind = false;
bool do_reuseaddr = false;
- socklen_t sa_len = sizeof(rbsda->u.ss);
+ socklen_t sa_socklen = sizeof(rbsda->u.ss);
req = tevent_req_create(mem_ctx, &state,
struct tstream_bsd_connect_state);
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
- sa_len = sizeof(rbsda->u.un);
+ sa_socklen = sizeof(rbsda->u.un);
break;
case AF_INET:
if (lbsda->u.in.sin_port != 0) {
}
}
- ret = connect(state->fd, &rbsda->u.sa, sa_len);
+ ret = connect(state->fd, &rbsda->u.sa, sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
_PUBLIC_ bool check_password_quality(const char *s)
{
int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0;
+ const char* reals = s;
while (*s) {
if (isdigit((unsigned char)*s)) {
has_digit |= 1;
}
return ((has_digit + has_lower + has_capital + has_special) >= 3
- || (has_high > strlen(s)/2));
+ || (has_high > strlen(reals)/2));
}
/**
torture_assert(tctx, !check_password_quality("aaaaaaaaaaaa"), "same char password");
torture_assert(tctx, !check_password_quality("BLA"), "multiple upcases password");
torture_assert(tctx, !check_password_quality("123"), "digits only");
+ torture_assert(tctx, !check_password_quality("matthiéu"), "not enough high symbols");
+ torture_assert(tctx, check_password_quality("abcdééà çè"), "valid");
torture_assert(tctx, check_password_quality("A2e"), "valid");
torture_assert(tctx, check_password_quality("BA2eLi443"), "valid");
return true;
return false;
}
if (write(fd, packet, length) != (size_t)length) {
+ close(fd);
return false;
}
close(fd);
positive number. */
if ((num_aces) &&
- ((dst->aces = talloc_array(ctx, struct security_ace, num_aces))
+ ((dst->aces = talloc_array(dst, struct security_ace, num_aces))
== NULL)) {
return NULL;
}
-/*
+/*
Unix SMB/CIFS implementation.
- helper mapping functions for the SAMDB server
-
+ helper mapping functions for the UF and ACB flags
+
Copyright (C) Stefan (metze) Metzmacher 2002
Copyright (C) Andrew Tridgell 2004
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "librpc/gen_ndr/samr.h"
-#include "dsdb/common/flags.h"
-#include "lib/ldb/include/ldb.h"
-#include "dsdb/common/proto.h"
+#include "../libds/common/flags.h"
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
+/*
+translated the ACB_CTRL Flags to UserFlags (userAccountControl)
+*/
/* mapping between ADS userAccountControl and SAMR acct_flags */
static const struct {
uint32_t uf;
{ UF_NO_AUTH_DATA_REQUIRED, ACB_NO_AUTH_DATA_REQD }
};
-uint32_t samdb_acb2uf(uint32_t acb)
+uint32_t ds_acb2uf(uint32_t acb)
{
uint32_t i, ret = 0;
for (i=0;i<ARRAY_SIZE(acct_flags_map);i++) {
/*
translated the UserFlags (userAccountControl) to ACB_CTRL Flags
*/
-uint32_t samdb_uf2acb(uint32_t uf)
+uint32_t ds_uf2acb(uint32_t uf)
{
uint32_t i;
uint32_t ret = 0;
return ret;
}
-/*
+/*
get the accountType from the UserFlags
*/
-uint32_t samdb_uf2atype(uint32_t uf)
+uint32_t ds_uf2atype(uint32_t uf)
{
uint32_t atype = 0x00000000;
-
+
if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
return atype;
-}
+}
-/*
+/*
get the accountType from the groupType
*/
-uint32_t samdb_gtype2atype(uint32_t gtype)
+uint32_t ds_gtype2atype(uint32_t gtype)
{
uint32_t atype = 0x00000000;
-
+
switch(gtype) {
case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
atype = ATYPE_SECURITY_LOCAL_GROUP;
case GTYPE_SECURITY_GLOBAL_GROUP:
atype = ATYPE_SECURITY_GLOBAL_GROUP;
break;
-
+
case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
break;
}
/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType samdb_atype_map(uint32_t atype)
+enum lsa_SidType ds_atype_map(uint32_t atype)
{
switch (atype & 0xF0000000) {
case ATYPE_GLOBAL_GROUP:
/* UserFlags for userAccountControl */
#define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */
#define UF_ACCOUNTDISABLE 0x00000002
-#define UF_00000004 0x00000004
+#define UF_00000004 0x00000004
#define UF_HOMEDIR_REQUIRED 0x00000008
-#define UF_LOCKOUT 0x00000010
-#define UF_PASSWD_NOTREQD 0x00000020
-#define UF_PASSWD_CANT_CHANGE 0x00000040
+#define UF_LOCKOUT 0x00000010
+#define UF_PASSWD_NOTREQD 0x00000020
+#define UF_PASSWD_CANT_CHANGE 0x00000040
#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080
-#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */
-#define UF_NORMAL_ACCOUNT 0x00000200
-#define UF_00000400 0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
+#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */
+#define UF_NORMAL_ACCOUNT 0x00000200
+#define UF_00000400 0x00000400
+#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
-#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
-#define UF_SERVER_TRUST_ACCOUNT 0x00002000
-#define UF_00004000 0x00004000
-#define UF_00008000 0x00008000
+#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
+#define UF_SERVER_TRUST_ACCOUNT 0x00002000
+#define UF_00004000 0x00004000
+#define UF_00008000 0x00008000
#define UF_DONT_EXPIRE_PASSWD 0x00010000
#define UF_MNS_LOGON_ACCOUNT 0x00020000
#define UF_PASSWORD_EXPIRED 0x00800000
#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
+#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
+
+#define UF_MACHINE_ACCOUNT_MASK (\
+ UF_INTERDOMAIN_TRUST_ACCOUNT |\
+ UF_WORKSTATION_TRUST_ACCOUNT |\
+ UF_SERVER_TRUST_ACCOUNT \
+ )
+
+#define UF_ACCOUNT_TYPE_MASK (\
+ UF_TEMP_DUPLICATE_ACCOUNT |\
+ UF_NORMAL_ACCOUNT |\
+ UF_INTERDOMAIN_TRUST_ACCOUNT |\
+ UF_WORKSTATION_TRUST_ACCOUNT |\
+ UF_SERVER_TRUST_ACCOUNT \
+ )
+
+#define UF_SETTABLE_BITS (\
+ UF_SCRIPT |\
+ UF_ACCOUNTDISABLE |\
+ UF_HOMEDIR_REQUIRED |\
+ UF_LOCKOUT |\
+ UF_PASSWD_NOTREQD |\
+ UF_PASSWD_CANT_CHANGE |\
+ UF_ACCOUNT_TYPE_MASK | \
+ UF_DONT_EXPIRE_PASSWD | \
+ UF_MNS_LOGON_ACCOUNT |\
+ UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
+ UF_SMARTCARD_REQUIRED |\
+ UF_TRUSTED_FOR_DELEGATION |\
+ UF_NOT_DELEGATED |\
+ UF_USE_DES_KEY_ONLY |\
+ UF_DONT_REQUIRE_PREAUTH \
+ )
/* sAMAccountType */
#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */
#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
+#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */
#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
+#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */
#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */
-#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
+#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
+#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
+#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
/* groupType */
#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001
#define SYSTEM_FLAG_CR_NTDS_DOMAIN 0x00000002
#define SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED 0x00000004
#define SYSTEM_FLAG_SCHEMA_BASE_OBJECT 0x00000010
-#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020
+#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020
#define SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE 0x02000000
#define SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE 0x04000000
#define SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME 0x08000000
#define SYSTEM_FLAG_CONFIG_ALLOW_RENAME 0x40000000
#define SYSTEM_FLAG_DISALLOW_DELTE 0x80000000
-#define SEARCH_FLAG_ATTINDEX 0x0000001
-#define SEARCH_FLAG_PDNTATTINDEX 0x0000002
-#define SEARCH_FLAG_ANR 0x0000004
-#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008
-#define SEARCH_FLAG_COPY 0x0000010
-#define SEARCH_FLAG_TUPLEINDEX 0x0000020
-#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040
-#define SEARCH_FLAG_CONFIDENTIAL 0x0000080
-#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100
-#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200
+#define SEARCH_FLAG_ATTINDEX 0x0000001
+#define SEARCH_FLAG_PDNTATTINDEX 0x0000002
+#define SEARCH_FLAG_ANR 0x0000004
+#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008
+#define SEARCH_FLAG_COPY 0x0000010
+#define SEARCH_FLAG_TUPLEINDEX 0x0000020
+#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040
+#define SEARCH_FLAG_CONFIDENTIAL 0x0000080
+#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100
+#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200
#define DS_BEHAVIOR_WIN2000 0
#define DS_BEHAVIOR_WIN2003_INTERIM 1
#define DS_BEHAVIOR_WIN2003 2
#define DS_BEHAVIOR_WIN2008 3
+
+/* Settings for the domainFunctionality attribute in the rootDSE */
+
+#define DS_DOMAIN_FUNCTION_2000 0
+#define DS_DOMAIN_FUCNTION_2003_MIXED 1
+#define DS_DOMAIN_FUNCTION_2003 2
+#define DS_DOMAIN_FUNCTION_2008 3
+
}
NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx)
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF *val /* [in] [unique] */)
{
struct lsa_StorePrivateData r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.name = name;
+ r.in.val = val;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_StorePrivateData, &r);
}
NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx)
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF **val /* [in,out] [ref] */)
{
struct lsa_RetrievePrivateData r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.name = name;
+ r.in.val = val;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, &r);
}
/* Return variables */
+ *val = *r.out.val;
/* Return result */
return r.out.result;
struct policy_handle *handle /* [in] [ref] */,
struct dom_sid2 *dom_sid /* [in] [ref] */);
NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx);
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF *val /* [in] [unique] */);
NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx);
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF **val /* [in,out] [ref] */);
NTSTATUS rpccli_lsa_OpenPolicy2(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *system_name /* [in] [unique,charset(UTF16)] */,
NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct policy_handle *gdi_handle /* [out] [ref] */,
+ struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
WERROR *werror)
{
struct spoolss_CreatePrinterIC r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.devmode_ctr = devmode_ctr;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, &r);
}
/* Return variables */
+ *gdi_handle = *r.out.gdi_handle;
/* Return result */
if (werror) {
NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *gdi_handle /* [in,out] [ref] */,
WERROR *werror)
{
struct spoolss_DeletePrinterIC r;
NTSTATUS status;
/* In parameters */
+ r.in.gdi_handle = gdi_handle;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, &r);
}
/* Return variables */
+ *gdi_handle = *r.out.gdi_handle;
/* Return result */
if (werror) {
WERROR *werror);
NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct policy_handle *gdi_handle /* [out] [ref] */,
+ struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
WERROR *werror);
NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
WERROR *werror);
NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *gdi_handle /* [in,out] [ref] */,
WERROR *werror);
NTSTATUS rpccli_spoolss_AddPrinterConnection(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL=10,
LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL=11,
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL=12,
- LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES=13
+ LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES=13
}
#else
{ __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF}
#define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL ( 10 )
#define LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL ( 11 )
#define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL ( 12 )
-#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES ( 13 )
+#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES ( 13 )
#endif
;
struct lsa_TrustDomainInfoFullInfoInternal full_info_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL)] */
struct lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL)] */
struct lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)] */
- struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)] */
+ struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)] */
}/* [switch_type(lsa_TrustDomInfoEnum)] */;
struct lsa_DATA_BUF_PTR {
struct lsa_StorePrivateData {
+ struct {
+ struct policy_handle *handle;/* [ref] */
+ struct lsa_String *name;/* [ref] */
+ struct lsa_DATA_BUF *val;/* [unique] */
+ } in;
+
struct {
NTSTATUS result;
} out;
struct lsa_RetrievePrivateData {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct lsa_String *name;/* [ref] */
+ struct lsa_DATA_BUF **val;/* [ref] */
+ } in;
+
+ struct {
+ struct lsa_DATA_BUF **val;/* [ref] */
NTSTATUS result;
} out;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL"; break;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL"; break;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL"; break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES"; break;
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES"; break;
}
ndr_print_enum(ndr, name, "ENUM", val, r);
}
NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
break; }
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
NDR_CHECK(ndr_push_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
break; }
NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
break;
default:
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
break; }
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
break; }
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
break;
default:
ndr_print_lsa_TrustDomainInfoFullInfo2Internal(ndr, "full_info2_internal", &r->full_info2_internal);
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
ndr_print_lsa_TrustDomainInfoSupportedEncTypes(ndr, "enc_types", &r->enc_types);
break;
static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int flags, const struct lsa_StorePrivateData *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.name == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.val));
+ if (r->in.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+ }
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
static enum ndr_err_code ndr_pull_lsa_StorePrivateData(struct ndr_pull *ndr, int flags, struct lsa_StorePrivateData *r)
{
+ uint32_t _ptr_val;
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_name_0;
+ TALLOC_CTX *_mem_save_val_0;
if (flags & NDR_IN) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.name);
+ }
+ _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, r->in.val);
+ } else {
+ r->in.val = NULL;
+ }
+ if (r->in.val) {
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, 0);
+ }
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "lsa_StorePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "name", r->in.name);
+ ndr->depth++;
+ ndr_print_lsa_String(ndr, "name", r->in.name);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "val", r->in.val);
+ ndr->depth++;
+ if (r->in.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", r->in.val);
+ }
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr, int flags, const struct lsa_RetrievePrivateData *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.name == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ if (r->in.val == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_unique_ptr(ndr, *r->in.val));
+ if (*r->in.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+ }
}
if (flags & NDR_OUT) {
+ if (r->out.val == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.val));
+ if (*r->out.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+ }
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
static enum ndr_err_code ndr_pull_lsa_RetrievePrivateData(struct ndr_pull *ndr, int flags, struct lsa_RetrievePrivateData *r)
{
+ uint32_t _ptr_val;
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_name_0;
+ TALLOC_CTX *_mem_save_val_0;
+ TALLOC_CTX *_mem_save_val_1;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.name);
+ }
+ _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.val);
+ }
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.val, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, *r->in.val);
+ } else {
+ *r->in.val = NULL;
+ }
+ if (*r->in.val) {
+ _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->in.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.val);
+ *r->out.val = *r->in.val;
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.val);
+ }
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.val, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, *r->out.val);
+ } else {
+ *r->out.val = NULL;
+ }
+ if (*r->out.val) {
+ _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->out.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "lsa_RetrievePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "name", r->in.name);
+ ndr->depth++;
+ ndr_print_lsa_String(ndr, "name", r->in.name);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "val", r->in.val);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "val", *r->in.val);
+ ndr->depth++;
+ if (*r->in.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", *r->in.val);
+ }
+ ndr->depth--;
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "lsa_RetrievePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "val", r->out.val);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "val", *r->out.val);
+ ndr->depth++;
+ if (*r->out.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", *r->out.val);
+ }
+ ndr->depth--;
+ ndr->depth--;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
}
case SAMR_VALIDATION_STATUS_SUCCESS: val = "SAMR_VALIDATION_STATUS_SUCCESS"; break;
case SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE: val = "SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE"; break;
case SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT: val = "SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT"; break;
+ case SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED: val = "SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED"; break;
case SAMR_VALIDATION_STATUS_BAD_PASSWORD: val = "SAMR_VALIDATION_STATUS_BAD_PASSWORD"; break;
case SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT: val = "SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT"; break;
case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT: val = "SAMR_VALIDATION_STATUS_PWD_TOO_SHORT"; break;
case SAMR_VALIDATION_STATUS_PWD_TOO_LONG: val = "SAMR_VALIDATION_STATUS_PWD_TOO_LONG"; break;
case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH: val = "SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH"; break;
case SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT: val = "SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT"; break;
+ case SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR: val = "SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR"; break;
}
ndr_print_enum(ndr, name, "ENUM", val, r);
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
ndr_print_uint32(ndr, "major", r->major);
ndr_print_uint32(ndr, "minor", r->minor);
ndr_print_uint32(ndr, "build", r->build);
- ndr_print_uint32(ndr, "unknown", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown);
+ ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
ndr_print_string(ndr, "extra_string", r->extra_string);
ndr->depth--;
}
}
ndr->flags = _flags_save_string;
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown2));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_major));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_minor));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->suite_mask));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->product_type));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->reserved));
}
if (ndr_flags & NDR_BUFFERS) {
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
}
ndr->flags = _flags_save_string;
}
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_major));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_minor));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->suite_mask));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->product_type));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->reserved));
}
if (ndr_flags & NDR_BUFFERS) {
}
ndr_print_uint32(ndr, "major", r->major);
ndr_print_uint32(ndr, "minor", r->minor);
ndr_print_uint32(ndr, "build", r->build);
- ndr_print_uint32(ndr, "unknown1", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown1);
+ ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
ndr_print_string(ndr, "extra_string", r->extra_string);
- ndr_print_uint32(ndr, "unknown2", r->unknown2);
- ndr_print_uint32(ndr, "unknown3", r->unknown3);
+ ndr_print_uint16(ndr, "service_pack_major", r->service_pack_major);
+ ndr_print_uint16(ndr, "service_pack_minor", r->service_pack_minor);
+ ndr_print_uint16(ndr, "suite_mask", r->suite_mask);
+ ndr_print_uint8(ndr, "product_type", r->product_type);
+ ndr_print_uint8(ndr, "reserved", r->reserved);
ndr->depth--;
}
static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_CreatePrinterIC *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.devmode_ctr == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
}
if (flags & NDR_OUT) {
+ if (r->out.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
static enum ndr_err_code ndr_pull_spoolss_CreatePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_CreatePrinterIC *r)
{
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_gdi_handle_0;
+ TALLOC_CTX *_mem_save_devmode_ctr_0;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.devmode_ctr);
+ }
+ _mem_save_devmode_ctr_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.devmode_ctr, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_ctr_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ ZERO_STRUCTP(r->out.gdi_handle);
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "spoolss_CreatePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "devmode_ctr", r->in.devmode_ctr);
+ ndr->depth++;
+ ndr_print_spoolss_DevmodeContainer(ndr, "devmode_ctr", r->in.devmode_ctr);
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "spoolss_CreatePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth--;
ndr_print_WERROR(ndr, "result", r->out.result);
ndr->depth--;
}
static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_DeletePrinterIC *r)
{
if (flags & NDR_IN) {
+ if (r->in.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
}
if (flags & NDR_OUT) {
+ if (r->out.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
static enum ndr_err_code ndr_pull_spoolss_DeletePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_DeletePrinterIC *r)
{
+ TALLOC_CTX *_mem_save_gdi_handle_0;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ *r->out.gdi_handle = *r->in.gdi_handle;
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "spoolss_DeletePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->in.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->in.gdi_handle);
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "spoolss_DeletePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth--;
ndr_print_WERROR(ndr, "result", r->out.result);
ndr->depth--;
}
SAMR_VALIDATION_STATUS_SUCCESS=0,
SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE=1,
SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT=2,
+ SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED=3,
SAMR_VALIDATION_STATUS_BAD_PASSWORD=4,
SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT=5,
SAMR_VALIDATION_STATUS_PWD_TOO_SHORT=6,
SAMR_VALIDATION_STATUS_PWD_TOO_LONG=7,
SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH=8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9
+ SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9,
+ SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR=10
}
#else
{ __donnot_use_enum_samr_ValidationStatus=0x7FFFFFFF}
#define SAMR_VALIDATION_STATUS_SUCCESS ( 0 )
#define SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE ( 1 )
#define SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT ( 2 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED ( 3 )
#define SAMR_VALIDATION_STATUS_BAD_PASSWORD ( 4 )
#define SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT ( 5 )
#define SAMR_VALIDATION_STATUS_PWD_TOO_SHORT ( 6 )
#define SAMR_VALIDATION_STATUS_PWD_TOO_LONG ( 7 )
#define SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH ( 8 )
#define SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT ( 9 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR ( 10 )
#endif
;
uint32_t major;
uint32_t minor;
uint32_t build;
- uint32_t unknown;/* [value(2)] */
+ uint32_t platform_id;/* [value(2)] */
const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
}/* [gensize,public] */;
uint32_t major;
uint32_t minor;
uint32_t build;
- uint32_t unknown1;/* [value(2)] */
+ uint32_t platform_id;/* [value(2)] */
const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
- uint32_t unknown2;
- uint32_t unknown3;
+ uint16_t service_pack_major;
+ uint16_t service_pack_minor;
+ uint16_t suite_mask;
+ uint8_t product_type;
+ uint8_t reserved;
}/* [gensize,public] */;
union spoolss_PrinterData {
struct spoolss_CreatePrinterIC {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct spoolss_DevmodeContainer *devmode_ctr;/* [ref] */
+ } in;
+
+ struct {
+ struct policy_handle *gdi_handle;/* [ref] */
WERROR result;
} out;
struct spoolss_DeletePrinterIC {
struct {
+ struct policy_handle *gdi_handle;/* [ref] */
+ } in;
+
+ struct {
+ struct policy_handle *gdi_handle;/* [ref] */
WERROR result;
} out;
NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.val = r->in.val;
r->out.result = _lsa_RetrievePrivateData(p, r);
if (p->rng_fault_state) {
case NDR_LSA_RETRIEVEPRIVATEDATA: {
struct lsa_RetrievePrivateData *r = (struct lsa_RetrievePrivateData *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.val = r->in.val;
r->out.result = _lsa_RetrievePrivateData(cli->pipes_struct, r);
return NT_STATUS_OK;
}
NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = talloc_zero(r, struct policy_handle);
+ if (r->out.gdi_handle == NULL) {
+ talloc_free(r);
+ return false;
+ }
+
r->out.result = _spoolss_CreatePrinterIC(p, r);
if (p->rng_fault_state) {
NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = r->in.gdi_handle;
r->out.result = _spoolss_DeletePrinterIC(p, r);
if (p->rng_fault_state) {
case NDR_SPOOLSS_CREATEPRINTERIC: {
struct spoolss_CreatePrinterIC *r = (struct spoolss_CreatePrinterIC *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = talloc_zero(mem_ctx, struct policy_handle);
+ if (r->out.gdi_handle == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
r->out.result = _spoolss_CreatePrinterIC(cli->pipes_struct, r);
return NT_STATUS_OK;
}
case NDR_SPOOLSS_DELETEPRINTERIC: {
struct spoolss_DeletePrinterIC *r = (struct spoolss_DeletePrinterIC *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = r->in.gdi_handle;
r->out.result = _spoolss_DeletePrinterIC(cli->pipes_struct, r);
return NT_STATUS_OK;
}
WERROR frsapi_IsPathReplicated(
[in,unique] [string,charset(UTF16)] uint16 *path,
[in] frsapi_ReplicaSetType replica_set_type,
- [out] uint32 *unknown1,
- [out] uint32 *unknown2,
- [out] uint32 *unknown3,
+ [out] uint32 *replicated,
+ [out] uint32 *primary,
+ [out] uint32 *root,
[out] GUID *replica_set_guid
);
/****************/
/* Function 0x09 */
- [todo] void FRSAPI_WRITER_COMMAND();
+ typedef [v1_enum] enum {
+ FRSAPI_WRITER_COMMAND_FREEZE = 0x00000001,
+ FRSAPI_WRITER_COMMAND_THAW = 0x00000002
+ } frsapi_WriterCommandsValues;
+
+ WERROR frsapi_WriterCommand(
+ [in] frsapi_WriterCommandsValues command
+ );
/****************/
/* Function 0x0a */
/* not supported before w2k3 sp2 */
WERROR frsapi_ForceReplication(
- [in,unique] GUID *guid1,
- [in,unique] GUID *guid2,
- [in,unique] [charset(UTF16),string] uint16 *replica_set,
- [in,unique] [charset(UTF16),string] uint16 *partner_name
+ [in,unique] GUID *replica_set_guid,
+ [in,unique] GUID *connection_guid,
+ [in,unique] [charset(UTF16),string] uint16 *replica_set_name,
+ [in,unique] [charset(UTF16),string] uint16 *partner_dns_name
);
}
version(1.1),
endpoint("ncacn_ip_tcp:", "ncalrpc:"),
helpstring("File Replication Service"),
+ helper("../librpc/ndr/ndr_frsrpc.h"),
pointer_default(unique)
]
interface frsrpc
/*****************/
/* Function 0x00 */
- /* TAG:3 this TLV contains a GUID and the name of the server sending
- * the call
- */
typedef struct {
- [subcontext(4)] GUID unknown1;
- [subcontext(4)] nstring source_server;
- } frsrpc_FrsSendCommPktChunkDataSSRV;
+ [subcontext(4)] GUID guid;
+ [subcontext(4)] nstring name;
+ } frsrpc_CommPktChunkGuidName;
- /* TAG:4 this TLV contains a GUID and the name of the destination
- * server the PDU is sent to
- */
typedef struct {
- [subcontext(4)] GUID unknown1;
- [subcontext(4)] nstring dest_server;
- } frsrpc_FrsSendCommPktChunkDataDSRV;
+ hyper vsn;
+ GUID guid;
+ } frsrpc_CommPktGSVN;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CO_FLAG_ABORT_CO = 0x00000001,
+ FRSRPC_CO_FLAG_VV_ACTIVATED = 0x00000002,
+ FRSRPC_CO_FLAG_CONTENT_CMD = 0x00000004,
+ FRSRPC_CO_FLAG_LOCATION_CMD = 0x00000008,
+ FRSRPC_CO_FLAG_ONLIST = 0x00000010,
+ FRSRPC_CO_FLAG_LOCALCO = 0x00000020,
+ FRSRPC_CO_FLAG_RETRY = 0x00000040,
+ FRSRPC_CO_FLAG_OUT_OF_ORDER = 0x00000200,
+ FRSRPC_CO_FLAG_NEW_FILE = 0x00000400,
+ FRSRPC_CO_FLAG_CONTROL = 0x00001000,
+ FRSRPC_CO_FLAG_DIRECTED_CO = 0x00002000,
+ FRSRPC_CO_FLAG_VVJOIN_TO_ORIG = 0x00040000,
+ FRSRPC_CO_FLAG_SKIP_ORIG_REC_C = 0x00100000,
+ FRSRPC_CO_FLAG_MOVEIN_GEN = 0x00200000,
+ FRSRPC_CO_FLAG_MORPH_GEN_HEAD = 0x00400000,
+ FRSRPC_CO_FLAG_JUST_OID_RESET = 0x00800000,
+ FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+ FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+ FRSRPC_CO_FLAG_SKIP_VV_UPDATE = 0x02000000
+ } frsrpc_CommPktCoCmdFlags;
+
+ const uint32 FRSRPC_CO_IFLAG_NONE = 0x0000000;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CO_IFLAG_VVRETIRE_EXEC = 0x00000001,
+ FRSRPC_CO_IFLAG_CO_ABORT = 0x00000002,
+ FRSRPC_CO_IFLAG_DIR_ENUM_PENDING= 0x00000004
+ } frsrpc_CommPktCoCmdIFlags;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_STATUS_CO_ENTERED_LOG = 0x00000000,
+ FRSRPC_CO_STATUS_ALLOC_STAGING_LOCAL_CO = 0x00000001,
+ FRSRPC_CO_STATUS_LOCAL_CO_STAGING_STARTED = 0x00000002,
+ FRSRPC_CO_STATUS_LOCAL_CO_STAGING_COMPLETED = 0x00000003,
+ FRSRPC_CO_STATUS_WAIT_RETRY_LOCAL_CO_STAGING = 0x00000004,
+ FRSRPC_CO_STATUS_ALLOC_STAGING_REMOTE_CO = 0x00000005,
+ FRSRPC_CO_STATUS_REMOTE_CO_STAGING_STARTED = 0x00000006,
+ FRSRPC_CO_STATUS_REMOTE_CO_STAGING_COMPLETED = 0x00000007,
+ FRSRPC_CO_STATUS_WAIT_RETRY_REMOTE_CO_STAGING = 0x00000008,
+ FRSRPC_CO_STATUS_FILE_INSTALL_REQUESTED = 0x00000009,
+ FRSRPC_CO_STATUS_FILE_INSTALL_STARTED = 0x0000000A,
+ FRSRPC_CO_STATUS_FILE_INSTALL_COMPLETED = 0x0000000B,
+ FRSRPC_CO_STATUS_FILE_INSTALL_WAIT_RETRY = 0x0000000C,
+ FRSRPC_CO_STATUS_FILE_INSTALL_RETRYING = 0x0000000D,
+ FRSRPC_CO_STATUS_FILE_INSTALL_RENAME_RETRYING = 0x0000000E,
+ FRSRPC_CO_STATUS_FILE_INSTALL_DELETE_RETRYING = 0x0000000F,
+ FRSRPC_CO_STATUS_CO_RECYCLED_FOR_ENUM = 0x00000013,
+ FRSRPC_CO_STATUS_REQUEST_OUTBOUND_PROPAGATION = 0x00000014,
+ FRSRPC_CO_STATUS_REQUEST_ACCEPTED_OUTBOUND_LOG = 0x00000015,
+ FRSRPC_CO_STATUS_DB_STATE_UPDATE_STARTED = 0x00000016,
+ FRSRPC_CO_STATUS_DB_STATE_UPDATE_COMPLETED = 0x00000017,
+ FRSRPC_CO_STATUS_CO_ABORTED = 0x00000018
+ } frsrpc_CommPktCoCmdStatus;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CONTENT_REASON_DATA_OVERWRITE = 0x00000001,
+ FRSRPC_CONTENT_REASON_DATA_EXTEND = 0x00000002,
+ FRSRPC_CONTENT_REASON_DATA_TRUNCATION = 0x00000004,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_OVERWRITE = 0x00000010,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_EXTEND = 0x00000020,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_TRUNCATION = 0x00000040,
+ FRSRPC_CONTENT_REASON_FILE_CREATE = 0x00000100,
+ FRSRPC_CONTENT_REASON_FILE_DELETE = 0x00000200,
+ FRSRPC_CONTENT_REASON_EA_CHANGE = 0x00000400,
+ FRSRPC_CONTENT_REASON_SECURITY_CHANGE = 0x00000800,
+ FRSRPC_CONTENT_REASON_OLD_NAME = 0x00001000,
+ FRSRPC_CONTENT_REASON_NEW_NAME = 0x00002000,
+ FRSRPC_CONTENT_REASON_BASIC_INFO_CHANGE = 0x00004000,
+ FRSRPC_CONTENT_REASON_COMPRESSION_CHANGE = 0x00020000
+ } frsrpc_CommPktCoCmdContentCmd;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_LOCATION_FILE_CREATE = 0x00000000,
+ FRSRPC_CO_LOCATION_DIR_CREATE = 0x00000000 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_DELETE = 0x00000002,
+ FRSRPC_CO_LOCATION_DIR_DELETE = 0x00000002 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEIN = 0x00000004,
+ FRSRPC_CO_LOCATION_DIR_MOVEIN = 0x00000004 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEIN2 = 0x00000006,
+ FRSRPC_CO_LOCATION_DIR_MOVEIN2 = 0x00000006 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEOUT = 0x00000008,
+ FRSRPC_CO_LOCATION_DIR_MOVEOUT = 0x00000008 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVERS = 0x0000000a,
+ FRSRPC_CO_LOCATION_DIR_MOVERS = 0x0000000a | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEDIR = 0x0000000c,
+ FRSRPC_CO_LOCATION_DIR_MOVEDIR = 0x0000000c | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_NO_CMD = 0x0000000e,
+ FRSRPC_CO_LOCATION_DIR_NO_CMD = 0x0000000e | 0x00000001
+ } frsrpc_CommPktCoCmdLocationCmd;
- /* TAG:18 this TLV contains a timestamp
- */
typedef struct {
- [subcontext(4)] NTTIME time;
- } frsrpc_FrsSendCommPktChunkDataTS;
+ uint32 sequence_number;
+ frsrpc_CommPktCoCmdFlags flags;
+ frsrpc_CommPktCoCmdIFlags iflags;
+ frsrpc_CommPktCoCmdStatus status;
+ frsrpc_CommPktCoCmdContentCmd content_cmd;
+ frsrpc_CommPktCoCmdLocationCmd location_cmd;
+ uint32 file_attributes;
+ uint32 file_version_number;
+ uint32 partern_ack_sequence_number;
+ [value(0)] uint32 not_used;
+ hyper file_size;
+ hyper file_offset;
+ hyper frs_vsn;
+ hyper file_usn;
+ hyper jrnl_usn;
+ hyper jrnl_first_usn;
+ uint32 original_replica_num;
+ uint32 new_replica_num;
+ GUID change_order_guid;
+ GUID originator_guid;
+ GUID file_guid;
+ GUID old_parent_guid;
+ GUID new_parent_guid;
+ GUID connection_guid;
+ hyper ack_version;
+ [value(0)] hyper spare2ul1;
+ [value(0)] hyper spare1guid_p1;
+ [value(0)] hyper spare1guid_p2;
+ [value(0)] hyper spare2guid_p1;
+ [value(0)] hyper spare3guid_p2;
+ [value(0)] uint32 spare1wcs;
+ [value(0)] uint32 spare2wcs;
+ [value(0)] uint32 extension;
+ [value(0)] uint32 spare2bin;
+ NTTIME event_time;
+ [value(2*strlen_m(file_name))] uint16 file_name_length;
+#define FRSRPC_MAX_PATH 260
+ [charset(UTF16)] uint16 file_name[FRSRPC_MAX_PATH+1];
+ [value(0)] uint8 padding1;
+ [value(0)] uint8 padding2;
+ [value(0)] uint8 padding3;
+ [value(0)] uint8 padding4;
+ } frsrpc_CommPktChangeOrderCommand;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_DATA_EXTENSION_TERMINATOR = 0x00000000,
+ FRSRPC_DATA_EXTENSION_MD5_CHECKSUM = 0x00000001,
+ FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT = 0x00000002
+ } frsrpc_CommPktDataExtensionType;
+ typedef [flag(NDR_PAHEX)] struct {
+ [value(0x00000018)] uint32 prefix_size;
+ [value(FRSRPC_DATA_EXTENSION_MD5_CHECKSUM)]
+ frsrpc_CommPktDataExtensionType prefix_type;
+ uint8 data[16];
+ } frsrpc_CommPktDataExtensionChecksum;
typedef struct {
- uint32 unknown1;
- } frsrpc_FrsSendCommPktChunkDataA;
+ [value(0x00000018)] uint32 prefix_size;
+ [value(FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT)]
+ frsrpc_CommPktDataExtensionType prefix_type;
+ uint32 count;
+ [value(0)] uint32 not_used;
+ NTTIME first_try_time;
+ } frsrpc_CommPktDataExtensionRetryTimeout;
+
+ typedef [flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K = 0x0000,
+ FRSRPC_CO_RECORD_EXTENSION_VERSION_1 = 0x0001
+ } frsrpc_CommPktCoRecordExtensionMajor;
typedef struct {
- uint32 unknown1;
- GUID unknown2;
- [subcontext(4)] nstring unknown3;
- } frsrpc_FrsSendCommPktChunkDataB;
+ [value(0x00000028)] uint32 field_size;
+ [value(FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K)]
+ frsrpc_CommPktCoRecordExtensionMajor major;
+ [value(0x0001)] uint16 offset_count;
+ [value(0x00000010)] uint32 offset;
+ [value(0)] uint32 offset_last;
+ frsrpc_CommPktDataExtensionChecksum data_checksum;
+ } frsrpc_CommPktCoRecordExtensionWin2k;
typedef struct {
- uint32 unknown1;
- GUID unknown2;
- } frsrpc_FrsSendCommPktChunkDataC;
+ [value(0x00000048)] uint32 field_size;
+ frsrpc_CommPktCoRecordExtensionMajor major;
+ [value(0x0002)] uint16 offset_count;
+ [value(0x00000018)] uint32 offset0;
+ [value(0x00000030)] uint32 offset1;/*TODO: is this correct??? */
+ [value(0)] uint32 offset_last;
+ [value(0)] uint32 not_used;
+ frsrpc_CommPktDataExtensionChecksum data_checksum;
+ frsrpc_CommPktDataExtensionRetryTimeout data_retry_timeout;
+ } frsrpc_CommPktChangeOrderRecordExtension;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_COMMAND_REMOTE_CO = 0x00000218,
+ FRSRPC_COMMAND_RECEIVING_STATE = 0x00000238,
+ FRSRPC_COMMAND_REMOTE_CO_DONE = 0x00000250,
+ FRSRPC_COMMAND_ABORT_FETCH = 0x00000246,
+ FRSRPC_COMMAND_RETRY_FETCH = 0x00000244,
+ FRSRPC_COMMAND_NEED_JOIN = 0x00000121,
+ FRSRPC_COMMAND_START_JOIN = 0x00000122,
+ FRSRPC_COMMAND_JOINING = 0x00000130,
+ FRSRPC_COMMAND_JOINED = 0x00000128,
+ FRSRPC_COMMAND_UNJOIN_REMOTE = 0x00000148,
+ FRSRPC_COMMAND_WJOIN_DONE = 0x00000136,
+ FRSRPC_COMMAND_SEND_STAGE = 0x00000228
+ } frsrpc_CommPktCommand;
+
+ typedef [flag(NDR_PAHEX)] enum {
+ FRSRPC_COMM_PKT_CHUNK_BOP = 0x0001,
+ FRSRPC_COMM_PKT_CHUNK_COMMAND = 0x0002,
+ FRSRPC_COMM_PKT_CHUNK_TO = 0x0003,
+ FRSRPC_COMM_PKT_CHUNK_FROM = 0x0004,
+ FRSRPC_COMM_PKT_CHUNK_REPLICA = 0x0005,
+ FRSRPC_COMM_PKT_CHUNK_CONNECTION = 0x0008,
+ FRSRPC_COMM_PKT_CHUNK_JOIN_GUID = 0x0006,
+ FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME = 0x0012,
+
+ FRSRPC_COMM_PKT_CHUNK_VVECTOR = 0x0007,
+ FRSRPC_COMM_PKT_CHUNK_JOIN_TIME = 0x0011,
+ FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID = 0x0014,
+ FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID = 0x0018,
+
+ FRSRPC_COMM_PKT_CHUNK_BLOCK = 0x0009,
+ FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE = 0x000A,
+ FRSRPC_COMM_PKT_CHUNK_FILE_SIZE = 0x000B,
+ FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET = 0x000C,
+ FRSRPC_COMM_PKT_CHUNK_GVSN = 0x000E,
+ FRSRPC_COMM_PKT_CHUNK_CO_GUID = 0x000F,
+ FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER = 0x0010,
+
+ FRSRPC_COMM_PKT_CHUNK_REMOTE_CO = 0x000D,
+ FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K = 0x0016,
+ FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2 = 0x0017,
+
+ FRSRPC_COMM_PKT_CHUNK_EOP = 0x0013
+ } frsrpc_CommPktChunkType;
typedef [nodiscriminant] union {
[default,flag(NDR_REMAINING)] DATA_BLOB blob;
- [case(1)] frsrpc_FrsSendCommPktChunkDataA A;
- [case(2)] frsrpc_FrsSendCommPktChunkDataA A;
- [case(3)] frsrpc_FrsSendCommPktChunkDataSSRV SSRV;
- [case(4)] frsrpc_FrsSendCommPktChunkDataDSRV DSRV;
- [case(5)] frsrpc_FrsSendCommPktChunkDataB B;
- [case(8)] frsrpc_FrsSendCommPktChunkDataB B;
- [case(6)] frsrpc_FrsSendCommPktChunkDataC C;
- [case(18)] frsrpc_FrsSendCommPktChunkDataTS TS;
- [case(19)] frsrpc_FrsSendCommPktChunkDataA A;
- } frsrpc_FrsSendCommPktChunkData;
+ [case(FRSRPC_COMM_PKT_CHUNK_BOP)]
+ [value(0)] uint32 bop;
+ [case(FRSRPC_COMM_PKT_CHUNK_COMMAND)]
+ frsrpc_CommPktCommand command;
+ [case(FRSRPC_COMM_PKT_CHUNK_TO)]
+ frsrpc_CommPktChunkGuidName to;
+ [case(FRSRPC_COMM_PKT_CHUNK_FROM)]
+ frsrpc_CommPktChunkGuidName from;
+ [case(FRSRPC_COMM_PKT_CHUNK_REPLICA)]
+ frsrpc_CommPktChunkGuidName replica;
+ [case(FRSRPC_COMM_PKT_CHUNK_CONNECTION)]
+ frsrpc_CommPktChunkGuidName connection;
+ [case(FRSRPC_COMM_PKT_CHUNK_JOIN_GUID)][subcontext(4)]
+ GUID join_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME)]
+ NTTIME last_join_time;
+ [case(FRSRPC_COMM_PKT_CHUNK_VVECTOR)][subcontext(4)]
+ frsrpc_CommPktGSVN vvector;
+ [case(FRSRPC_COMM_PKT_CHUNK_JOIN_TIME)][subcontext(4)]
+ NTTIME join_time;
+ [case(FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID)][subcontext(4)]
+ GUID replica_version_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID)]
+ GUID compression_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_BLOCK)]
+ [flag(NDR_REMAINING)] DATA_BLOB block;
+ [case(FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE)]
+ hyper block_size;
+ [case(FRSRPC_COMM_PKT_CHUNK_FILE_SIZE)]
+ hyper file_size;
+ [case(FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET)]
+ hyper file_offset;
+ [case(FRSRPC_COMM_PKT_CHUNK_GVSN)][subcontext(4)]
+ frsrpc_CommPktGSVN gvsn;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_GUID)][subcontext(4)]
+ GUID co_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER)]
+ uint32 co_sequnence_number;
+ [case(FRSRPC_COMM_PKT_CHUNK_REMOTE_CO)][subcontext(4)]
+ frsrpc_CommPktChangeOrderCommand remote_co;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K)][subcontext(4)]
+ frsrpc_CommPktCoRecordExtensionWin2k co_ext_win2k;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2)][subcontext(4)]
+ frsrpc_CommPktChangeOrderRecordExtension co_extension2;
+ [case(FRSRPC_COMM_PKT_CHUNK_EOP)]
+ [value(0xFFFFFFFF)] uint32 bop;
+ } frsrpc_CommPktChunkData;
- typedef struct {
- uint16 type;
- [subcontext(4),switch_is(type)] frsrpc_FrsSendCommPktChunkData data;
- } frsrpc_FrsSendCommPktChunk;
-
- typedef [flag(NDR_NOALIGN)] struct {
- frsrpc_FrsSendCommPktChunk chunk1;
- frsrpc_FrsSendCommPktChunk chunk2;
- frsrpc_FrsSendCommPktChunk chunk3;
- frsrpc_FrsSendCommPktChunk chunk4;
- frsrpc_FrsSendCommPktChunk chunk5;
- frsrpc_FrsSendCommPktChunk chunk6;
- frsrpc_FrsSendCommPktChunk chunk7;
- frsrpc_FrsSendCommPktChunk chunk8;
- frsrpc_FrsSendCommPktChunk chunk9;
- } frsrpc_FrsSendCommPktChunkCtr;
+ typedef [public,flag(NDR_NOALIGN)] struct {
+ frsrpc_CommPktChunkType type;
+ [subcontext(4),switch_is(type)] frsrpc_CommPktChunkData data;
+ } frsrpc_CommPktChunk;
+
+ typedef [nopull,nopush,flag(NDR_NOALIGN)] struct {
+ uint32 num_chunks; /* this doesn't appear on the wire */
+ frsrpc_CommPktChunk chunks[num_chunks];
+ } frsrpc_CommPktChunkCtr;
+
+ typedef [v1_enum] enum {
+ FRSRPC_COMM_PKT_MAJOR_0 = 0x00000000
+ } frsrpc_CommPktMajor;
+
+ typedef [v1_enum] enum {
+ FRSRPC_COMM_PKT_MINOR_0 = 0x00000000,
+ FRSRPC_COMM_PKT_MINOR_1 = 0x00000001,
+ FRSRPC_COMM_PKT_MINOR_2 = 0x00000002,
+ FRSRPC_COMM_PKT_MINOR_3 = 0x00000003,
+ FRSRPC_COMM_PKT_MINOR_4 = 0x00000004,
+ FRSRPC_COMM_PKT_MINOR_5 = 0x00000005,
+ FRSRPC_COMM_PKT_MINOR_6 = 0x00000006,
+ FRSRPC_COMM_PKT_MINOR_7 = 0x00000007,
+ FRSRPC_COMM_PKT_MINOR_8 = 0x00000008,
+ FRSRPC_COMM_PKT_MINOR_9 = 0x00000009
+ } frsrpc_CommPktMinor;
typedef struct {
- uint32 unknown1;
- uint32 unknown2;
- uint32 unknown3;
- uint32 unknown4;
- uint32 tlv_size;
- uint32 unknown6;
- uint32 unknown7; /* This may be a UNIQUE pointer? */
- uint32 unknown8;
- uint32 unknown9;
- /*
- * The format of this blob is this a concatenation
- * of TLVs which are not really NDR encoded.
- *
- * The individual TLVs are encoded as :
- * struct {
- * uint16 type;
- * [subcontext(4),switch_is(type)] chunk_data data;
- * } chunk;
- *
- * some of the chunk are like this:
- *
- * struct {
- * uint32 unknown; // 0x00000010
- * struct GUID guid;
- * lstring string;
- * } ...;
- *
- *
- * The tags are (might be) :
- * 3: Source server sending the PDU
- * 4: Destination server the PDU is sent to
- * 18: Timestamp
- *
- */
- [subcontext(4)/*,size_is(tlv_size)*/] frsrpc_FrsSendCommPktChunkCtr *chunks;
- uint32 unknown10;
- uint32 unknown11;
+ frsrpc_CommPktMajor major;
+ frsrpc_CommPktMinor minor;
+ [value(1)] uint32 cs_id;
+ [value(pkt_len+12)] uint32 memory_len;
+ [value(ndr_size_frsrpc_CommPktChunkCtr(r->ctr,
+ ndr->iconv_convenience, ndr->flags))]
+ [range(0, 262144)]
+ uint32 pkt_len;
+ [value(0)] uint32 upk_len;
+ [subcontext(4),subcontext_size(pkt_len)]
+ frsrpc_CommPktChunkCtr *ctr;
+ [value(0)] uint32 data_name;
+ [value(0)] uint32 data_handle;
} frsrpc_FrsSendCommPktReq;
WERROR frsrpc_FrsSendCommPkt(
/*****************/
/* Function 0x02 */
- [todo] void FRSRPC_START_PROMOTION_PARENT();
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_PARENT_AUTH_LEVEL_ENCRYPTED_KERBEROS = 0x00000000,
+ FRSRPC_PARENT_AUTH_LEVEL_NO_AUTHENTICATION = 0x00000001
+ } frsrpc_PartnerAuthLevel;
+
+ WERROR frsrpc_FrsStartPromotionParent(
+ [in,unique,string,charset(UTF16)] uint16 *parent_account,
+ [in,unique,string,charset(UTF16)] uint16 *parent_password,
+ [in,unique,string,charset(UTF16)] uint16 *replica_set_name,
+ [in,unique,string,charset(UTF16)] uint16 *replica_set_type,
+ [in,unique,string,charset(UTF16)] uint16 *connection_name,
+ [in,unique,string,charset(UTF16)] uint16 *partner_name,
+ [in,unique,string,charset(UTF16)] uint16 *partner_princ_name,
+ [in] frsrpc_PartnerAuthLevel partner_auth_level,
+ [in,value(16),range(16,16)] uint32 __ndr_guid_size,
+ [in,unique,subcontext(4),subcontext_size(16)]
+ GUID *connection_guid,
+ [in,unique,subcontext(4),subcontext_size(16)]
+ GUID *partner_guid,
+ [in,out,unique,subcontext(4),subcontext_size(16)]
+ GUID *parent_guid
+ );
/*****************/
/* Function 0x03 */
--- /dev/null
+#include "idl_types.h"
+
+import "misc.idl";
+
+[
+ uuid("897e2e5f-93f3-4376-9c9c-fd2277495c27"),
+ version(1.0),
+ endpoint("ncacn_ip_tcp:", "ncalrpc:"),
+ helpstring("File Replication Service DFS-R"),
+ pointer_default(unique)
+]
+interface frstrans
+{
+ /*****************/
+ /* Function 0x00 */
+ [todo] void FRSTRANS_CHECK_CONNECTIVITY();
+
+ /*****************/
+ /* Function 0x01 */
+ [todo] void FRSTRANS_ESTABLISH_CONNECTION();
+
+ /*****************/
+ /* Function 0x02 */
+ [todo] void FRSTRANS_ESTABLISH_SESSION();
+
+ /*****************/
+ /* Function 0x03 */
+ [todo] void FRSTRANS_REQUEST_UPDATES();
+
+ /*****************/
+ /* Function 0x04 */
+ [todo] void FRSTRANS_REQUEST_VERSION_VECTOR();
+
+ /*****************/
+ /* Function 0x05 */
+ [todo] void FRSTRANS_ASYNC_POLL();
+
+ /*****************/
+ /* Function 0x06 */
+ [todo] void FRSTRANS_REQUEST_RECORDS();
+
+ /*****************/
+ /* Function 0x07 */
+ [todo] void FRSTRANS_UPDATE_CANCEL();
+
+ /*****************/
+ /* Function 0x08 */
+ [todo] void FRSTRANS_RAW_GET_FILE_DATA();
+
+ /*****************/
+ /* Function 0x09 */
+ [todo] void FRSTRANS_RDC_GET_SIGNATURES();
+
+ /*****************/
+ /* Function 0x0a */
+ [todo] void FRSTRANS_RDC_PUSH_SOURCE_NEEDS();
+
+ /*****************/
+ /* Function 0x0b */
+ [todo] void FRSTRANS_RDC_GET_FILE_DATA();
+
+ /*****************/
+ /* Function 0x0c */
+ [todo] void FRSTRANS_RDC_CLOSE();
+
+ /*****************/
+ /* Function 0x0d */
+ [todo] void FRSTRANS_INITIALIZE_FILE_TRANSFER_ASYNC();
+
+ /*****************/
+ /* Function 0x0e */
+ [todo] void FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE();
+
+ /* The following functions are new in Windows 2008 */
+
+ /*****************/
+ /* Function 0x0f */
+ [todo] void FRSTRANS_RAW_GET_FILE_DATA_ASYNC();
+
+ /*****************/
+ /* Function 0x10 */
+ [todo] void FRSTRANS_RDC_GET_FILE_DATA_ASYNC();
+}
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL = 10,
LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL = 11,
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL = 12,
- LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES = 13
+ LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES = 13
} lsa_TrustDomInfoEnum;
typedef [public,bitmap32bit] bitmap {
lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;
[case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)]
lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;
- [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)]
+ [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)]
lsa_TrustDomainInfoSupportedEncTypes enc_types;
} lsa_TrustedDomainInfo;
);
/* Function: 0x2a */
- [todo] NTSTATUS lsa_StorePrivateData();
- /* Function: 0x2b */
- [todo] NTSTATUS lsa_RetrievePrivateData();
+ NTSTATUS lsa_StorePrivateData(
+ [in] policy_handle *handle,
+ [in,ref] lsa_String *name,
+ [in,unique] lsa_DATA_BUF *val
+ );
+ /* Function: 0x2b */
+ NTSTATUS lsa_RetrievePrivateData(
+ [in] policy_handle *handle,
+ [in,ref] lsa_String *name,
+ [in,out,ref] lsa_DATA_BUF **val
+ );
/**********************/
/* Function: 0x2c */
SAMR_VALIDATION_STATUS_SUCCESS = 0,
SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
+ SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED = 3,
SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
+ SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9,
+ SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR = 10
} samr_ValidationStatus;
typedef struct {
uint32 major;
uint32 minor;
uint32 build;
- [value(2)] uint32 unknown;
+ [value(2)] uint32 platform_id;
[subcontext(0),subcontext_size(256)] nstring extra_string;
} spoolss_OSVersion;
uint32 major;
uint32 minor;
uint32 build;
- [value(2)] uint32 unknown1;
+ [value(2)] uint32 platform_id;
[subcontext(0),subcontext_size(256)] nstring extra_string;
- uint32 unknown2;/* service pack number? I saw 0 from w2k3 and 1 from winxp sp1*/
- uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */
+ uint16 service_pack_major;
+ uint16 service_pack_minor;
+ uint16 suite_mask;
+ uint8 product_type;
+ uint8 reserved;
} spoolss_OSVersionEx;
typedef [nodiscriminant,public,gensize] union {
/******************/
/* Function: 0x28 */
- [todo] WERROR spoolss_CreatePrinterIC(
+ WERROR spoolss_CreatePrinterIC(
+ [in,ref] policy_handle *handle,
+ [out,ref] policy_handle *gdi_handle,
+ [in,ref] spoolss_DevmodeContainer *devmode_ctr
);
/******************/
/******************/
/* Function: 0x2a */
- [todo] WERROR spoolss_DeletePrinterIC(
+ WERROR spoolss_DeletePrinterIC(
+ [in,out,ref] policy_handle *gdi_handle
);
/******************/
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ helper routines for FRSRPC marshalling
+
+ Copyright (C) Stefan (metze) Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_frsrpc.h"
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+ int ndr_flags,
+ const struct frsrpc_CommPktChunkCtr *r)
+{
+ uint32_t cntr_chunks_0;
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 2));
+ for (cntr_chunks_0 = 0; cntr_chunks_0 < r->num_chunks; cntr_chunks_0++) {
+ NDR_CHECK(ndr_push_frsrpc_CommPktChunk(ndr, NDR_SCALARS, &r->chunks[cntr_chunks_0]));
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+#define _TMP_PULL_REALLOC_N(ndr, s, t, n) do { \
+ _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\
+ (s) = talloc_realloc(ndr->current_mem_ctx, (s), t, n); \
+ if (!(s)) { \
+ return ndr_pull_error(ndr, NDR_ERR_ALLOC, \
+ "Alloc %u * %s failed: %s\n", \
+ (unsigned)n, # s, __location__); \
+ } \
+} while (0)
+
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+ int ndr_flags,
+ struct frsrpc_CommPktChunkCtr *r)
+{
+ uint32_t cntr_chunks_0;
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t remaining = ndr->data_size - ndr->offset;
+ r->num_chunks = 0;
+ r->chunks = NULL;
+ for (cntr_chunks_0 = 0; remaining > 0; cntr_chunks_0++) {
+ r->num_chunks += 1;
+ _TMP_PULL_REALLOC_N(ndr, r->chunks,
+ struct frsrpc_CommPktChunk,
+ r->num_chunks);
+ NDR_CHECK(ndr_pull_frsrpc_CommPktChunk(ndr,
+ NDR_SCALARS,
+ &r->chunks[cntr_chunks_0]));
+ remaining = ndr->data_size - ndr->offset;
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+ struct smb_iconv_convenience *ic,
+ int flags)
+{
+ flags |= LIBNDR_FLAG_NOALIGN;
+ return ndr_size_struct(r, flags,
+ (ndr_push_flags_fn_t)ndr_push_frsrpc_CommPktChunkCtr,
+ ic);
+}
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ helper routines for FRSRPC marshalling
+
+ Copyright (C) Stefan (metze) Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBRPC_NDR_NDR_FRSRPC_H
+#define _LIBRPC_NDR_NDR_FRSRPC_H
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+ int ndr_flags,
+ const struct frsrpc_CommPktChunkCtr *r);
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+ int ndr_flags,
+ struct frsrpc_CommPktChunkCtr *r);
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+ struct smb_iconv_convenience *ic,
+ int flags);
+
+#endif /* _LIBRPC_NDR_NDR_FRSRPC_H */
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ndr-standard
+Description: NDR marshallers for the standard set of DCE/RPC interfaces
+Requires: ndr
+Version: 0.0.1
+Libs: -L${libdir} -lndr-standard
+Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -D_GNU_SOURCE=1
*/
#include "pam_winbind.h"
+#define CONST_DISCARD(type,ptr) ((type)(void *)ptr)
+
static int wbc_error_to_pam_error(wbcErr status)
{
config_file = PAM_WINBIND_CONFIG_FILE;
}
- d = iniparser_load(config_file);
+ d = iniparser_load(CONST_DISCARD(char *, config_file));
if (d == NULL) {
goto config_from_pam;
}
- if (iniparser_getboolean(d, "global:debug", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug"), false)) {
ctrl |= WINBIND_DEBUG_ARG;
}
- if (iniparser_getboolean(d, "global:debug_state", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug_state"), false)) {
ctrl |= WINBIND_DEBUG_STATE;
}
- if (iniparser_getboolean(d, "global:cached_login", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:cached_login"), false)) {
ctrl |= WINBIND_CACHED_LOGIN;
}
- if (iniparser_getboolean(d, "global:krb5_auth", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
ctrl |= WINBIND_KRB5_AUTH;
}
- if (iniparser_getboolean(d, "global:silent", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:silent"), false)) {
ctrl |= WINBIND_SILENT;
}
- if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) {
+ if (iniparser_getstr(d, CONST_DISCARD(char *, "global:krb5_ccache_type")) != NULL) {
ctrl |= WINBIND_KRB5_CCACHE_TYPE;
}
- if ((iniparser_getstr(d, "global:require-membership-of") != NULL) ||
- (iniparser_getstr(d, "global:require_membership_of") != NULL)) {
+ if ((iniparser_getstr(d, CONST_DISCARD(char *, "global:require-membership-of"))
+ != NULL) ||
+ (iniparser_getstr(d, CONST_DISCARD(char *, "global:require_membership_of"))
+ != NULL)) {
ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
}
- if (iniparser_getboolean(d, "global:try_first_pass", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:try_first_pass"), false)) {
ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
}
- if (iniparser_getint(d, "global:warn_pwd_expire", 0)) {
+ if (iniparser_getint(d, CONST_DISCARD(char *, "global:warn_pwd_expire"), 0)) {
ctrl |= WINBIND_WARN_PWD_EXPIRE;
}
- if (iniparser_getboolean(d, "global:mkhomedir", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:mkhomedir"), false)) {
ctrl |= WINBIND_MKHOMEDIR;
}
enum wbcSidType type;
char *domain;
char *name;
+ char *p;
/* This cannot work when the winbind separator = @ */
return NULL;
}
+ name = talloc_strdup(ctx, upn);
+ if (!name) {
+ return NULL;
+ }
+ if ((p = strchr(name, '@')) != NULL) {
+ *p = 0;
+ domain = p + 1;
+ }
+
/* Convert the UPN to a SID */
- wbc_status = wbcLookupName("", upn, &sid, &type);
+ wbc_status = wbcLookupName(domain, name, &sid, &type);
if (!WBC_ERROR_IS_OK(wbc_status)) {
return NULL;
}
# structure, the user should be able to know the size beforehand
# to allocate a structure of the right size.
my $env = GenerateFunctionInEnv($fn, "r.");
- my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL});
- if (has_property($e, "charset")) {
- $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ my $l = $e->{LEVELS}[$level];
+ unless (defined($l->{SIZE_IS})) {
+ error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'");
+ $self->pidl('#error No size known for [out] array `$e->{NAME}');
} else {
- $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ my $size_is = ParseExpr($l->{SIZE_IS}, $env, $e->{ORIGINAL});
+ if (has_property($e, "charset")) {
+ $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ } else {
+ $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ }
}
} else {
$self->pidl("*$e->{NAME} = *r.out.$e->{NAME};");
@EXPORT_OK = qw(DeclLevel);
use strict;
-use Parse::Pidl qw(warning fatal);
+use Parse::Pidl qw(warning error fatal);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
use Parse::Pidl::NDR qw(GetNextLevel);
}
if ($l->{TYPE} eq "ARRAY") {
- my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
- pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+ unless(defined($l->{SIZE_IS})) {
+ error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'");
+ pidl "#error No size known for array `$e->{NAME}'";
+ } else {
+ my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+ pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+ }
} else {
pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
}
} elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") {
$self->handle_werror("r->out.result", "NULL", undef);
} elsif (defined($fn->{RETURN_TYPE})) {
- my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result");
+ my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn);
if ($result_size > 1) {
$self->pidl("PyTuple_SetItem(result, $i, $conv);");
} else {
}
}
-sub ConvertObjectFromPythonData($$$$$$)
+sub ConvertObjectFromPythonData($$$$$$;$)
{
- my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_;
+ my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location) = @_;
- die("undef type for $cvar") unless(defined($ctype));
+ fatal($location, "undef type for $cvar") unless(defined($ctype));
$ctype = resolveType($ctype);
if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
my $ctype_name = $self->use_type_variable($ctype);
unless (defined ($ctype_name)) {
- error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+ error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
$self->assign($target, "NULL");
# FIXME:
return;
return;
}
- fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+ fatal($location, "unknown type `$actual_ctype->{TYPE}' for ".mapTypeName($ctype) . ": $cvar");
}
if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
$var_name = get_pointer_to($var_name);
}
- $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail);
+ $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail, $e->{ORIGINAL});
} elsif ($l->{TYPE} eq "SWITCH") {
$var_name = get_pointer_to($var_name);
my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
} else {
- die("unknown level type $l->{TYPE}");
+ fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
}
}
die("Unknown scalar type $ctypename");
}
-sub ConvertObjectToPythonData($$$$$)
+sub ConvertObjectToPythonData($$$$$;$)
{
- my ($self, $mem_ctx, $ctype, $cvar) = @_;
+ my ($self, $mem_ctx, $ctype, $cvar, $location) = @_;
die("undef type for $cvar") unless(defined($ctype));
} elsif ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
my $ctype_name = $self->use_type_variable($ctype);
unless (defined($ctype_name)) {
- error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+ error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
return "NULL"; # FIXME!
}
return "py_talloc_import_ex($ctype_name, $mem_ctx, $cvar)";
}
- fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+ fatal($location, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
}
sub fail_on_null($$$)
if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
$var_name = get_pointer_to($var_name);
}
- my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name);
+ my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
$self->pidl("$py_var = $conv;");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
$self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail);
} else {
- die("Unknown level type $l->{TYPE} $var_name");
+ fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
}
}
} elsif ($cvar =~ /^".*"$/) {
$py_obj = "PyString_FromString($cvar)";
} else {
- $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar);
+ $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
}
$self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);");
my $dt;
$t = expandAlias($t);
- unless ($dt or ($dt = getType($t))) {
+ if ($dt = getType($t)) {
+ return mapType($dt, $dt->{NAME});
+ } elsif (ref($t) eq "HASH" and defined($t->{NAME})) {
+ return mapType($t, $t->{NAME});
+ } else {
# Best guess
return "struct $t";
}
- return mapType($dt, $dt->{NAME});
}
sub LoadIdl($;$)
lib/interface.o lib/pidfile.o \
lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
lib/username.o \
- lib/ads_flags.o \
+ ../libds/common/flag_mapping.o \
lib/util_pw.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
lib/wins_srv.o \
NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
+FNAME_UTIL_OBJ = smbd/filename_util.o
+
VFS_DEFAULT_OBJ = modules/vfs_default.o
VFS_AUDIT_OBJ = modules/vfs_audit.o
VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
$(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
- $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
+ $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \
- $(PASSCHANGE_OBJ) $(LDB_OBJ)
+ $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ)
STATUS_OBJ = utils/status.o utils/status_profile.o \
$(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ)
+ $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ) \
+ $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \
$(PRINTBASE_OBJ)
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
$(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0)
+ $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0)
+ $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
- @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
+ @$(CC) -o $@ $(LDFLAGS) $(RPCCLIENT_OBJ) \
$(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
- $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS)
+ $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) $(PASSDB_LIBS)
bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
@$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
- -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \
+ $(LIBSMBCLIENT_OBJ1) $(LIBS) -lkeyutils $(KRB5LIBS) \
$(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \
$(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS)
DATA_BLOB challenge = data_blob_null;
const char *challenge_set_by = NULL;
auth_methods *auth_method;
- TALLOC_CTX *mem_ctx;
if (auth_context->challenge.length) {
DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n",
continue;
}
- mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name);
- if (!mem_ctx) {
- smb_panic("talloc_init() failed!");
- }
-
- challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
+ challenge = auth_method->get_chal(auth_context, &auth_method->private_data,
+ auth_context->mem_ctx);
if (!challenge.length) {
DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
auth_method->name));
challenge_set_by = auth_method->name;
auth_context->challenge_set_method = auth_method;
}
- talloc_destroy(mem_ctx);
}
if (!challenge_set_by) {
if (*workstation_list) {
bool invalid_ws = True;
- char *tok;
+ char *tok = NULL;
const char *s = workstation_list;
+ char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
- const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
if (machine_name == NULL)
return NT_STATUS_NO_MEMORY;
TALLOC_FREE(tok);
}
TALLOC_FREE(tok);
+ TALLOC_FREE(machine_name);
if (invalid_ws)
return NT_STATUS_INVALID_WORKSTATION;
len = (uint64_t)strtol(buf, (char **)NULL, 16);
- if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) {
+ if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) {
d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
}
len = (uint64_t)strtol(buf, (char **)NULL, 16);
- if (!cli_posix_unlock(cli, fnum, start, len)) {
+ if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) {
d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
}
basically this is a wrapper around ldap
*/
+#include "../libds/common/flags.h"
+
enum wb_posix_mapping {
WB_POSIX_MAP_UNKNOWN = -1,
WB_POSIX_MAP_TEMPLATE = 0,
#define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803"
#define ADS_LDAP_MATCHING_RULE_BIT_OR "1.2.840.113556.1.4.804"
-/* UserFlags for userAccountControl */
-#define UF_SCRIPT 0x00000001
-#define UF_ACCOUNTDISABLE 0x00000002
-#define UF_UNUSED_1 0x00000004
-#define UF_HOMEDIR_REQUIRED 0x00000008
-
-#define UF_LOCKOUT 0x00000010
-#define UF_PASSWD_NOTREQD 0x00000020
-#define UF_PASSWD_CANT_CHANGE 0x00000040
-#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080
-
-#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100
-#define UF_NORMAL_ACCOUNT 0x00000200
-#define UF_UNUSED_2 0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
-
-#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
-#define UF_SERVER_TRUST_ACCOUNT 0x00002000
-#define UF_UNUSED_3 0x00004000
-#define UF_UNUSED_4 0x00008000
-
-#define UF_DONT_EXPIRE_PASSWD 0x00010000
-#define UF_MNS_LOGON_ACCOUNT 0x00020000
-#define UF_SMARTCARD_REQUIRED 0x00040000
-#define UF_TRUSTED_FOR_DELEGATION 0x00080000
-
-#define UF_NOT_DELEGATED 0x00100000
-#define UF_USE_DES_KEY_ONLY 0x00200000
-#define UF_DONT_REQUIRE_PREAUTH 0x00400000
-#define UF_PASSWORD_EXPIRED 0x00800000
-
-#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
-#define UF_UNUSED_8 0x04000000
-#define UF_UNUSED_9 0x08000000
-
-#define UF_UNUSED_10 0x10000000
-#define UF_UNUSED_11 0x20000000
-#define UF_UNUSED_12 0x40000000
-#define UF_UNUSED_13 0x80000000
-
-#define UF_MACHINE_ACCOUNT_MASK (\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_ACCOUNT_TYPE_MASK (\
- UF_TEMP_DUPLICATE_ACCOUNT |\
- UF_NORMAL_ACCOUNT |\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_SETTABLE_BITS (\
- UF_SCRIPT |\
- UF_ACCOUNTDISABLE |\
- UF_HOMEDIR_REQUIRED |\
- UF_LOCKOUT |\
- UF_PASSWD_NOTREQD |\
- UF_PASSWD_CANT_CHANGE |\
- UF_ACCOUNT_TYPE_MASK | \
- UF_DONT_EXPIRE_PASSWD | \
- UF_MNS_LOGON_ACCOUNT |\
- UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
- UF_SMARTCARD_REQUIRED |\
- UF_TRUSTED_FOR_DELEGATION |\
- UF_NOT_DELEGATED |\
- UF_USE_DES_KEY_ONLY |\
- UF_DONT_REQUIRE_PREAUTH \
- )
-
-/* sAMAccountType */
-#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */
-#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
-#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */
-#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
-#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */
-#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */
-
-#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
-
-/* groupType */
-#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001
-#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002
-#define GROUP_TYPE_RESOURCE_GROUP 0x00000004
-#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
-#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010
-#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020
-#define GROUP_TYPE_SECURITY_ENABLED 0x80000000
-
-#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( /* 0x80000005 -2147483643 */ \
- GROUP_TYPE_BUILTIN_LOCAL_GROUP| \
- GROUP_TYPE_RESOURCE_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( /* 0x80000004 -2147483644 */ \
- GROUP_TYPE_RESOURCE_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_GLOBAL_GROUP ( /* 0x80000002 -2147483646 */ \
- GROUP_TYPE_ACCOUNT_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_UNIVERSAL_GROUP ( /* 0x80000008 -2147483656 */ \
- GROUP_TYPE_UNIVERSAL_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-
-#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */
-#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */
-#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */
-
#define ADS_PINGS 0x0000FFFF /* Ping response */
#define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/
#define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */
#define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore"
-/* Settings for the domainFunctionality attribute in the rootDSE */
-
-#define DS_DOMAIN_FUNCTION_2000 0
-#define DS_DOMAIN_FUCNTION_2003_MIXED 1
-#define DS_DOMAIN_FUNCTION_2003 2
-#define DS_DOMAIN_FUNCTION_2008 3
-
#endif /* _INCLUDE_ADS_H_ */
struct GUID guid;
};
+/*
+ * Types of account policy.
+ */
+enum pdb_policy_type {
+ PDB_POLICY_MIN_PASSWORD_LEN = 1,
+ PDB_POLICY_PASSWORD_HISTORY = 2,
+ PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS = 3,
+ PDB_POLICY_MAX_PASSWORD_AGE = 4,
+ PDB_POLICY_MIN_PASSWORD_AGE = 5,
+ PDB_POLICY_LOCK_ACCOUNT_DURATION = 6,
+ PDB_POLICY_RESET_COUNT_TIME = 7,
+ PDB_POLICY_BAD_ATTEMPT_LOCKOUT = 8,
+ PDB_POLICY_TIME_TO_LOGOUT = 9,
+ PDB_POLICY_REFUSE_MACHINE_PW_CHANGE = 10
+};
+
#define PDB_CAP_STORE_RIDS 0x0001
#define PDB_CAP_ADS 0x0002
enum lsa_SidType *attrs);
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
- int policy_index, uint32 *value);
+ enum pdb_policy_type type,
+ uint32_t *value);
NTSTATUS (*set_account_policy)(struct pdb_methods *methods,
- int policy_index, uint32 value);
+ enum pdb_policy_type type,
+ uint32_t value);
NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num);
/* The following definitions come from lib/account_pol.c */
void account_policy_names_list(const char ***names, int *num_names);
-const char *decode_account_policy_name(int field);
-const char *get_account_policy_attr(int field);
-const char *account_policy_get_desc(int field);
-int account_policy_name_to_fieldnum(const char *name);
-bool account_policy_get_default(int account_policy, uint32 *val);
+const char *decode_account_policy_name(enum pdb_policy_type type);
+const char *get_account_policy_attr(enum pdb_policy_type type);
+const char *account_policy_get_desc(enum pdb_policy_type type);
+enum pdb_policy_type account_policy_name_to_typenum(const char *name);
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val);
bool init_account_policy(void);
-bool account_policy_get(int field, uint32 *value);
-bool account_policy_set(int field, uint32 value);
-bool cache_account_policy_set(int field, uint32 value);
-bool cache_account_policy_get(int field, uint32 *value);
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value);
+bool account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value);
struct db_context *get_account_pol_db( void );
/* The following definitions come from lib/adt_tree.c */
NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key,
TDB_DATA data, int flags);
NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key);
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+ NTSTATUS (*action)(struct db_context *, void *),
+ void *private_data);
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key);
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+ TDB_DATA data, int flags);
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+ const char *key);
/* The following definitions come from lib/debug.c */
/* The following definitions come from lib/gencache.c */
-bool gencache_init(void);
-bool gencache_shutdown(void);
bool gencache_set(const char *keystr, const char *value, time_t timeout);
bool gencache_del(const char *keystr);
bool gencache_get(const char *keystr, char **valstr, time_t *timeout);
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired);
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+ time_t *timeout);
+bool gencache_stabilize(void);
bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout);
void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
void* data, const char* keystr_pattern);
-int gencache_lock_entry( const char *key );
-void gencache_unlock_entry( const char *key );
/* The following definitions come from lib/interface.c */
/* The following definitions come from lib/ldap_escape.c */
-char *escape_ldap_string_alloc(const char *s);
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s);
char *escape_rdn_val_string_alloc(const char *s);
/* The following definitions come from lib/module.c */
const char *ldap_server);
void ads_destroy(ADS_STRUCT **ads);
-/* The following definitions come from libads/ads_utils.c */
-
-uint32 ads_acb2uf(uint32 acb);
-uint32 ads_uf2acb(uint32 uf);
-uint32 ads_uf2atype(uint32 uf);
-uint32 ads_gtype2atype(uint32 gtype);
-enum lsa_SidType ads_atype_map(uint32 atype);
const char *ads_get_ldap_server_name(ADS_STRUCT *ads);
/* The following definitions come from libads/authdata.c */
/* The following definitions come from libsmb/clidgram.c */
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
- bool unique, const char *mailslot,
- uint16 priority,
- char *buf, int len,
- const char *srcname, int src_type,
- const char *dstname, int dest_type,
- const struct sockaddr_storage *dest_ss);
bool send_getdc_request(TALLOC_CTX *mem_ctx,
struct messaging_context *msg_ctx,
struct sockaddr_storage *dc_ss,
int timeout, unsigned char locktype);
bool cli_lock(struct cli_state *cli, uint16_t fnum,
uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
bool cli_lock64(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_unlock64_recv(struct tevent_req *req);
+NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type);
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len,
bool wait_lock, enum brl_type lock_type);
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen);
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct cli_state *cli,
const char **names,
uint32 *rids,
enum lsa_SidType *attrs);
-bool pdb_get_account_policy(int policy_index, uint32 *value);
-bool pdb_set_account_policy(int policy_index, uint32 value);
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value);
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value);
bool pdb_get_seq_num(time_t *seq_num);
bool pdb_uid_to_rid(uid_t uid, uint32 *rid);
bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid);
/* The following definitions come from registry/reg_objects.c */
WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr);
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr);
WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum);
int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr);
WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname );
void prs_force_dynamic(prs_struct *ps);
void prs_set_session_key(prs_struct *ps, const char sess_key[16]);
bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8);
-bool prs_pointer( const char *name, prs_struct *ps, int depth,
- void *dta, size_t data_size,
- bool (*prs_fn)(const char*, prs_struct*, int, void*) );
bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);
bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);
bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32);
bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status);
bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size);
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str);
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
- uint32 ptr_uint16, uint32 start_offset);
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
- uint32 ptr_uint32, uint32 data_size);
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps);
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx);
-bool prs_hash1(prs_struct *ps, uint32 offset, int len);
void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
enum schannel_direction direction,
RPC_AUTH_SCHANNEL_CHK * verf,
/* The following definitions come from rpc_server/srv_spoolss_nt.c */
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename );
void do_drv_upgrade_printer(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
int id);
struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
const char *servicename);
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
/* The following definitions come from rpc_server/srv_srvsvc_nt.c */
void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode,
NTSTATUS status, int line, const char *file);
void reply_openerror(struct smb_request *req, NTSTATUS status);
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
- NTSTATUS defstatus, int line, const char *file);
/* The following definitions come from smbd/fake_file.c */
-enum FAKE_FILE_TYPE is_fake_file(const char *fname);
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname);
NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
uint16_t current_vuid,
enum FAKE_FILE_TYPE fake_file_type,
- const char *fname,
+ const struct smb_filename *smb_fname,
uint32 access_mask,
files_struct **result);
NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp);
/* The following definitions come from smbd/filename.c */
+NTSTATUS unix_convert(TALLOC_CTX *ctx,
+ connection_struct *conn,
+ const char *orig_path,
+ struct smb_filename **smb_fname,
+ uint32_t ucf_flags);
+NTSTATUS check_name(connection_struct *conn, const char *name);
+int get_real_filename(connection_struct *conn, const char *path,
+ const char *name, TALLOC_CTX *mem_ctx,
+ char **found_name);
+NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ bool dfs_path,
+ const char *name_in,
+ struct smb_filename **pp_smb_fname);
+
+/* The following definitions come from smbd/filename_utils.c */
+
NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
char **full_name);
NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
const char *fname,
const SMB_STRUCT_STAT *psbuf,
struct smb_filename **smb_fname_out);
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf);
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf);
const char *smb_fname_str_dbg(const struct smb_filename *smb_fname);
+const char *fsp_str_dbg(const struct files_struct *fsp);
NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **smb_fname_out);
-NTSTATUS unix_convert(TALLOC_CTX *ctx,
- connection_struct *conn,
- const char *orig_path,
- struct smb_filename **smb_fname,
- uint32_t ucf_flags);
-NTSTATUS check_name(connection_struct *conn, const char *name);
-int get_real_filename(connection_struct *conn, const char *path,
- const char *name, TALLOC_CTX *mem_ctx,
- char **found_name);
-NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
- connection_struct *conn,
- bool dfs_path,
- const char *name_in,
- struct smb_filename **pp_smb_fname,
- char **pp_name);
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
/* The following definitions come from smbd/files.c */
void file_free(struct smb_request *req, files_struct *fsp);
files_struct *file_fnum(uint16 fnum);
files_struct *file_fsp(struct smb_request *req, uint16 fid);
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
uint32 create_options, files_struct *to);
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+ const struct smb_filename *smb_fname_in);
/* The following definitions come from smbd/ipc.c */
struct smb_request *req, NTSTATUS nt_error,
char *params, int paramsize,
char *pdata, int datasize);
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
void reply_ntcreate_and_X(struct smb_request *req);
void reply_ntcancel(struct smb_request *req);
void reply_ntrename(struct smb_request *req);
uint32 access_mask,
uint32 share_access,
uint32 create_options);
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+ int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
uint32 *pcreate_disposition,
int vfs_ChDir(connection_struct *conn, const char *path);
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf);
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf);
/* The following definitions come from torture/denytest.c */
SE_PRIV *rights, uint32 rights_mask,
uint32 des_access, uint32 *acc_granted,
const char *debug);
-void map_max_allowed_access(const NT_USER_TOKEN *token,
- uint32_t *pacc_requested);
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+ const struct unix_user_token *unix_token,
+ uint32_t *pacc_requested);
+
+/* The following definitions come from ../libds/common/flag_mapping.c */
+
+uint32_t ds_acb2uf(uint32_t acb);
+uint32_t ds_uf2acb(uint32_t uf);
+uint32_t ds_uf2atype(uint32_t uf);
+uint32_t ds_gtype2atype(uint32_t gtype);
+enum lsa_SidType ds_atype_map(uint32_t atype);
+
#endif /* _PROTO_H_ */
bool lockdb_clean;
bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
bool posix_open;
- char *fsp_name;
+ struct smb_filename *fsp_name;
struct vfs_fsp_data *vfs_extension;
struct fake_file_handle *fake_file_handle;
#define PW_HISTORY_ENTRY_LEN (PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN)
#define MAX_PW_HISTORY_LEN 24
-/*
- * Flags for account policy.
- */
-#define AP_MIN_PASSWORD_LEN 1
-#define AP_PASSWORD_HISTORY 2
-#define AP_USER_MUST_LOGON_TO_CHG_PASS 3
-#define AP_MAX_PASSWORD_AGE 4
-#define AP_MIN_PASSWORD_AGE 5
-#define AP_LOCK_ACCOUNT_DURATION 6
-#define AP_RESET_COUNT_TIME 7
-#define AP_BAD_ATTEMPT_LOCKOUT 8
-#define AP_TIME_TO_LOGOUT 9
-#define AP_REFUSE_MACHINE_PW_CHANGE 10
-
/*
* Flags for local user manipulation.
*/
#define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__)
#define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__)
#define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__)
-#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
#if 0
/* defined in IDL */
NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2);
+
#endif /* __TDBUTIL_H__ */
-/*
+/*
* Unix SMB/CIFS implementation.
* account policy storage
* Copyright (C) Jean François Micouleau 1998-2001.
* Copyright (C) Andrew Bartlett 2002
* Copyright (C) Guenther Deschner 2004-2005
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
struct ap_table {
- int field;
+ enum pdb_policy_type type;
const char *string;
uint32 default_val;
const char *description;
};
static const struct ap_table account_policy_names[] = {
- {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
- "Minimal password length (default: 5)",
+ {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
+ "Minimal password length (default: 5)",
"sambaMinPwdLength" },
- {AP_PASSWORD_HISTORY, "password history", 0,
- "Length of Password History Entries (default: 0 => off)",
+ {PDB_POLICY_PASSWORD_HISTORY, "password history", 0,
+ "Length of Password History Entries (default: 0 => off)",
"sambaPwdHistoryLength" },
-
- {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
+
+ {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
"Force Users to logon for password change (default: 0 => off, 2 => on)",
"sambaLogonToChgPwd" },
-
- {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
- "Maximum password age, in seconds (default: -1 => never expire passwords)",
+
+ {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
+ "Maximum password age, in seconds (default: -1 => never expire passwords)",
"sambaMaxPwdAge" },
-
- {AP_MIN_PASSWORD_AGE,"minimum password age", 0,
- "Minimal password age, in seconds (default: 0 => allow immediate password change)",
+
+ {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0,
+ "Minimal password age, in seconds (default: 0 => allow immediate password change)",
"sambaMinPwdAge" },
-
- {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
+
+ {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
"Lockout duration in minutes (default: 30, -1 => forever)",
"sambaLockoutDuration" },
-
- {AP_RESET_COUNT_TIME, "reset count minutes", 30,
- "Reset time after lockout in minutes (default: 30)",
+
+ {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30,
+ "Reset time after lockout in minutes (default: 30)",
"sambaLockoutObservationWindow" },
-
- {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
- "Lockout users after bad logon attempts (default: 0 => off)",
+
+ {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
+ "Lockout users after bad logon attempts (default: 0 => off)",
"sambaLockoutThreshold" },
-
- {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
- "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
- "sambaForceLogoff" },
-
- {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
+
+ {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
+ "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
+ "sambaForceLogoff" },
+
+ {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
"Allow Machine Password changes (default: 0 => off)",
"sambaRefuseMachinePwdChange" },
-
+
{0, NULL, 0, "", NULL}
};
void account_policy_names_list(const char ***names, int *num_names)
-{
+{
const char **nl;
int i, count;
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-const char *decode_account_policy_name(int field)
+const char *decode_account_policy_name(enum pdb_policy_type type)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
- if (field == account_policy_names[i].field) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].string;
}
}
Get the account policy LDAP attribute as a string from its #define'ed number
****************************************************************************/
-const char *get_account_policy_attr(int field)
+const char *get_account_policy_attr(enum pdb_policy_type type)
{
int i;
- for (i=0; account_policy_names[i].field; i++) {
- if (field == account_policy_names[i].field) {
+ for (i=0; account_policy_names[i].type; i++) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].ldap_attr;
}
}
Get the account policy description as a string from its #define'ed number
****************************************************************************/
-const char *account_policy_get_desc(int field)
+const char *account_policy_get_desc(enum pdb_policy_type type)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
- if (field == account_policy_names[i].field) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].description;
}
}
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-int account_policy_name_to_fieldnum(const char *name)
+enum pdb_policy_type account_policy_name_to_typenum(const char *name)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
if (strcmp(name, account_policy_names[i].string) == 0) {
- return account_policy_names[i].field;
+ return account_policy_names[i].type;
}
}
return 0;
Get default value for account policy
*****************************************************************************/
-bool account_policy_get_default(int account_policy, uint32 *val)
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val)
{
int i;
- for (i=0; account_policy_names[i].field; i++) {
- if (account_policy_names[i].field == account_policy) {
+ for (i=0; account_policy_names[i].type; i++) {
+ if (account_policy_names[i].type == type) {
*val = account_policy_names[i].default_val;
return True;
}
}
- DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
- account_policy));
+ DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
+ type));
return False;
}
/*****************************************************************************
- Set default for a field if it is empty
+ Set default for a type if it is empty
*****************************************************************************/
-static bool account_policy_set_default_on_empty(int account_policy)
+static bool account_policy_set_default_on_empty(enum pdb_policy_type type)
{
uint32 value;
- if (!account_policy_get(account_policy, &value) &&
- !account_policy_get_default(account_policy, &value)) {
+ if (!account_policy_get(type, &value) &&
+ !account_policy_get_default(type, &value)) {
return False;
}
- return account_policy_set(account_policy, value);
+ return account_policy_set(type, value);
}
/*****************************************************************************
goto cancel;
}
- for (i=0; account_policy_names[i].field; i++) {
+ for (i=0; account_policy_names[i].type; i++) {
- if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
+ if (!account_policy_set_default_on_empty(account_policy_names[i].type)) {
DEBUG(0,("failed to set default value in account policy tdb\n"));
goto cancel;
}
}
/*****************************************************************************
-Get an account policy (from tdb)
+Get an account policy (from tdb)
*****************************************************************************/
-bool account_policy_get(int field, uint32 *value)
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value)
{
const char *name;
uint32 regval;
*value = 0;
}
- name = decode_account_policy_name(field);
+ name = decode_account_policy_name(type);
if (name == NULL) {
- DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field));
+ DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", type));
return False;
}
-
+
if (!dbwrap_fetch_uint32(db, name, ®val)) {
- DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
+ DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name));
return False;
}
-
+
if (value) {
*value = regval;
}
/****************************************************************************
-Set an account policy (in tdb)
+Set an account policy (in tdb)
****************************************************************************/
-bool account_policy_set(int field, uint32 value)
+bool account_policy_set(enum pdb_policy_type type, uint32_t value)
{
const char *name;
NTSTATUS status;
return False;
}
- name = decode_account_policy_name(field);
+ name = decode_account_policy_name(type);
if (name == NULL) {
- DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field));
+ DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", type));
return False;
}
status = dbwrap_trans_store_uint32(db, name, value);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("store_uint32 failed for field %d (%s) on value "
- "%u: %s\n", field, name, value, nt_errstr(status)));
+ DEBUG(1, ("store_uint32 failed for type %d (%s) on value "
+ "%u: %s\n", type, name, value, nt_errstr(status)));
return False;
}
DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
-
+
return True;
}
/****************************************************************************
-Set an account policy in the cache
+Set an account policy in the cache
****************************************************************************/
-bool cache_account_policy_set(int field, uint32 value)
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value)
{
const char *policy_name = NULL;
char *cache_key = NULL;
char *cache_value = NULL;
bool ret = False;
- policy_name = decode_account_policy_name(field);
+ policy_name = decode_account_policy_name(type);
if (policy_name == NULL) {
DEBUG(0,("cache_account_policy_set: no policy found\n"));
return False;
}
/*****************************************************************************
-Get an account policy from the cache
+Get an account policy from the cache
*****************************************************************************/
-bool cache_account_policy_get(int field, uint32 *value)
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
{
const char *policy_name = NULL;
char *cache_key = NULL;
char *cache_value = NULL;
bool ret = False;
- policy_name = decode_account_policy_name(field);
+ policy_name = decode_account_policy_name(type);
if (policy_name == NULL) {
DEBUG(0,("cache_account_policy_set: no policy found\n"));
return False;
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
-
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
-uint32 ads_acb2uf(uint32 acb)
-{
- uint32 uf = 0x00000000;
-
- if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE;
- if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED;
- if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD;
- if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT;
- if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT;
- if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT;
- if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
- if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT;
- if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT;
- if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD;
- if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT;
- if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY;
- if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED;
- if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION;
- if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH;
- if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED;
- if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED;
- if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
-
- return uf;
-}
-
-/*
-translated the UserFlags (userAccountControl) to ACB_CTRL Flags
-*/
-uint32 ads_uf2acb(uint32 uf)
-{
- uint32 acb = 0x00000000;
-
- if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED;
- if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ;
- if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ;
- if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS;
- if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP;
- if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK;
- if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY;
- if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED;
- if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION;
- if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH;
- if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD;
- if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED;
- if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED;
-
- switch (uf & UF_ACCOUNT_TYPE_MASK)
- {
- case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break;
- case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break;
- case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break;
- case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break;
- case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break;
- /*Fix Me: what should we do here? */
- default: acb |= ACB_NORMAL;break;
- }
-
- return acb;
-}
-
-/*
-get the accountType from the UserFlags
-*/
-uint32 ads_uf2atype(uint32 uf)
-{
- uint32 atype = 0x00000000;
-
- if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
-
- return atype;
-}
-
-/*
-get the accountType from the groupType
-*/
-uint32 ads_gtype2atype(uint32 gtype)
-{
- uint32 atype = 0x00000000;
-
- switch(gtype) {
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_GLOBAL_GROUP:
- atype = ATYPE_SECURITY_GLOBAL_GROUP;
- break;
-
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
- break;
- }
-
- return atype;
-}
-
-/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType ads_atype_map(uint32 atype)
-{
- switch (atype & 0xF0000000) {
- case ATYPE_GLOBAL_GROUP:
- return SID_NAME_DOM_GRP;
- case ATYPE_SECURITY_LOCAL_GROUP:
- return SID_NAME_ALIAS;
- case ATYPE_ACCOUNT:
- return SID_NAME_USER;
- default:
- DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
- }
- return SID_NAME_UNKNOWN;
-}
size_t size;
smb_ucs2_t *buffer;
- if (!push_ucs2_talloc(NULL, &buffer, src, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
return (size_t)-1;
}
size_t size;
smb_ucs2_t *buffer = NULL;
- if (!convert_string_talloc(NULL, CH_UNIX, CH_UTF16LE, src, srclen,
+ if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
(void **)(void *)&buffer, &size,
True))
{
smb_ucs2_t *buffer;
conv_silent = True;
- if (!push_ucs2_talloc(NULL, &buffer, src, &buffer_len)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
smb_panic("failed to create UCS2 buffer");
}
}
if (flags & STR_UPPER) {
- tmpbuf = strupper_talloc(NULL, src);
+ tmpbuf = strupper_talloc(talloc_tos(), src);
if (!tmpbuf) {
return (size_t)-1;
}
goto next_pkt;
}
- if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) {
+ if (!(msg_state = TALLOC_P(talloc_autofree_context(), struct deferred_msg_state))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(hdr);
goto next_pkt;
/* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
if(DEBUGLEVEL >= 10) {
- char *keystr = hex_encode_talloc(NULL, (unsigned char*)key.dptr, key.dsize);
+ char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize);
DEBUG(10, (DEBUGLEVEL > 10
? "Locking key %s\n" : "Locking key %.20s\n",
keystr));
Unix SMB/CIFS implementation.
Utility functions for the dbwrap API
Copyright (C) Volker Lendecke 2007
+ Copyright (C) Michael Adam 2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return 0;
}
-NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
- int flag)
+struct dbwrap_store_context {
+ TDB_DATA *key;
+ TDB_DATA *dbuf;
+ int flag;
+};
+
+static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data)
{
- int res;
struct db_record *rec = NULL;
NTSTATUS status;
+ struct dbwrap_store_context *store_ctx;
- res = db->transaction_start(db);
- if (res != 0) {
- DEBUG(5, ("transaction_start failed\n"));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
+ store_ctx = (struct dbwrap_store_context *)private_data;
- rec = db->fetch_locked(db, talloc_tos(), key);
+ rec = db->fetch_locked(db, talloc_tos(), *(store_ctx->key));
if (rec == NULL) {
DEBUG(5, ("fetch_locked failed\n"));
- status = NT_STATUS_NO_MEMORY;
- goto cancel;
+ return NT_STATUS_NO_MEMORY;
}
- status = rec->store(rec, dbuf, flag);
+ status = rec->store(rec, *(store_ctx->dbuf), store_ctx->flag);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("store returned %s\n", nt_errstr(status)));
- goto cancel;
}
TALLOC_FREE(rec);
+ return status;
+}
- res = db->transaction_commit(db);
- if (res != 0) {
- DEBUG(5, ("tdb_transaction_commit failed\n"));
- status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- TALLOC_FREE(rec);
- return status;
- }
+NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
+ int flag)
+{
+ NTSTATUS status;
+ struct dbwrap_store_context store_ctx;
- return NT_STATUS_OK;
+ store_ctx.key = &key;
+ store_ctx.dbuf = &dbuf;
+ store_ctx.flag = flag;
- cancel:
- TALLOC_FREE(rec);
+ status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx);
- if (db->transaction_cancel(db) != 0) {
- smb_panic("Cancelling transaction failed");
- }
return status;
}
-NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+static NTSTATUS dbwrap_delete_action(struct db_context * db, void *private_data)
{
- int res;
- struct db_record *rec = NULL;
NTSTATUS status;
+ struct db_record *rec;
+ TDB_DATA *key = (TDB_DATA *)private_data;
- res = db->transaction_start(db);
- if (res != 0) {
- DEBUG(5, ("transaction_start failed\n"));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- rec = db->fetch_locked(db, talloc_tos(), key);
+ rec = db->fetch_locked(db, talloc_tos(), *key);
if (rec == NULL) {
DEBUG(5, ("fetch_locked failed\n"));
- status = NT_STATUS_NO_MEMORY;
- goto cancel;
+ return NT_STATUS_NO_MEMORY;
}
status = rec->delete_rec(rec);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status)));
- goto cancel;
}
- TALLOC_FREE(rec);
-
- res = db->transaction_commit(db);
- if (res != 0) {
- DEBUG(5, ("tdb_transaction_commit failed\n"));
- status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- TALLOC_FREE(rec);
- return status;
- }
+ talloc_free(rec);
+ return status;
+}
- return NT_STATUS_OK;
+NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+{
+ NTSTATUS status;
- cancel:
- TALLOC_FREE(rec);
+ status = dbwrap_trans_do(db, dbwrap_delete_action, &key);
- if (db->transaction_cancel(db) != 0) {
- smb_panic("Cancelling transaction failed");
- }
return status;
}
{
return dbwrap_trans_delete(db, string_term_tdb_data(key));
}
+
+/**
+ * Wrap db action(s) into a transaction.
+ */
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+ NTSTATUS (*action)(struct db_context *, void *),
+ void *private_data)
+{
+ int res;
+ NTSTATUS status;
+
+ res = db->transaction_start(db);
+ if (res != 0) {
+ DEBUG(5, ("transaction_start failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ status = action(db, private_data);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (db->transaction_cancel(db) != 0) {
+ smb_panic("Cancelling transaction failed");
+ }
+ return status;
+ }
+
+ res = db->transaction_commit(db);
+ if (res == 0) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(2, ("transaction_commit failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+}
+
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key)
+{
+ char *key_upper;
+ NTSTATUS status;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dbwrap_delete_bystring(db, key_upper);
+
+ talloc_free(key_upper);
+ return status;
+}
+
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+ TDB_DATA data, int flags)
+{
+ char *key_upper;
+ NTSTATUS status;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dbwrap_store_bystring(db, key_upper, data, flags);
+
+ talloc_free(key_upper);
+ return status;
+}
+
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+ const char *key)
+{
+ char *key_upper;
+ TDB_DATA result;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return make_tdb_data(NULL, 0);
+ }
+
+ result = dbwrap_fetch_bystring(db, mem_ctx, key_upper);
+
+ talloc_free(key_upper);
+ return result;
+}
{ EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY},
{ EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS },
{ EINTR, ERRHRD, ERRgeneral, NT_STATUS_RETRY },
+ { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED },
#ifdef ELOOP
{ ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
#endif
samba_level = 2;
break;
case TEVENT_DEBUG_TRACE:
- samba_level = 10;
+ samba_level = 11;
break;
};
#define DBGC_CLASS DBGC_TDB
#define TIMEOUT_LEN 12
-#define CACHE_DATA_FMT "%12u/%s"
+#define CACHE_DATA_FMT "%12u/"
#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
#define BLOB_TYPE "DATA_BLOB"
#define BLOB_TYPE_LEN 9
-static TDB_CONTEXT *cache;
+static struct tdb_context *cache;
+static struct tdb_context *cache_notrans;
/**
* @file gencache.c
* false on failure
**/
-bool gencache_init(void)
+static bool gencache_init(void)
{
char* cache_fname = NULL;
+ int open_flags = O_RDWR|O_CREAT;
/* skip file open if it's already opened */
if (cache) return True;
DEBUG(5, ("Opening cache file at %s\n", cache_fname));
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0644);
+ cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, 0644);
if (!cache && (errno == EACCES)) {
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644);
+ open_flags = O_RDONLY;
+ cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags,
+ 0644);
if (cache) {
DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
}
DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
return False;
}
- return True;
-}
+ cache_fname = lock_path("gencache_notrans.tdb");
-/**
- * Cache shutdown function. Closes opened cache tdb file.
- *
- * @return true on successful closing the cache or
- * false on failure during cache shutdown
- **/
+ DEBUG(5, ("Opening cache file at %s\n", cache_fname));
-bool gencache_shutdown(void)
-{
- int ret;
- /* tdb_close routine returns -1 on error */
- if (!cache) return False;
- DEBUG(5, ("Closing cache file\n"));
- ret = tdb_close(cache);
- cache = NULL;
- return ret != -1;
+ cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST,
+ open_flags, 0644);
+ if (cache_notrans == NULL) {
+ DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
+ strerror(errno)));
+ tdb_close(cache);
+ return false;
+ }
+
+ return True;
}
+static TDB_DATA last_stabilize_key(void)
+{
+ TDB_DATA result;
+ result.dptr = (uint8_t *)"@LAST_STABILIZED";
+ result.dsize = 17;
+ return result;
+}
/**
* Set an entry in the cache file. If there's no such
* one, then add it.
*
* @param keystr string that represents a key of this entry
- * @param value text representation value being cached
+ * @param blob DATA_BLOB value being cached
* @param timeout time when the value is expired
*
* @retval true when entry is successfuly stored
* @retval false on failure
**/
-bool gencache_set(const char *keystr, const char *value, time_t timeout)
+bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
+ time_t timeout)
{
int ret;
TDB_DATA databuf;
- char* valstr = NULL;
+ char* val;
+ time_t last_stabilize;
+ static int writecount;
+
+ if (tdb_data_cmp(string_term_tdb_data(keystr),
+ last_stabilize_key()) == 0) {
+ DEBUG(10, ("Can't store %s as a key\n", keystr));
+ return false;
+ }
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && value);
+ if ((keystr == NULL) || (blob == NULL)) {
+ return false;
+ }
if (!gencache_init()) return False;
- if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) {
+ val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout);
+ if (val == NULL) {
return False;
}
+ val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1);
+ if (val == NULL) {
+ return false;
+ }
+ val = (char *)talloc_append_blob(NULL, val, *blob);
+ if (val == NULL) {
+ return false;
+ }
- databuf = string_term_tdb_data(valstr);
- DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
- " %s (%d seconds %s)\n", keystr, value,ctime(&timeout),
+ DEBUG(10, ("Adding cache entry with key = %s and timeout ="
+ " %s (%d seconds %s)\n", keystr, ctime(&timeout),
(int)(timeout - time(NULL)),
timeout > time(NULL) ? "ahead" : "in the past"));
- ret = tdb_store_bystring(cache, keystr, databuf, 0);
- SAFE_FREE(valstr);
+ ret = tdb_store_bystring(
+ cache_notrans, keystr,
+ make_tdb_data((uint8_t *)val, talloc_array_length(val)),
+ 0);
+ TALLOC_FREE(val);
+ if (ret != 0) {
+ return false;
+ }
+
+ /*
+ * Every 100 writes within a single process, stabilize the cache with
+ * a transaction. This is done to prevent a single transaction to
+ * become huge and chew lots of memory.
+ */
+ writecount += 1;
+ if (writecount > lp_parm_int(-1, "gencache", "stabilize_count", 100)) {
+ gencache_stabilize();
+ writecount = 0;
+ goto done;
+ }
+
+ /*
+ * Every 5 minutes, call gencache_stabilize() to not let grow
+ * gencache_notrans.tdb too large.
+ */
+
+ last_stabilize = 0;
+ databuf = tdb_fetch(cache_notrans, last_stabilize_key());
+ if ((databuf.dptr != NULL)
+ && (databuf.dptr[databuf.dsize-1] == '\0')) {
+ last_stabilize = atoi((char *)databuf.dptr);
+ SAFE_FREE(databuf.dptr);
+ }
+ if ((last_stabilize
+ + lp_parm_int(-1, "gencache", "stabilize_interval", 300))
+ < time(NULL)) {
+ gencache_stabilize();
+ }
+
+done:
return ret == 0;
}
bool gencache_del(const char *keystr)
{
- int ret;
+ bool exists;
+ bool ret = false;
+ char *value;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ if (keystr == NULL) {
+ return false;
+ }
if (!gencache_init()) return False;
DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
- ret = tdb_delete_bystring(cache, keystr);
- return ret == 0;
+ if (tdb_lock_bystring(cache_notrans, keystr) == -1) {
+ DEBUG(5, ("Could not lock key for %s\n", keystr));
+ return false;
+ }
+
+ /*
+ * We delete an element by setting its timeout to 0. This way we don't
+ * have to do a transaction on gencache.tdb every time we delete an
+ * element.
+ */
+
+ exists = gencache_get(keystr, &value, NULL);
+ if (exists) {
+ SAFE_FREE(value);
+ ret = gencache_set(keystr, "", 0);
+ }
+ tdb_unlock_bystring(cache_notrans, keystr);
+ return ret;
}
+static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr)
+{
+ time_t res;
+ char *endptr;
+
+ res = strtol(val, &endptr, 10);
+
+ if ((endptr == NULL) || (*endptr != '/')) {
+ DEBUG(2, ("Invalid gencache data format: %s\n", val));
+ return false;
+ }
+ if (pres != NULL) {
+ *pres = res;
+ }
+ if (pendptr != NULL) {
+ *pendptr = endptr;
+ }
+ return true;
+}
/**
* Get existing entry from the cache file.
*
* @param keystr string that represents a key of this entry
- * @param valstr buffer that is allocated and filled with the entry value
- * buffer's disposing must be done outside
+ * @param blob DATA_BLOB that is filled with entry's blob
* @param timeout pointer to a time_t that is filled with entry's
* timeout
*
* @retval False for failure
**/
-bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+ time_t *timeout)
{
TDB_DATA databuf;
time_t t;
char *endptr;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ if (keystr == NULL) {
+ return false;
+ }
+
+ if (tdb_data_cmp(string_term_tdb_data(keystr),
+ last_stabilize_key()) == 0) {
+ DEBUG(10, ("Can't get %s as a key\n", keystr));
+ return false;
+ }
if (!gencache_init()) {
return False;
}
- databuf = tdb_fetch_bystring(cache, keystr);
+ databuf = tdb_fetch_bystring(cache_notrans, keystr);
if (databuf.dptr == NULL) {
- DEBUG(10, ("Cache entry with key = %s couldn't be found\n",
+ databuf = tdb_fetch_bystring(cache, keystr);
+ }
+
+ if (databuf.dptr == NULL) {
+ DEBUG(10, ("Cache entry with key = %s couldn't be found \n",
keystr));
return False;
}
- t = strtol((const char *)databuf.dptr, &endptr, 10);
-
- if ((endptr == NULL) || (*endptr != '/')) {
- DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr));
+ if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) {
SAFE_FREE(databuf.dptr);
return False;
}
"timeout = %s", t > time(NULL) ? "valid" :
"expired", keystr, endptr+1, ctime(&t)));
+ if (t == 0) {
+ /* Deleted */
+ SAFE_FREE(databuf.dptr);
+ return False;
+ }
+
if (t <= time(NULL)) {
- /* We're expired, delete the entry */
- tdb_delete_bystring(cache, keystr);
+ /*
+ * We're expired, delete the entry. We can't use gencache_del
+ * here, because that uses gencache_get_data_blob for checking
+ * the existence of a record. We know the thing exists and
+ * directly store an empty value with 0 timeout.
+ */
+ gencache_set(keystr, "", 0);
SAFE_FREE(databuf.dptr);
return False;
}
- if (valstr) {
- *valstr = SMB_STRDUP(endptr+1);
- if (*valstr == NULL) {
+ if (blob != NULL) {
+ *blob = data_blob(
+ endptr+1,
+ databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr));
+ if (blob->data == NULL) {
SAFE_FREE(databuf.dptr);
- DEBUG(0, ("strdup failed\n"));
+ DEBUG(0, ("memdup failed\n"));
return False;
}
}
return True;
}
+struct stabilize_state {
+ bool written;
+ bool error;
+};
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+ void *priv);
+
/**
- * Get existing entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB that is filled with entry's blob
- * @param expired pointer to a bool that indicates whether the entry is expired
+ * Stabilize gencache
*
- * @retval true when entry is successfuly fetched
- * @retval False for failure
- **/
+ * Migrate the clear-if-first gencache data to the stable,
+ * transaction-based gencache.tdb
+ */
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired)
+bool gencache_stabilize(void)
{
- TDB_DATA databuf;
- time_t t;
- char *blob_type;
- unsigned char *buf = NULL;
- bool ret = False;
- fstring valstr;
- int buflen = 0, len = 0, blob_len = 0;
- unsigned char *blob_buf = NULL;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ struct stabilize_state state;
+ int res;
+ char *now;
if (!gencache_init()) {
- return False;
+ return false;
}
- databuf = tdb_fetch_bystring(cache, keystr);
- if (!databuf.dptr) {
- DEBUG(10,("Cache entry with key = %s couldn't be found\n",
- keystr));
- return False;
+ res = tdb_transaction_start(cache);
+ if (res == -1) {
+ DEBUG(10, ("Could not start transaction on gencache.tdb: "
+ "%s\n", tdb_errorstr(cache)));
+ return false;
+ }
+ res = tdb_transaction_start(cache_notrans);
+ if (res == -1) {
+ tdb_transaction_cancel(cache);
+ DEBUG(10, ("Could not start transaction on "
+ "gencache_notrans.tdb: %s\n",
+ tdb_errorstr(cache_notrans)));
+ return false;
}
- buf = (unsigned char *)databuf.dptr;
- buflen = databuf.dsize;
+ state.error = false;
+ state.written = false;
- len += tdb_unpack(buf+len, buflen-len, "fB",
- &valstr,
- &blob_len, &blob_buf);
- if (len == -1) {
- goto out;
+ res = tdb_traverse(cache_notrans, stabilize_fn, &state);
+ if ((res == -1) || state.error) {
+ if ((tdb_transaction_cancel(cache_notrans) == -1)
+ || (tdb_transaction_cancel(cache) == -1)) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return false;
}
- t = strtol(valstr, &blob_type, 10);
+ if (!state.written) {
+ if ((tdb_transaction_cancel(cache_notrans) == -1)
+ || (tdb_transaction_cancel(cache) == -1)) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return true;
+ }
- if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
- goto out;
+ res = tdb_transaction_commit(cache);
+ if (res == -1) {
+ DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+ "%s\n", tdb_errorstr(cache)));
+ if (tdb_transaction_cancel(cache_notrans) == -1) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return false;
}
- DEBUG(10,("Returning %s cache entry: key = %s, "
- "timeout = %s", t > time(NULL) ? "valid" :
- "expired", keystr, ctime(&t)));
+ res = tdb_transaction_commit(cache_notrans);
+ if (res == -1) {
+ DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+ "%s\n", tdb_errorstr(cache)));
+ return false;
+ }
- if (t <= time(NULL)) {
- /* We're expired */
- if (expired) {
- *expired = True;
- }
+ now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL));
+ if (now != NULL) {
+ tdb_store(cache_notrans, last_stabilize_key(),
+ string_term_tdb_data(now), 0);
+ TALLOC_FREE(now);
}
- if (blob) {
- *blob = data_blob(blob_buf, blob_len);
- if (!blob->data) {
- goto out;
+ return true;
+}
+
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+ void *priv)
+{
+ struct stabilize_state *state = (struct stabilize_state *)priv;
+ int res;
+ time_t timeout;
+
+ if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+ return 0;
+ }
+
+ if (!gencache_pull_timeout((char *)val.dptr, &timeout, NULL)) {
+ DEBUG(10, ("Ignoring invalid entry\n"));
+ return 0;
+ }
+ if ((timeout < time(NULL)) || (val.dsize == 0)) {
+ res = tdb_delete(cache, key);
+ if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
+ res = 0;
+ } else {
+ state->written = true;
+ }
+ } else {
+ res = tdb_store(cache, key, val, 0);
+ if (res == 0) {
+ state->written = true;
}
}
- ret = True;
- out:
- SAFE_FREE(blob_buf);
- SAFE_FREE(databuf.dptr);
+ if (res == -1) {
+ DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
+ tdb_errorstr(cache)));
+ state->error = true;
+ return -1;
+ }
- return ret;
+ if (tdb_delete(cache_notrans, key) == -1) {
+ DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
+ "%s\n", tdb_errorstr(cache_notrans)));
+ state->error = true;
+ return -1;
+ }
+ return 0;
}
/**
- * Set an entry in the cache file. If there's no such
- * one, then add it.
+ * Get existing entry from the cache file.
*
* @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB value being cached
- * @param timeout time when the value is expired
+ * @param valstr buffer that is allocated and filled with the entry value
+ * buffer's disposing must be done outside
+ * @param timeout pointer to a time_t that is filled with entry's
+ * timeout
*
- * @retval true when entry is successfuly stored
- * @retval false on failure
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
**/
-bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout)
+bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
{
+ DATA_BLOB blob;
bool ret = False;
- int tdb_ret;
- TDB_DATA databuf;
- char *valstr = NULL;
- unsigned char *buf = NULL;
- int len = 0, buflen = 0;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && blob);
-
- if (!gencache_init()) {
- return False;
+ ret = gencache_get_data_blob(keystr, &blob, ptimeout);
+ if (!ret) {
+ return false;
}
-
- if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) {
- return False;
+ if ((blob.data == NULL) || (blob.length == 0)) {
+ SAFE_FREE(blob.data);
+ return false;
}
-
- again:
- len = 0;
-
- len += tdb_pack(buf+len, buflen-len, "fB",
- valstr,
- blob->length, blob->data);
-
- if (len == -1) {
- goto out;
+ if (blob.data[blob.length-1] != '\0') {
+ /* Not NULL terminated, can't be a string */
+ SAFE_FREE(blob.data);
+ return false;
}
-
- if (buflen < len) {
- SAFE_FREE(buf);
- buf = SMB_MALLOC_ARRAY(unsigned char, len);
- if (!buf) {
- goto out;
- }
- buflen = len;
- goto again;
- }
-
- databuf = make_tdb_data(buf, len);
-
- DEBUG(10,("Adding cache entry with key = %s; "
- "blob size = %d and timeout = %s"
- "(%d seconds %s)\n", keystr, (int)databuf.dsize,
- ctime(&timeout), (int)(timeout - time(NULL)),
- timeout > time(NULL) ? "ahead" : "in the past"));
-
- tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
- if (tdb_ret == 0) {
- ret = True;
+ *value = SMB_STRDUP((char *)blob.data);
+ data_blob_free(&blob);
+ if (*value == NULL) {
+ return false;
}
+ return true;
+}
- out:
- SAFE_FREE(valstr);
- SAFE_FREE(buf);
+/**
+ * Set an entry in the cache file. If there's no such
+ * one, then add it.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param value text representation value being cached
+ * @param timeout time when the value is expired
+ *
+ * @retval true when entry is successfuly stored
+ * @retval false on failure
+ **/
- return ret;
+bool gencache_set(const char *keystr, const char *value, time_t timeout)
+{
+ DATA_BLOB blob = data_blob_const(value, strlen(value)+1);
+ return gencache_set_data_blob(keystr, &blob, timeout);
}
/**
void *priv);
const char *pattern;
void *priv;
+ bool in_persistent;
};
static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
time_t timeout;
char *timeout_endp;
+ if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+ return 0;
+ }
+
+ if (state->in_persistent && tdb_exists(cache_notrans, key)) {
+ return 0;
+ }
+
if (key.dptr[key.dsize-1] == '\0') {
keystr = (char *)key.dptr;
} else {
{
struct gencache_iterate_state state;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(fn && keystr_pattern);
+ if ((fn == NULL) || (keystr_pattern == NULL)) {
+ return;
+ }
if (!gencache_init()) return;
state.fn = fn;
state.pattern = keystr_pattern;
state.priv = data;
- tdb_traverse(cache, gencache_iterate_fn, &state);
-}
-/********************************************************************
- lock a key
-********************************************************************/
+ state.in_persistent = false;
+ tdb_traverse(cache_notrans, gencache_iterate_fn, &state);
-int gencache_lock_entry( const char *key )
-{
- if (!gencache_init())
- return -1;
-
- return tdb_lock_bystring(cache, key);
-}
-
-/********************************************************************
- unlock a key
-********************************************************************/
-
-void gencache_unlock_entry( const char *key )
-{
- if (!gencache_init())
- return;
-
- tdb_unlock_bystring(cache, key);
- return;
+ state.in_persistent = true;
+ tdb_traverse(cache, gencache_iterate_fn, &state);
}
* and to be free()ed by the caller.
**/
-char *escape_ldap_string_alloc(const char *s)
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s)
{
size_t len = strlen(s)+1;
- char *output = (char *)SMB_MALLOC(len);
+ char *output = talloc_array(mem_ctx, char, len);
const char *sub;
int i = 0;
char *p = output;
if (output == NULL) {
return NULL;
}
-
+
while (*s)
{
switch (*s)
sub = NULL;
break;
}
-
+
if (sub) {
+ char *tmp;
len = len + 3;
- output = (char *)SMB_REALLOC(output, len);
- if (!output) {
+ tmp = talloc_realloc(mem_ctx, output, char, len);
+ if (tmp == NULL) {
+ TALLOC_FREE(output);
return NULL;
}
-
+ output = tmp;
+
p = &output[i];
strncpy (p, sub, 3);
p += 3;
}
s++;
}
-
+
*p = '\0';
return output;
}
}
p = output;
-
+
while (*s)
{
switch (*s)
*p = *s;
p++;
}
-
+
s++;
}
-
+
*p = '\0';
/* resize the string to the actual final size */
gfree_charcnv();
gfree_interfaces();
- gencache_shutdown();
secrets_shutdown();
TALLOC_FREE(ctx);
{
uint32_t fl = UF_SCRIPT; /* god knows why */
- fl |= ads_acb2uf(acb);
+ fl |= ds_acb2uf(acb);
return fl;
}
char *escape_domain_name;
/* escape for filter */
- escape_domain_name = escape_ldap_string_alloc(domain_name);
+ escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
if (!escape_domain_name) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))",
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
escape_domain_name, LDAP_OBJ_DOMINFO) < 0) {
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
attr_list = get_attr_list(NULL, dominfo_attr_list );
rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
int count;
char *escape_domain_name;
- escape_domain_name = escape_ldap_string_alloc(domain_name);
+ escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
if (!escape_domain_name) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
LDAP_OBJ_DOMINFO,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
escape_domain_name) < 0) {
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter));
static void get_create_timespec(const struct stat *pst, struct stat_ex *dst)
{
- struct timespec ret;
-
if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
dst->st_ex_btime.tv_sec = 315493200L; /* 1/1/1980 */
dst->st_ex_btime.tv_nsec = 0;
/* Deal with systems that don't initialize birthtime correctly.
* Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
*/
- if (null_timespec(ret)) {
+ if (null_timespec(dst->st_ex_btime)) {
dst->st_ex_btime = calc_create_time_stat(pst);
dst->st_ex_calculated_birthtime = true;
}
static void tldap_add_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_ADD);
+ tldap_simple_done(subreq, TLDAP_RES_ADD);
}
int tldap_add_recv(struct tevent_req *req)
static void tldap_modify_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_MODIFY);
+ tldap_simple_done(subreq, TLDAP_RES_MODIFY);
}
int tldap_modify_recv(struct tevent_req *req)
static void tldap_delete_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_DELETE);
+ tldap_simple_done(subreq, TLDAP_RES_DELETE);
}
int tldap_delete_recv(struct tevent_req *req)
#endif
#ifdef TCP_FASTACK
{"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
+#endif
+#ifdef TCP_QUICKACK
+ {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
#endif
{NULL,0,0,0,0}};
return +1;
}
- if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
return strcmp(ps, pt);
/* Not quite the right answer, but finding the right one
under this failure case is expensive, and it's pretty
close */
}
- if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
TALLOC_FREE(buffer_s);
return strcmp(ps, pt);
/* Not quite the right answer, but finding the right one
return 0;
}
- if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
return strncmp(ps, pt, len-n);
/* Not quite the right answer, but finding the right one
under this failure case is expensive,
and it's pretty close */
}
- if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
TALLOC_FREE(buffer_s);
return strncmp(ps, pt, len-n);
/* Not quite the right answer, but finding the right one
{
size_t ret, converted_size;
smb_ucs2_t *tmpbuf2 = NULL;
- if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
return 0;
}
ret = strlen_w(tmpbuf2);
{
size_t ret, converted_size;
char *tmpbuf2 = NULL;
- if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+ if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
return 0;
}
ret = strlen(tmpbuf2);
bool ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
return false;
}
bool ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
return false;
}
s = src;
#endif
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Wrong answer, but what can we do... */
return strchr(src, c);
}
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
SAFE_FREE(ws);
/* Wrong answer, but what can we do... */
return strchr(src, c);
char *ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Wrong answer, but what can we do. */
return strrchr(s, c);
}
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
TALLOC_FREE(ws);
/* Wrong answer, but what can we do. */
return strrchr(s, c);
char *ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Too hard to try and get right. */
return NULL;
}
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
TALLOC_FREE(ws);
/* Too hard to try and get right. */
return NULL;
s = src;
#endif
- if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
DEBUG(0,("strstr_m: src malloc fail\n"));
return NULL;
}
- if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
TALLOC_FREE(src_w);
DEBUG(0,("strstr_m: find malloc fail\n"));
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
TALLOC_FREE(src_w);
TALLOC_FREE(find_w);
DEBUG(0,("strstr_m: dest malloc fail\n"));
result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
SMB_ASSERT(result != NULL);
- while (len-- && out_cnt < (data.length * 2) - 5) {
+ while (len--) {
int c = (unsigned char) *(data.data++);
bits += c;
char_count++;
return NT_STATUS_INTERNAL_ERROR;
}
+
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2)
+{
+ int ret;
+ if (t1.dptr == NULL && t2.dptr != NULL) {
+ return -1;
+ }
+ if (t1.dptr != NULL && t2.dptr == NULL) {
+ return 1;
+ }
+ if (t1.dptr == t2.dptr) {
+ return t1.dsize - t2.dsize;
+ }
+ ret = memcmp(t1.dptr, t2.dptr, MIN(t1.dsize, t2.dsize));
+ if (ret == 0) {
+ return t1.dsize - t2.dsize;
+ }
+ return ret;
+}
bool ret = False;
char *key;
- if (!gencache_init()) {
- return False;
- }
-
if (!realm || (strlen(realm) == 0)) {
DEBUG(0,("sitename_store: no realm\n"));
return False;
const char *query_realm;
char *key;
- if (!gencache_init()) {
- return NULL;
- }
-
if (!realm || (strlen(realm) == 0)) {
query_realm = lp_realm();
} else {
ADS_STATUS status;
char *ldap_exp;
const char *attrs[] = {"*", NULL};
- char *escaped_user = escape_ldap_string_alloc(user);
+ char *escaped_user = escape_ldap_string(talloc_tos(), user);
if (!escaped_user) {
return ADS_ERROR(LDAP_NO_MEMORY);
}
if (asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user) == -1) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return ADS_ERROR(LDAP_NO_MEMORY);
}
status = ads_search(ads, res, ldap_exp, attrs);
SAFE_FREE(ldap_exp);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return status;
}
}
- if (!pdb_set_account_policy(AP_PASSWORD_HISTORY,
+ if (!pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
r->password_history_length))
return nt_status;
- if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+ if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
r->min_password_length))
return nt_status;
- if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ if (!pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE,
+ (uint32)u_max_age))
return nt_status;
- if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE,
+ (uint32)u_min_age))
return nt_status;
- if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ if (!pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT,
+ (uint32)u_logout))
return nt_status;
if (lockstr) {
u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count);
u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration);
- if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+ if (!pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
lockstr->bad_attempt_lockout))
return nt_status;
- if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60))
+ if (!pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME,
+ (uint32_t)u_lockoutreset/60))
return nt_status;
if (u_lockouttime != -1)
u_lockouttime /= 60;
- if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime))
+ if (!pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION,
+ (uint32_t)u_lockouttime))
return nt_status;
}
- if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ if (!pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
r->logon_to_chgpass))
return nt_status;
* cli_send_mailslot, send a mailslot for client code ...
*/
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
+static bool cli_send_mailslot(struct messaging_context *msg_ctx,
bool unique, const char *mailslot,
uint16 priority,
char *buf, int len,
return True;
}
-
SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
/* Setup param array. */
- memset(state->param, '\0', 6);
SSVAL(state->param,0,fnum);
SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO);
if (req == NULL) {
return NULL;
}
+
vwv = state->vwv;
SCVAL(vwv+0, 0, 0xFF);
if (req == NULL) {
return NULL;
}
+
SSVAL(state->vwv+0, 0, fnum);
SIVALS(state->vwv+1, 0, -1);
Unlock a file.
****************************************************************************/
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len)
+struct cli_unlock_state {
+ uint16_t vwv[8];
+ uint8_t data[10];
+};
+
+static void cli_unlock_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+
{
- char *p;
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct cli_unlock_state *state = NULL;
+ uint8_t additional_flags = 0;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state);
+ if (req == NULL) {
+ return NULL;
+ }
- cli_set_message(cli->outbuf,8,0,True);
+ SCVAL(state->vwv+0, 0, 0xFF);
+ SSVAL(state->vwv+2, 0, fnum);
+ SCVAL(state->vwv+3, 0, 0);
+ SIVALS(state->vwv+4, 0, 0);
+ SSVAL(state->vwv+6, 0, 1);
+ SSVAL(state->vwv+7, 0, 0);
- SCVAL(cli->outbuf,smb_com,SMBlockingX);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ SSVAL(state->data, 0, cli->pid);
+ SIVAL(state->data, 2, offset);
+ SIVAL(state->data, 6, len);
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,fnum);
- SCVAL(cli->outbuf,smb_vwv3,0);
- SIVALS(cli->outbuf, smb_vwv4, 0);
- SSVAL(cli->outbuf,smb_vwv6,1);
- SSVAL(cli->outbuf,smb_vwv7,0);
+ subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+ 8, state->vwv, 10, state->data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_unlock_done, req);
+ return req;
+}
- p = smb_buf(cli->outbuf);
- SSVAL(p, 0, cli->pid);
- SIVAL(p, 2, offset);
- SIVAL(p, 6, len);
- p += 10;
- cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return False;
+static void cli_unlock_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ NTSTATUS status;
+
+ status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- if (cli_is_error(cli)) {
- return False;
+NTSTATUS cli_unlock_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock(struct cli_state *cli,
+ uint16_t fnum,
+ uint32_t offset,
+ uint32_t len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
}
- return True;
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_unlock_send(frame, ev, cli,
+ fnum, offset, len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_unlock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
Unlock a file with 64 bit offsets.
****************************************************************************/
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct cli_unlock64_state {
+ uint16_t vwv[8];
+ uint8_t data[20];
+};
+
+static void cli_unlock64_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+
{
- char *p;
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct cli_unlock64_state *state = NULL;
+ uint8_t additional_flags = 0;
- if (! (cli->capabilities & CAP_LARGE_FILES)) {
- return cli_unlock(cli, fnum, offset, len);
+ req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state);
+ if (req == NULL) {
+ return NULL;
}
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ SCVAL(state->vwv+0, 0, 0xff);
+ SSVAL(state->vwv+2, 0, fnum);
+ SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES);
+ SIVALS(state->vwv+4, 0, 0);
+ SSVAL(state->vwv+6, 0, 1);
+ SSVAL(state->vwv+7, 0, 0);
- cli_set_message(cli->outbuf,8,0,True);
+ SIVAL(state->data, 0, cli->pid);
+ SOFF_T_R(state->data, 4, offset);
+ SOFF_T_R(state->data, 12, len);
- SCVAL(cli->outbuf,smb_com,SMBlockingX);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+ 8, state->vwv, 20, state->data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_unlock64_done, req);
+ return req;
+}
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,fnum);
- SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES);
- SIVALS(cli->outbuf, smb_vwv4, 0);
- SSVAL(cli->outbuf,smb_vwv6,1);
- SSVAL(cli->outbuf,smb_vwv7,0);
+static void cli_unlock64_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ NTSTATUS status;
- p = smb_buf(cli->outbuf);
- SIVAL(p, 0, cli->pid);
- SOFF_T_R(p, 4, offset);
- SOFF_T_R(p, 12, len);
- p += 20;
- cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return False;
+ status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- if (cli_is_error(cli)) {
- return False;
+NTSTATUS cli_unlock64_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock64(struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (! (cli->capabilities & CAP_LARGE_FILES)) {
+ return cli_unlock(cli, fnum, offset, len);
}
- return True;
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_unlock64_send(frame, ev, cli,
+ fnum, offset, len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_unlock64_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
Get/unlock a POSIX lock on a file - internal function.
****************************************************************************/
-static bool cli_posix_lock_internal(struct cli_state *cli, uint16_t fnum,
- uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type)
+struct posix_lock_state {
+ uint16_t setup;
+ uint8_t param[4];
+ uint8_t data[POSIX_LOCK_DATA_SIZE];
+};
+
+static void cli_posix_unlock_internal_done(struct tevent_req *subreq)
{
- unsigned int param_len = 4;
- unsigned int data_len = POSIX_LOCK_DATA_SIZE;
- uint16_t setup = TRANSACT2_SETFILEINFO;
- char param[4];
- unsigned char data[POSIX_LOCK_DATA_SIZE];
- char *rparam=NULL, *rdata=NULL;
- int saved_timeout = cli->timeout;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state);
+ NTSTATUS status;
- SSVAL(param,0,fnum);
- SSVAL(param,2,SMB_SET_POSIX_LOCK);
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ tevent_req_done(req);
+}
+static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct posix_lock_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct posix_lock_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
+
+ /* Setup param array. */
+ SSVAL(&state->param, 0, fnum);
+ SSVAL(&state->param, 2, SMB_SET_POSIX_LOCK);
+
+ /* Setup data array. */
switch (lock_type) {
case READ_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_READ);
break;
case WRITE_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_WRITE);
break;
case UNLOCK_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_UNLOCK);
break;
default:
- return False;
+ return NULL;
}
if (wait_lock) {
- SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT);
- cli->timeout = 0x7FFFFFFF;
+ SSVAL(&state->data, POSIX_LOCK_FLAGS_OFFSET,
+ POSIX_LOCK_FLAG_WAIT);
} else {
- SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT);
- }
-
- SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid);
- SOFF_T(data, POSIX_LOCK_START_OFFSET, offset);
- SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len);
+ SSVAL(state->data, POSIX_LOCK_FLAGS_OFFSET,
+ POSIX_LOCK_FLAG_NOWAIT);
+ }
+
+ SIVAL(&state->data, POSIX_LOCK_PID_OFFSET, cli->pid);
+ SOFF_T(&state->data, POSIX_LOCK_START_OFFSET, offset);
+ SOFF_T(&state->data, POSIX_LOCK_LEN_OFFSET, len);
+
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ 4, /* num param. */
+ 2, /* max returned param. */
+ state->data, /* data. */
+ POSIX_LOCK_DATA_SIZE, /* num data. */
+ 0); /* max returned data. */
- 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 */
- (char *)&data, data_len, cli->max_xmit /* data, length, max */
- )) {
- cli->timeout = saved_timeout;
- return False;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, ¶m_len,
- &rdata, &data_len)) {
- cli->timeout = saved_timeout;
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return False;
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
-
- cli->timeout = saved_timeout;
-
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
-
- return True;
+ tevent_req_set_callback(subreq, cli_posix_unlock_internal_done, req);
+ return req;
}
/****************************************************************************
POSIX Lock a file.
****************************************************************************/
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type)
+{
+ return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+ wait_lock, lock_type);
+}
+
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len,
bool wait_lock, enum brl_type lock_type)
{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) {
- return False;
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_lock_send(frame,
+ ev,
+ cli,
+ fnum,
+ offset,
+ len,
+ wait_lock,
+ lock_type);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_lock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
}
- return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type);
+ return status;
}
/****************************************************************************
POSIX Unlock a file.
****************************************************************************/
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
{
- return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK);
+ return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+ false, UNLOCK_LOCK);
}
-/****************************************************************************
- POSIX Get any lock covering a file.
-****************************************************************************/
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen)
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
{
- return True;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_unlock_send(frame,
+ ev,
+ cli,
+ fnum,
+ offset,
+ len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_unlock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
static void cli_setattrE_done(struct tevent_req *subreq);
struct cli_setattrE_state {
- int dummy;
+ uint16_t vwv[7];
};
struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req = NULL, *subreq = NULL;
struct cli_setattrE_state *state = NULL;
uint8_t additional_flags = 0;
- uint16_t vwv[7];
req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state);
if (req == NULL) {
return NULL;
}
- memset(vwv, '\0', sizeof(vwv));
- SSVAL(vwv+0, 0, fnum);
- cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time);
- cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time);
- cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time);
+ SSVAL(state->vwv+0, 0, fnum);
+ cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time);
+ cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time);
+ cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time);
subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
- 7, vwv, 0, NULL);
+ 7, state->vwv, 0, NULL);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
return NULL;
}
- memset(state->vwv, '\0', sizeof(state->vwv));
SSVAL(state->vwv+0, 0, attr);
cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);
}
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, &edata_contents);
+ asn1_read_OctetString(data, talloc_autofree_context(), &edata_contents);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_start_tag(data, ASN1_CONTEXT(1));
- asn1_read_OctetString(data, NULL, &pac_contents);
+ asn1_read_OctetString(data, talloc_autofree_context(), &pac_contents);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_start_tag(data,ASN1_SEQUENCE(0));
for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
const char *oid_str = NULL;
- asn1_read_OID(data,NULL,&oid_str);
+ asn1_read_OID(data,talloc_autofree_context(),&oid_str);
OIDs[i] = CONST_DISCARD(char *, oid_str);
}
OIDs[i] = NULL;
asn1_start_tag(data, ASN1_CONTEXT(3));
asn1_start_tag(data, ASN1_SEQUENCE(0));
asn1_start_tag(data, ASN1_CONTEXT(0));
- asn1_read_GeneralString(data,NULL,principal);
+ asn1_read_GeneralString(data,talloc_autofree_context(),principal);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_start_tag(data, ASN1_SEQUENCE(0));
for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
const char *oid_str = NULL;
- asn1_read_OID(data,NULL,&oid_str);
+ asn1_read_OID(data,talloc_autofree_context(),&oid_str);
OIDs[i] = CONST_DISCARD(char *, oid_str);
}
OIDs[i] = NULL;
}
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data,NULL,secblob);
+ asn1_read_OctetString(data,talloc_autofree_context(),secblob);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, chal1);
+ asn1_read_OctetString(data, talloc_autofree_context(), chal1);
asn1_end_tag(data);
/* the second challenge is optional (XP doesn't send it) */
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(3));
- asn1_read_OctetString(data, NULL, chal2);
+ asn1_read_OctetString(data, talloc_autofree_context(), chal2);
asn1_end_tag(data);
}
asn1_start_tag(data, ASN1_CONTEXT(1));
asn1_start_tag(data, ASN1_SEQUENCE(0));
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, auth);
+ asn1_read_OctetString(data, talloc_autofree_context(), auth);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, auth);
+ asn1_read_OctetString(data, talloc_autofree_context(), auth);
asn1_end_tag(data);
}
} else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) {
if (asn1_tag_remaining(data)) {
DATA_BLOB mechList = data_blob_null;
asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString(data, NULL, &mechList);
+ asn1_read_OctetString(data, talloc_autofree_context(), &mechList);
asn1_end_tag(data);
data_blob_free(&mechList);
DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
{
char *key;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
char *key;
bool ret = false;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
- if (gencache_lock_entry(key) != 0) {
- return NT_STATUS_LOCK_NOT_GRANTED;
- }
-
ret = gencache_set_data_blob(key, blob, expire_time);
- gencache_unlock_entry(key);
-
return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
struct GUID *domain_guid,
uint32_t flags,
const char *site_name,
- struct netr_DsRGetDCNameInfo **info_p,
- bool *expired)
+ struct netr_DsRGetDCNameInfo **info_p)
{
char *key;
DATA_BLOB blob;
struct NETLOGON_SAM_LOGON_RESPONSE_EX r;
NTSTATUS status;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
}
- if (!gencache_get_data_blob(key, &blob, expired)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!gencache_get_data_blob(key, &blob, NULL)) {
+ return NT_STATUS_NOT_FOUND;
}
info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo);
struct netr_DsRGetDCNameInfo **info)
{
NTSTATUS status;
- bool expired = false;
status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid,
- flags, site_name, info, &expired);
- if (!NT_STATUS_IS_OK(status)) {
+ flags, site_name, info);
+ if (!NT_STATUS_IS_OK(status)
+ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n",
nt_errstr(status)));
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
return status;
}
- if (expired) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
domain_name,
domain_guid, flags,
static void
SMBC_module_terminate(void)
{
- gencache_shutdown();
secrets_shutdown();
gfree_all();
SMBC_initialized = false;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <pthread.h>
#include "includes.h"
+#include <pthread.h>
#include "libsmbclient.h"
#include "libsmb_internal.h"
return False;
}
- /* Init namecache by calling gencache initialisation */
-
- if (!gencache_init()) {
- DEBUG(2, ("namecache_enable: "
- "Couldn't initialise namecache on top of gencache.\n"));
- return False;
- }
-
/* I leave it for now, though I don't think we really
* need this (mimir, 27.09.2002) */
DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
int i;
bool ret;
- /*
- * we use gecache call to avoid annoying debug messages about
- * initialised namecache again and again...
- */
- if (!gencache_init()) {
- return False;
- }
-
if (name_type > 255) {
return False; /* Don't store non-real name types. */
}
return False;
}
- if (!gencache_init()) {
- return False;
- }
-
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
}
bool ret;
char *key;
- if (!gencache_init())
- return False;
-
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
}
void namecache_flush(void)
{
- if (!gencache_init()) {
- return;
- }
-
/*
* iterate through each NBT cache's entry and flush it
* by flush_netbios_name function
time_t expiry;
bool ret;
- if (!gencache_init()) {
- return False;
- }
-
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
char *value = NULL;
time_t timeout;
- if (!gencache_init())
- return False;
-
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_key( domain );
expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key( domain );
expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key(domain);
ret = gencache_del(key);
SAFE_FREE(key);
return NULL;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key( domain );
ret = gencache_get( key, &server, &timeout );
asn1_start_tag(asn1, ASN1_CONTEXT(0));
asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- token->mechTypes = TALLOC_P(NULL, const char *);
+ token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *);
for (i = 0; !asn1->has_error &&
0 < asn1_tag_remaining(asn1); i++) {
const char *p_oid = NULL;
token->mechTypes =
- TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2);
+ TALLOC_REALLOC_ARRAY(talloc_autofree_context(),
+ token->mechTypes, const char *, i + 2);
if (!token->mechTypes) {
asn1->has_error = True;
return False;
}
- asn1_read_OID(asn1, NULL, &p_oid);
+ asn1_read_OID(asn1, talloc_autofree_context(), &p_oid);
token->mechTypes[i] = p_oid;
}
token->mechTypes[i] = NULL;
/* Read mechToken */
case ASN1_CONTEXT(2):
asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, NULL, &token->mechToken);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->mechToken);
asn1_end_tag(asn1);
break;
/* Read mecListMIC */
case ASN1_CONTEXT(3):
asn1_start_tag(asn1, ASN1_CONTEXT(3));
if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
- asn1_read_OctetString(asn1, NULL,
+ asn1_read_OctetString(asn1, talloc_autofree_context(),
&token->mechListMIC);
} else {
/* RFC 2478 says we have an Octet String here,
char *mechListMIC;
asn1_push_tag(asn1, ASN1_SEQUENCE(0));
asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_read_GeneralString(asn1, NULL, &mechListMIC);
+ asn1_read_GeneralString(asn1,
+ talloc_autofree_context(), &mechListMIC);
asn1_pop_tag(asn1);
asn1_pop_tag(asn1);
case ASN1_CONTEXT(1): {
const char *mech = NULL;
asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_OID(asn1, NULL, &mech);
+ asn1_read_OID(asn1, talloc_autofree_context(), &mech);
asn1_end_tag(asn1);
token->supportedMech = CONST_DISCARD(char *, mech);
}
break;
case ASN1_CONTEXT(2):
asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, NULL, &token->responseToken);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->responseToken);
asn1_end_tag(asn1);
break;
case ASN1_CONTEXT(3):
asn1_start_tag(asn1, ASN1_CONTEXT(3));
- asn1_read_OctetString(asn1, NULL, &token->mechListMIC);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->mechListMIC);
asn1_end_tag(asn1);
break;
default:
Trusted domain names cache on top of gencache.
Copyright (C) Rafal Szczesniak 2002
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* list of trusted domains
**/
-
/**
* Initialise trustdom name caching system. Call gencache
* initialisation routine to perform necessary activities.
* @return true upon successful cache initialisation or
* false if cache init failed
**/
-
+
bool trustdom_cache_enable(void)
{
- /* Init trustdom cache by calling gencache initialisation */
- if (!gencache_init()) {
- DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
- return False;
- }
-
return True;
}
* @return true upon successful cache close or
* false if it failed
**/
-
+
bool trustdom_cache_shutdown(void)
{
- /* Close trustdom cache by calling gencache shutdown */
- if (!gencache_shutdown()) {
- DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
- return False;
- }
-
return True;
}
{
char* keystr = NULL;
asprintf_strupper_m(&keystr, TDOMKEY_FMT, name);
-
+
return keystr;
}
fstring sid_string;
bool ret;
- /*
- * we use gecache call to avoid annoying debug messages
- * about initialised trustdom
- */
- if (!gencache_init())
- return False;
-
DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
sid_string_dbg(sid), name));
* @return true if entry is found or
* false if has expired/doesn't exist
**/
-
+
bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
{
char *key = NULL, *value = NULL;
time_t timeout;
- /* init the cache */
- if (!gencache_init())
- return False;
-
/* exit now if null pointers were passed as they're required further */
if (!sid)
return False;
key = trustdom_cache_key(name);
if (!key)
return False;
-
+
if (!gencache_get(key, &value, &timeout)) {
DEBUG(5, ("no entry for trusted domain %s found.\n", name));
SAFE_FREE(key);
SAFE_FREE(value);
return False;
}
-
+
SAFE_FREE(value);
return True;
}
time_t timeout;
uint32 timestamp;
- /* init the cache */
- if (!gencache_init())
- return False;
-
if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
SAFE_FREE(value);
}
timestamp = atoi(value);
-
+
SAFE_FREE(value);
return timestamp;
}
{
fstring value;
- /* init the cache */
- if (!gencache_init())
- return False;
-
fstr_sprintf(value, "%d", t );
-
+
if (!gencache_set(TDOMTSKEY, value, timeout)) {
DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
return False;
void trustdom_cache_flush(void)
{
- if (!gencache_init())
- return;
-
/*
* iterate through each TDOM cache's entry and flush it
* by flush_trustdom_name function
TALLOC_CTX *mem_ctx = NULL;
time_t now = time(NULL);
int i;
-
+
/* get the timestamp. We have to initialise it if the last timestamp == 0 */
if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 )
trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
time_diff = (int) (now - last_check);
-
+
if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
return;
smbd from blocking all other smbd daemons while we
enumerate the trusted domains */
trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL);
-
+
if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
goto done;
}
/* get the domains and store them */
-
+
if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names,
&num_domains, &dom_sids)) {
for ( i=0; i<num_domains; i++ ) {
done:
talloc_destroy( mem_ctx );
-
+
return;
}
DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
(double)start, (double)size, ret ? "locked" : "unlocked",
- fsp->fnum, fsp->fsp_name ));
+ fsp->fnum, fsp_str_dbg(fsp)));
/* We need to return the inverse of is_posix_locked. */
ret = !ret;
DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
(double)*pstart, (double)*psize, ret ? "locked" : "unlocked",
- fsp->fnum, fsp->fsp_name ));
+ fsp->fnum, fsp_str_dbg(fsp)));
if (ret) {
/* Hmmm. No clue what to set smbpid to - use -1. */
if (strict_locking == Auto) {
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
- DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
+ DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
ret = True;
} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
(plock->lock_type == READ_LOCK)) {
- DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
+ DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
ret = True;
} else {
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
lock_flav_name(plock->lock_flav),
(double)plock->start, (double)plock->size,
ret ? "unlocked" : "locked",
- plock->fnum, fsp->fsp_name ));
+ plock->fnum, fsp_str_dbg(fsp)));
return ret;
}
"blocking_lock=%s requested for fnum %d file %s\n",
lock_flav_name(lock_flav), lock_type_name(lock_type),
(double)offset, (double)count, blocking_lock ? "true" :
- "false", fsp->fnum, fsp->fsp_name));
+ "false", fsp->fnum, fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
}
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
- (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+ (double)offset, (double)count, fsp->fnum,
+ fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
}
DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
- (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+ (double)offset, (double)count, fsp->fnum,
+ fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
!lp_delete_readonly(SNUM(fsp->conn))) {
DEBUG(10,("can_set_delete_on_close: file %s delete on close "
"flag set but file attribute is readonly.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_CANNOT_DELETE;
}
if (!CAN_WRITE(fsp->conn)) {
DEBUG(10,("can_set_delete_on_close: file %s delete on "
"close flag set but write access denied on share.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_ACCESS_DENIED;
}
if (!(fsp->access_mask & DELETE_ACCESS)) {
DEBUG(10,("can_set_delete_on_close: file %s delete on "
"close flag set but delete access denied.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_ACCESS_DENIED;
}
/* Don't allow delete on close for non-empty directories. */
if (fsp->is_directory) {
- return can_delete_directory(fsp->conn, fsp->fsp_name);
+ SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+ return can_delete_directory(fsp->conn,
+ fsp->fsp_name->base_name);
}
return NT_STATUS_OK;
DEBUG(10,("set_delete_on_close: %s delete on close flag for "
"fnum = %d, file %s\n",
delete_on_close ? "Adding" : "Removing", fsp->fnum,
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
NULL);
set_delete_on_close_lck(lck, delete_on_close, tok);
if (fsp->is_directory) {
- send_stat_cache_delete_message(fsp->fsp_name);
+ SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+ send_stat_cache_delete_message(fsp->fsp_name->base_name);
}
TALLOC_FREE(lck);
SMB_OFF_T count;
int posix_lock_type = map_posix_lock_type(fsp,*plock_type);
- DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) ));
+ DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, "
+ "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset,
+ (double)*pu_count, posix_lock_type_name(*plock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
TALLOC_FREE(rec);
DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
}
/****************************************************************************
TALLOC_FREE(rec);
DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
}
static void decrement_windows_lock_ref_count(files_struct *fsp)
}
DEBUG(10,("get_windows_lock_count for file %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
return lock_ref_count;
}
TALLOC_FREE(rec);
DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
}
/****************************************************************************
TALLOC_FREE(rec);
DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
- fsp->fh->fd, fsp->fsp_name ));
+ fsp->fh->fd, fsp_str_dbg(fsp)));
}
/****************************************************************************
struct lock_list *llist = NULL;
struct lock_list *ll = NULL;
- DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/* Remember the number of Windows locks we have on this dev/ino pair. */
decrement_windows_lock_ref_count(fsp);
SMB_OFF_T count;
int posix_lock_type = map_posix_lock_type(fsp,lock_type);
- DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count "
+ "= %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/*
* If the requested lock won't fit in the POSIX range, we will
memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
if (fsp->is_directory || fsp->fh->fd == -1) {
- return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf);
+ return smbacl4_GetFileOwner(fsp->conn,
+ fsp->fsp_name->base_name, psbuf);
}
if (SMB_VFS_FSTAT(fsp, psbuf) != 0)
{
{
SMB_STRUCT_STAT sbuf;
- DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+ DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
return map_nt_error_from_unix(errno);
gid_t newGID = (gid_t)-1;
int saved_errno;
- DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+ DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
if ((security_info_sent & (DACL_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0)
}
if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- if(try_chown(fsp->conn, smb_fname, newUID, newGID)) {
- DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
+ if(try_chown(fsp->conn, fsp->fsp_name, newUID,
+ newGID)) {
+ DEBUG(3,("chown %s, %u, %u failed. Error = "
+ "%s.\n", fsp_str_dbg(fsp),
+ (unsigned int)newUID,
+ (unsigned int)newGID,
strerror(errno)));
- TALLOC_FREE(smb_fname);
return map_nt_error_from_unix(errno);
}
- TALLOC_FREE(smb_fname);
DEBUG(10,("chown %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
- if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
+ fsp_str_dbg(fsp), (unsigned int)newUID,
+ (unsigned int)newGID));
+ if (smbacl4_GetFileOwner(fsp->conn,
+ fsp->fsp_name->base_name,
+ &sbuf))
return map_nt_error_from_unix(errno);
/* If we successfully chowned, we know we must
return NT_STATUS_OK;
}
- theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms,
+ theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, ¶ms,
sbuf.st_ex_uid, sbuf.st_ex_gid);
if (!theacl)
return map_nt_error_from_unix(errno);
if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
DEBUG(10, ("Did not canonicalize ACLs because a "
- "Windows ACL set was found for file %s\n",
- fsp->fsp_name));
+ "Windows ACL set was found for file %s\n",
+ fsp_str_dbg(fsp)));
return true;
}
break;
SMB_ASSERT(new_aces_count == sd->dacl->num_aces);
DEBUG(10, ("Performed canonicalization of ACLs for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/*
* At this point you would think we could just do this:
if (error) {
DEBUG(0, ("Failed to stat %s in simple files sharing "
"compatibility mode. errno=%d\n",
- fsp->fsp_name, errno));
+ fsp_str_dbg(fsp), errno));
return false;
}
/* Only continue if this is a synthetic ACL and a directory. */
if (S_ISDIR(sbuf.st_ex_mode) &&
(sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
- struct smb_filename *smb_fname = NULL;
struct ifs_ace new_aces[6];
struct ifs_ace *old_aces;
int i, num_aces_to_add = 0;
mode_t file_mode = 0, dir_mode = 0;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
/* Use existing samba logic to derive the mode bits. */
- file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL);
- dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL);
-
- TALLOC_FREE(smb_fname);
+ file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL);
+ dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, NULL);
/* Initialize ACEs. */
new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
*ppdesc = NULL;
DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
- fsp->fsp_name, security_info));
+ fsp_str_dbg(fsp), security_info));
if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
- DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name));
+ DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp)));
security_info &= ~SACL_SECURITY_INFORMATION;
}
if (fsp->fh->fd == -1) {
if ((fsp->fh->fd = onefs_sys_create_file(handle->conn,
-1,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
0,
0,
0,
0,
NULL)) == -1) {
DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
- fsp->fsp_name, errno, strerror(errno)));
+ fsp_str_dbg(fsp), errno, strerror(errno)));
status = map_nt_error_from_unix(errno);
goto out;
}
{
files_struct finfo;
struct fd_handle fh;
+ NTSTATUS status;
ZERO_STRUCT(finfo);
ZERO_STRUCT(fh);
finfo.conn = handle->conn;
finfo.fh = &fh;
finfo.fh->fd = -1;
- finfo.fsp_name = CONST_DISCARD(char *, name);
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &finfo.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+ status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+
+ TALLOC_FREE(finfo.fsp_name);
+ return status;
}
/**
START_PROFILE(syscall_set_sd);
- DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
+ DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp)));
status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd,
SNUM(handle->conn), &sec_info_effective);
fd = fsp->fh->fd;
if (fd == -1) {
- DEBUG(10,("Reopening file %s.\n", fsp->fsp_name));
+ DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp)));
if ((fd = onefs_sys_create_file(handle->conn,
-1,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
0,
0,
0,
0,
NULL)) == -1) {
DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
- fsp->fsp_name, errno, strerror(errno)));
+ fsp_str_dbg(fsp), errno, strerror(errno)));
status = map_nt_error_from_unix(errno);
goto out;
}
struct security_descriptor *sd,
int *granted_oplock)
{
- char *path = NULL;
struct smb_filename *smb_fname_onefs = NULL;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
* wildcard characters are allowed in stream names
* only test the basefilename
*/
- wild = fsp->base_fsp->fsp_name;
+ wild = fsp->base_fsp->fsp_name->base_name;
} else {
wild = smb_fname->base_name;
}
fsp->aio_write_behind = True;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &path);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ errno = map_errno_from_nt_status(status);
return status;
}
- string_set(&fsp->fsp_name, path);
- TALLOC_FREE(path);
-
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
fsp->is_directory = True;
fsp->posix_open = posix_open;
- string_set(&fsp->fsp_name, smb_dname->base_name);
+ status = fsp_set_smb_fname(fsp, smb_dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ file_free(req, fsp);
+ return status;
+ }
mtimespec = smb_dname->st.st_ex_mtime;
}
}
- onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf);
+ onefs_adjust_stat_time(handle->conn, fsp->fsp_name->base_name, sbuf);
return ret;
}
fake_fs.conn = conn;
fake_fs.fh = &fake_fh;
- fake_fs.fsp_name = SMB_STRDUP(fname);
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+ &fake_fs.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
/* Iterate over the streams in the ADS directory. */
while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) {
close(base_fd);
}
- SAFE_FREE(fake_fs.fsp_name);
+ TALLOC_FREE(fake_fs.fsp_name);
return status;
}
{
uint8 id_buf[16];
struct file_id id;
- SMB_STRUCT_STAT sbuf;
TDB_DATA data;
struct db_context *db;
struct db_record *rec;
int ret = -1;
DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
- (unsigned int)pblob->length, fsp->fsp_name));
+ (unsigned int)pblob->length, fsp_str_dbg(fsp)));
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
return NT_STATUS_INTERNAL_DB_CORRUPTION);
if (fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
} else {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn, fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(handle->conn, fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name);
}
}
return map_nt_error_from_unix(errno);
}
- id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+ id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st);
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
NTSTATUS status;
if (fsp && name == NULL) {
- name = fsp->fsp_name;
+ name = fsp->fsp_name->base_name;
}
DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name));
*********************************************************************/
static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
bool container)
{
size_t size;
char *parent_name;
- if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+ if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
return NT_STATUS_NO_MEMORY;
}
}
if (!psd || psd->dacl == NULL) {
- SMB_STRUCT_STAT sbuf;
int ret;
TALLOC_FREE(psd);
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
} else {
if (fsp && fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn,fname,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(handle->conn,fname,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
}
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
- psd = default_file_sd(ctx, &sbuf);
+ psd = default_file_sd(ctx, &smb_fname->st);
if (!psd) {
return NT_STATUS_NO_MEMORY;
}
if (fsp) {
return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle, fname, &blob);
+ return store_acl_blob_pathname(handle, smb_fname->base_name,
+ &blob);
}
}
uint32_t access_granted = 0;
struct security_descriptor *pdesc = NULL;
bool file_existed = true;
- char *fname = NULL;
NTSTATUS status;
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
status = get_nt_acl_tdb_internal(handle,
NULL,
- fname,
+ smb_fname->base_name,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION),
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
- string_set(&fsp->fsp_name, fname);
- inherit_new_acl(handle, fname, fsp, false);
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ inherit_new_acl(handle, smb_fname, fsp, false);
}
-
return fsp->fh->fd;
}
static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode)
{
+ struct smb_filename *smb_fname = NULL;
int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+ NTSTATUS status;
if (ret == -1) {
return ret;
}
+
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
/* New directory - inherit from parent. */
- inherit_new_acl(handle, path, NULL, true);
+ inherit_new_acl(handle, smb_fname, NULL, true);
+ TALLOC_FREE(smb_fname);
return ret;
}
if (NT_STATUS_IS_OK(status)) {
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fget_nt_acl_tdb: returning tdb sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
}
return NT_STATUS_OK;
}
DEBUG(10,("fget_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n",
- fsp->fsp_name,
- nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
security_info, ppdesc);
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
/* Ensure owner and group are set. */
if (!psd->owner_sid || !psd->group_sid) {
int ret;
- SMB_STRUCT_STAT sbuf;
DOM_SID owner_sid, group_sid;
struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
}
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
/* Lower level acl set succeeded,
* so still return OK. */
return NT_STATUS_OK;
}
- create_file_sids(&sbuf, &owner_sid, &group_sid);
+ create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
/* This is safe as nc_psd is discarded at fn exit. */
nc_psd->owner_sid = &owner_sid;
nc_psd->group_sid = &group_sid;
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
files_struct *fsp,
SMB_ACL_T theacl)
{
- SMB_STRUCT_STAT sbuf;
struct db_context *db;
int ret;
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
return -1;
return -1;
}
- acl_tdb_delete(handle, db, &sbuf);
+ acl_tdb_delete(handle, db, &fsp->fsp_name->st);
return 0;
}
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+ DATA_BLOB *pblob,
+ uint8_t hash[16]);
+
+#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
+ GROUP_SECURITY_INFORMATION | \
+ DACL_SECURITY_INFORMATION | \
+ SACL_SECURITY_INFORMATION)
+
+/*******************************************************************
+ Hash a security descriptor.
+*******************************************************************/
+
+static NTSTATUS hash_sd(struct security_descriptor *psd,
+ uint8_t hash[16])
+{
+ DATA_BLOB blob;
+ struct MD5Context tctx;
+ NTSTATUS status;
+
+ memset(hash, '\0', 16);
+ status = create_acl_blob(psd, &blob, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ MD5Init(&tctx);
+ MD5Update(&tctx, blob.data, blob.length);
+ MD5Final(hash, &tctx);
+ return NT_STATUS_OK;
+}
+
/*******************************************************************
Parse out a struct security_descriptor from a DATA_BLOB.
*******************************************************************/
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
uint32 security_info,
- struct security_descriptor **ppdesc)
+ struct security_descriptor **ppdesc,
+ uint8_t hash[16])
{
TALLOC_CTX *ctx = talloc_tos();
struct xattr_NTACL xacl;
? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
+ memcpy(hash, xacl.info.sd_hs->hash, 16);
TALLOC_FREE(xacl.info.sd);
return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
Create a DATA_BLOB from a security descriptor.
*******************************************************************/
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+ DATA_BLOB *pblob,
+ uint8_t hash[16])
{
struct xattr_NTACL xacl;
struct security_descriptor_hash sd_hs;
xacl.version = 2;
xacl.info.sd_hs = &sd_hs;
xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd);
- memset(&xacl.info.sd_hs->hash[0], '\0', 16);
+ memcpy(&xacl.info.sd_hs->hash[0], hash, 16);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,
int saved_errno = 0;
DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
- (unsigned int)pblob->length, fsp->fsp_name));
+ (unsigned int)pblob->length, fsp_str_dbg(fsp)));
become_root();
if (fsp->fh->fd != -1) {
ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
}
errno = saved_errno;
DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
"with error %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
strerror(errno) ));
return map_nt_error_from_unix(errno);
}
uint32 security_info,
struct security_descriptor **ppdesc)
{
- TALLOC_CTX *ctx = talloc_tos();
DATA_BLOB blob;
NTSTATUS status;
+ uint8_t hash[16];
+ uint8_t hash_tmp[16];
+ struct security_descriptor *pdesc_next = NULL;
if (fsp && name == NULL) {
- name = fsp->fsp_name;
+ name = fsp->fsp_name->base_name;
}
DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name));
- status = get_acl_blob(ctx, handle, fsp, name, &blob);
+ status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
return status;
}
- status = parse_acl_blob(&blob, security_info, ppdesc);
+ status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("parse_acl_blob returned %s\n",
nt_errstr(status)));
return status;
}
+ /* If there was no stored hash, don't check. */
+ memset(&hash_tmp[0], '\0', 16);
+ if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+ /* No hash, goto return blob sd. */
+ goto out;
+ }
+
+ /* Get the full underlying sd, then hash. */
+ if (fsp) {
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ } else {
+ status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+ name,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = hash_sd(pdesc_next, hash_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+ TALLOC_FREE(pdesc_next);
+ /* Hash matches, return blob sd. */
+ goto out;
+ }
+
+ /* Hash doesn't match, return underlying sd. */
+
+ if (!(security_info & OWNER_SECURITY_INFORMATION)) {
+ pdesc_next->owner_sid = NULL;
+ }
+ if (!(security_info & GROUP_SECURITY_INFORMATION)) {
+ pdesc_next->group_sid = NULL;
+ }
+ if (!(security_info & DACL_SECURITY_INFORMATION)) {
+ pdesc_next->dacl = NULL;
+ }
+ if (!(security_info & SACL_SECURITY_INFORMATION)) {
+ pdesc_next->sacl = NULL;
+ }
+
+ TALLOC_FREE(*ppdesc);
+ *ppdesc = pdesc_next;
+
+ out:
+
TALLOC_FREE(blob.data);
return status;
}
*********************************************************************/
static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
bool container)
{
NTSTATUS status;
struct security_descriptor *parent_desc = NULL;
struct security_descriptor *psd = NULL;
+ struct security_descriptor *pdesc_next = NULL;
DATA_BLOB blob;
size_t size;
char *parent_name;
+ uint8_t hash[16];
- if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+ if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
return NT_STATUS_NO_MEMORY;
}
}
if (!psd || psd->dacl == NULL) {
- SMB_STRUCT_STAT sbuf;
int ret;
TALLOC_FREE(psd);
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
} else {
if (fsp && fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn, fname,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(handle->conn, fname,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
}
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
- psd = default_file_sd(ctx, &sbuf);
+ psd = default_file_sd(ctx, &smb_fname->st);
if (!psd) {
return NT_STATUS_NO_MEMORY;
}
}
}
- status = create_acl_blob(psd, &blob);
+ /* Object exists. Read the current SD to get the hash. */
+ if (fsp) {
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ } else {
+ status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+ smb_fname->base_name,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = hash_sd(pdesc_next, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = create_acl_blob(psd, &blob, hash);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (fsp) {
return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle, fname, &blob);
+ return store_acl_blob_pathname(handle, smb_fname->base_name,
+ &blob);
}
}
char *fname = NULL;
NTSTATUS status;
+ if (fsp->base_fsp) {
+ /* Stream open. Base filename open already did the ACL check. */
+ DEBUG(10,("open_acl_xattr: stream open on %s\n",
+ smb_fname_str_dbg(smb_fname) ));
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ }
+
status = get_full_smb_filename(talloc_tos(), smb_fname,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
- string_set(&fsp->fsp_name, fname);
- inherit_new_acl(handle, fname, fsp, false);
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ inherit_new_acl(handle, smb_fname, fsp, false);
}
return fsp->fh->fd;
static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode)
{
+ struct smb_filename *smb_fname = NULL;
int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+ NTSTATUS status;
if (ret == -1) {
return ret;
}
+
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
/* New directory - inherit from parent. */
- inherit_new_acl(handle, path, NULL, true);
+ inherit_new_acl(handle, smb_fname, NULL, true);
+ TALLOC_FREE(smb_fname);
return ret;
}
static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, struct security_descriptor **ppdesc)
{
- NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
+ return get_nt_acl_xattr_internal(handle, fsp,
NULL, security_info, ppdesc);
- if (NT_STATUS_IS_OK(status)) {
- if (DEBUGLEVEL >= 10) {
- DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n",
- fsp->fsp_name));
- NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
- }
- return NT_STATUS_OK;
- }
-
- DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
- fsp->fsp_name,
- nt_errstr(status) ));
-
- return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
- security_info, ppdesc);
}
/*********************************************************************
static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
const char *name, uint32 security_info, struct security_descriptor **ppdesc)
{
- NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
+ return get_nt_acl_xattr_internal(handle, NULL,
name, security_info, ppdesc);
- if (NT_STATUS_IS_OK(status)) {
- if (DEBUGLEVEL >= 10) {
- DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n",
- name));
- NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
- }
- return NT_STATUS_OK;
- }
-
- DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
- name,
- nt_errstr(status) ));
-
- return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
- security_info, ppdesc);
}
/*********************************************************************
{
NTSTATUS status;
DATA_BLOB blob;
+ struct security_descriptor *pdesc_next = NULL;
+ uint8_t hash[16];
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
- status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
/* Ensure owner and group are set. */
if (!psd->owner_sid || !psd->group_sid) {
int ret;
- SMB_STRUCT_STAT sbuf;
DOM_SID owner_sid, group_sid;
struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
}
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
/* Lower level acl set succeeded,
* so still return OK. */
return NT_STATUS_OK;
}
- create_file_sids(&sbuf, &owner_sid, &group_sid);
+ create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
/* This is safe as nc_psd is discarded at fn exit. */
nc_psd->owner_sid = &owner_sid;
nc_psd->group_sid = &group_sid;
psd = nc_psd;
}
+ status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* Get the full underlying sd, then hash. */
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = hash_sd(pdesc_next, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
#if 0
if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
psd->dacl != NULL &&
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
- create_acl_blob(psd, &blob);
+ create_acl_blob(psd, &blob, hash);
store_acl_blob_fsp(handle, fsp, &blob);
return NT_STATUS_OK;
static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
struct connection_struct *conn,
- const char *name,
+ struct smb_filename *smb_fname,
uint32 security_info,
struct security_descriptor **ppdesc)
{
- SMB_STRUCT_STAT sbuf;
-
/* Get the stat struct for the owner info. */
- if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
+ if(SMB_VFS_STAT(conn, smb_fname) != 0) {
return 0;
}
- return afs_to_nt_acl_common(afs_acl, &sbuf, security_info, ppdesc);
+ return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info,
+ ppdesc);
}
static size_t afs_fto_nt_acl(struct afs_acl *afs_acl,
ZERO_STRUCT(dir_acl);
ZERO_STRUCT(file_acl);
- name = talloc_strdup(talloc_tos(), fsp->fsp_name);
+ name = talloc_strdup(talloc_tos(), fsp->fsp_name->base_name);
if (!name) {
return NT_STATUS_NO_MEMORY;
}
}
if (!afs_get_afs_acl(name, &old_afs_acl)) {
- DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name));
+ DEBUG(3, ("Could not get old ACL of %s\n", fsp_str_dbg(fsp)));
goto done;
}
}
free_afs_acl(&dir_acl);
- if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+ if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+ security_info_sent, psd,
nt_to_afs_dir_rights, &dir_acl))
goto done;
} else {
}
free_afs_acl(&file_acl);
- if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+ if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+ security_info_sent, psd,
nt_to_afs_file_rights, &file_acl))
goto done;
}
struct afs_acl acl;
size_t sd_size;
- DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp->fsp_name));
+ DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp_str_dbg(fsp)));
sidpts = lp_parm_bool(SNUM(fsp->conn), "afsacl", "sidpts", False);
- if (!afs_get_afs_acl(fsp->fsp_name, &acl)) {
+ if (!afs_get_afs_acl(fsp->fsp_name->base_name, &acl)) {
return NT_STATUS_ACCESS_DENIED;
}
{
struct afs_acl acl;
size_t sd_size;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
DEBUG(5, ("afsacl_get_nt_acl: %s\n", name));
return NT_STATUS_ACCESS_DENIED;
}
- sd_size = afs_to_nt_acl(&acl, handle->conn, name, security_info,
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ free_afs_acl(&acl);
+ return status;
+ }
+
+ sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info,
ppdesc);
+ TALLOC_FREE(smb_fname);
free_afs_acl(&acl);
bool retryPosix = False;
*ppdesc = NULL;
- result = aixjfs2_get_nfs4_acl(fsp->fsp_name, &pacl, &retryPosix);
+ result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl,
+ &retryPosix);
if (retryPosix)
{
DEBUG(10, ("retrying with posix acl...\n"));
acl_type_t aixjfs2_type;
aixjfs2_type.u64 = ACL_AIXC;
- return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type);
+ return aixjfs2_get_posix_acl(fsp->fsp_name->base_name, aixjfs2_type);
}
/*
int rc;
acl_type_t acltype;
- DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name));
+ DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp)));
/* no need to be freed which is alloced with mem_ctx */
mem_ctx = talloc_tos();
/* won't set S_ISUID - the only one JFS2/NFS4 accepts */
rc = aclx_put(
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
SET_ACL, /* set only the ACL, not mode bits */
acltype, /* not a pointer !!! */
jfs2acl,
acl_type_t acl_type_info;
int rc;
- DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name));
+ DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp_str_dbg(fsp)));
- rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info);
+ rc = aixjfs2_query_acl_support(fsp->fsp_name->base_name, ACL_AIXC,
+ &acl_type_info);
if (rc) {
DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
return -1;
);
if (rc) {
DEBUG(2, ("aclx_fput failed with %s for %s\n",
- strerror(errno), fsp->fsp_name));
+ strerror(errno), fsp_str_dbg(fsp)));
return -1;
}
result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
DEBUG(module_debug,
("%s: doing readahead of %lld bytes at %lld for %s\n",
MODULE, (long long)g_readsz, (long long)*last,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last);
if (nread < 0) {
return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
}
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
SMB_STRUCT_DIRENT *newdirent;
}
-static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
+ const char *newpath)
{
char *capold = capencode(talloc_tos(), oldpath);
char *capnew = capencode(talloc_tos(), newpath);
return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
}
-static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle, const char *path,
+ char *buf, size_t bufsiz)
{
char *cappath = capencode(talloc_tos(), path);
}
static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result = NULL;
SMB_STRUCT_DIRENT *newdirent = NULL;
struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_open);
- /*
- * XXX: Should an error be returned if there is a stream rather than
- * trying to open a filename with a ':'?
- */
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_open(fname, flags, mode);
-
- TALLOC_FREE(fname);
-
+ result = sys_open(smb_fname->base_name, flags, mode);
+ out:
END_PROFILE(syscall_open);
return result;
}
static int vfswrap_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_stat);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_stat(fname, &smb_fname->st);
-
- TALLOC_FREE(fname);
-
+ result = sys_stat(smb_fname->base_name, &smb_fname->st);
+ out:
END_PROFILE(syscall_stat);
return result;
}
static int vfswrap_lstat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_lstat);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_lstat(fname, &smb_fname->st);
-
- TALLOC_FREE(fname);
-
+ result = sys_lstat(smb_fname->base_name, &smb_fname->st);
+ out:
END_PROFILE(syscall_lstat);
return result;
}
uint64_t space_avail;
uint64_t bsize,dfree,dsize;
- space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+ space_avail = get_dfree_info(fsp->conn,
+ fsp->fsp_name->base_name, false,
+ &bsize, &dfree, &dsize);
/* space_avail is 1k blocks */
if (space_avail == (uint64_t)-1 ||
((uint64_t)space_to_write/1024 > space_avail) ) {
return NT_STATUS_OK;
}
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
+ unsigned int flags)
{
#ifdef HAVE_CHFLAGS
return chflags(path, flags);
}
static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
- SMB_STRUCT_STAT *sbuf)
+ const SMB_STRUCT_STAT *sbuf)
{
struct file_id key;
}
static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
struct dirsort_privates *data = NULL;
time_t current_mtime;
if (lp_syslog() > 0) {
syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
- fsp->fsp_name, (unsigned int)mode,
+ fsp_str_dbg(fsp), (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
if (lp_syslog() > 0) {
syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
- fsp->fsp_name, (unsigned int)mode,
+ fsp_str_dbg(fsp), (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
return fname;
}
+/**
+ * Return an fsp debug string using the do_log_ctx()
+ */
+static const char *fsp_str_do_log(const struct files_struct *fsp)
+{
+ return smb_fname_str_do_log(fsp->fsp_name);
+}
/* Free function for the private data. */
return result;
}
-static int smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
{
int result;
result = SMB_VFS_NEXT_CLOSE(handle, fsp);
- do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
- do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
- do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
- do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
do_log(SMB_VFS_OP_LSEEK, (result != (ssize_t)-1), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n);
do_log(SMB_VFS_OP_SENDFILE, (result >= 0), handle,
- "%s", fromfsp->fsp_name);
+ "%s", fsp_str_do_log(fromfsp));
return result;
}
result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n);
do_log(SMB_VFS_OP_RECVFILE, (result >= 0), handle,
- "%s", tofsp->fsp_name);
+ "%s", fsp_str_do_log(tofsp));
return result;
}
result = SMB_VFS_NEXT_FSYNC(handle, fsp);
- do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
return result;
}
-static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
+static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
{
int result;
result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle,
- "%s|%o", fsp->fsp_name, mode);
+ "%s|%o", fsp_str_do_log(fsp), mode);
return result;
}
result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
do_log(SMB_VFS_OP_FCHOWN, (result >= 0), handle, "%s|%ld|%ld",
- fsp->fsp_name, (long int)uid, (long int)gid);
+ fsp_str_do_log(fsp), (long int)uid, (long int)gid);
return result;
}
result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len);
do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
- do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode);
do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s",
- fsp->fsp_name);
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s",
- fsp->fsp_name);
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
- do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp_str_do_log(fsp));
return result;
}
blocking_lock, blr);
do_log(SMB_VFS_OP_BRL_LOCK_WINDOWS, NT_STATUS_IS_OK(result), handle,
- "%s:%llu-%llu. type=%d. blocking=%d", br_lck->fsp->fsp_name,
+ "%s:%llu-%llu. type=%d. blocking=%d", fsp_str_do_log(br_lck->fsp),
plock->start, plock->size, plock->lock_type, blocking_lock );
return result;
plock);
do_log(SMB_VFS_OP_BRL_UNLOCK_WINDOWS, (result == 0), handle,
- "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
plock->size, plock->lock_type);
return result;
result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr);
do_log(SMB_VFS_OP_BRL_CANCEL_WINDOWS, (result == 0), handle,
- "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
plock->size);
return result;
result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
do_log(SMB_VFS_OP_STRICT_LOCK, result, handle,
- "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
plock->size);
return result;
SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle,
- "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
plock->size);
return;
result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc);
do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
- do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle,
- "%s|%o", fsp->fsp_name, mode);
+ "%s|%o", fsp_str_do_log(fsp), mode);
return result;
}
result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
do_log(SMB_VFS_OP_SYS_ACL_SET_FD, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
do_log(SMB_VFS_OP_FGETXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
do_log(SMB_VFS_OP_FLISTXATTR, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
do_log(SMB_VFS_OP_FREMOVEXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
do_log(SMB_VFS_OP_FSETXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb);
do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts);
do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
do_log(SMB_VFS_OP_AIO_FORCE, result, handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
int result;
*ppdesc = NULL;
- result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl);
+ result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
if (result == 0)
return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl);
"merge_writeappend", True)) {
DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
"WRITE^APPEND, setting WRITE|APPEND\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
}
gacl->acl_nace++;
}
- ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
+ ret = smbd_gpfs_putacl(fsp->fsp_name->base_name,
+ GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
if (ret != 0) {
DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno)));
gpfs_dumpacl(8, gacl);
struct gpfs_acl *acl;
NTSTATUS result = NT_STATUS_ACCESS_DENIED;
- acl = gpfs_getacl_alloc(fsp->fsp_name, 0);
+ acl = gpfs_getacl_alloc(fsp->fsp_name->base_name, 0);
if (acl == NULL)
return result;
if (acl->acl_version&GPFS_ACL_VERSION_NFS4)
{
+ if ((psd->type&SEC_DESC_DACL_PROTECTED)) {
+ DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
result = smb_set_nt_acl_nfs4(
fsp, security_info_sent, psd,
gpfsacl_process_smbacl);
static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
files_struct *fsp)
{
- return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
+ return gpfsacl_get_posix_acl(fsp->fsp_name->base_name,
+ GPFS_ACL_TYPE_ACCESS);
}
static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
files_struct *fsp,
SMB_ACL_T theacl)
{
- return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl);
+ return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name->base_name,
+ SMB_ACL_TYPE_ACCESS, theacl);
}
static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
int i;
files_struct fake_fsp; /* TODO: rationalize parametrization */
SMB4ACE_T *smbace;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode));
/* don't add complementary DENY ACEs here */
ZERO_STRUCT(fake_fsp);
- fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */
-
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &fake_fsp.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
/* put the acl */
- if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False)
+ if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) {
+ TALLOC_FREE(fake_fsp.fsp_name);
return -1;
+ }
+
+ TALLOC_FREE(fake_fsp.fsp_name);
return 0; /* ok for [f]chmod */
}
return 0;
}
- rc = gpfsacl_emu_chmod(fsp->fsp_name, mode);
+ rc = gpfsacl_emu_chmod(fsp->fsp_name->base_name, mode);
if (rc == 1)
return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
return rc;
DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to "
"hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n"));
- return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name,
- SMB_ACL_TYPE_ACCESS);
+ return hpuxacl_sys_acl_get_file(handle,
+ file_struct_p->fsp_name->base_name,
+ SMB_ACL_TYPE_ACCESS);
}
int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
- const char *name,
+ struct smb_filename *smb_fname,
SMB_ACL_TYPE_T type,
SMB_ACL_T theacl)
{
int ret = -1;
- SMB_STRUCT_STAT s;
HPUX_ACL_T hpux_acl = NULL;
int count;
DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
- name));
+ smb_fname_str_dbg(smb_fname)));
if(hpux_acl_call_present() == False) {
* that has _not_ been specified in "type" from the file first
* and concatenate it with the acl provided.
*/
- if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) {
+ if (SMB_VFS_STAT(handle->conn, smb_fname) != 0) {
DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
goto done;
}
- if (S_ISDIR(s.st_ex_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
HPUX_ACL_T other_acl;
int other_count;
SMB_ACL_TYPE_T other_type;
? SMB_ACL_TYPE_DEFAULT
: SMB_ACL_TYPE_ACCESS;
DEBUGADD(10, ("getting acl from filesystem\n"));
- if (!hpux_acl_get_file(name, &other_acl, &other_count)) {
+ if (!hpux_acl_get_file(smb_fname->base_name, &other_acl,
+ &other_count)) {
DEBUG(10, ("error getting acl from directory\n"));
goto done;
}
}
DEBUG(10, ("resulting acl is valid.\n"));
- ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl);
+ ret = acl(CONST_DISCARD(char *, smb_fname->base_name), ACL_SET, count,
+ hpux_acl);
if (ret != 0) {
DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
}
files_struct *fsp);
int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
- const char *name,
+ struct smb_filename *smb_fname,
SMB_ACL_TYPE_T type,
SMB_ACL_T theacl);
static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
- convert_sbuf(handle, fsp->fsp_name, sbuf);
+ if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) {
+ convert_sbuf(handle, fsp->fsp_name->base_name, sbuf);
}
return ret;
}
SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
}
-static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags)
+static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
+ unsigned int flags)
{
SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
}
ssize_t result;
result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
- DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
false);
return result;
}
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n",
+ fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
false);
return result;
result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
- DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n",
+ fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
true);
return result;
}
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
- DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
true);
return result;
}
static bool streams_xattr_recheck(struct stream_io *sio)
{
NTSTATUS status;
- struct smb_filename *smb_fname = NULL;
char *xattr_name = NULL;
if (sio->fsp->fsp_name == sio->fsp_name_ptr) {
return true;
}
- status = create_synthetic_smb_fname_split(talloc_tos(),
- sio->fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
-
- if (smb_fname->stream_name == NULL) {
+ if (sio->fsp->fsp_name->stream_name == NULL) {
/* how can this happen */
errno = EINVAL;
return false;
}
- status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
+ status = streams_xattr_get_name(talloc_tos(),
+ sio->fsp->fsp_name->stream_name,
&xattr_name);
if (!NT_STATUS_IS_OK(status)) {
return false;
sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
xattr_name);
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
- smb_fname->base_name);
+ sio->fsp->fsp_name->base_name);
sio->fsp_name_ptr = sio->fsp->fsp_name;
- TALLOC_FREE(smb_fname);
TALLOC_FREE(xattr_name);
if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn,
+ fsp->base_fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
- fsp->fsp_name,
- (double)offset ));
+ fsp_str_dbg(fsp), (double)offset));
if (sio == NULL) {
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn,
+ fsp->base_fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
if(result >= 0) {
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
SMB_ASSERT(i == naces);
/* store acl */
- if(acl(fsp->fsp_name, ACE_SETACL, naces, acebuf)) {
+ if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
if(errno == ENOSYS) {
DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
"supported on the filesystem where the file "
- "reside", fsp->fsp_name));
+ "reside", fsp_str_dbg(fsp)));
} else {
- DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp->fsp_name,
- strerror(errno)));
+ DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp),
+ strerror(errno)));
}
return 0;
}
SMB4ACL_T *pacl;
NTSTATUS status;
- status = zfs_get_nt_acl_common(fsp->fsp_name, security_info, &pacl);
+ status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info,
+ &pacl);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* If there was an async dns child - kill it. */
kill_async_dns_child();
+ gencache_stabilize();
+
pidfile_unlink();
exit(0);
#if 0
DEBUG(10, ("lp_string(%s)\n", s));
#endif
+ if (!s) {
+ return NULL;
+ }
ret = talloc_sub_basic(ctx,
get_current_username(),
}
/* Change from V1 is addition of password history field. */
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
}
}
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
nt_pw_len = 0;
}
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
}
/*********************************************************************
- Update the bad password count checking the AP_RESET_COUNT_TIME
+ Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
*********************************************************************/
bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
}
become_root();
- res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
+ res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
unbecome_root();
if (!res) {
}
/*********************************************************************
- Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
+ Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
*********************************************************************/
bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
}
become_root();
- res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
+ res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
unbecome_root();
if (!res) {
/* Retrieve the account lockout policy */
become_root();
- ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
+ ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
unbecome_root();
if ( !ret ) {
DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
}
if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
- pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
+ pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
}
str = tldap_talloc_single_attribute(entry, "displayName",
DEBUG(10, ("Could not pull userAccountControl\n"));
goto fail;
}
- pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
+ pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
if (blob.length != NT_HASH_LEN) {
ret &= tldap_make_mod_fmt(
existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
- "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
+ "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
ret &= tldap_make_mod_fmt(
existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
DEBUG(10, ("no samAccountType"));
continue;
}
- lsa_attrs[i] = ads_atype_map(attr);
+ lsa_attrs[i] = ds_atype_map(attr);
num_mapped += 1;
}
}
static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
- int policy_index, uint32 *value)
+ enum pdb_policy_type type,
+ uint32_t *value)
{
- return account_policy_get(policy_index, value)
+ return account_policy_get(type, value)
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
- int policy_index, uint32 value)
+ enum pdb_policy_type type,
+ uint32_t value)
{
- return account_policy_set(policy_index, value)
+ return account_policy_set(type, value)
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
uint32 *num_domains,
struct trustdom_info ***domains)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ *num_domains = 0;
+ *domains = NULL;
+ return NT_STATUS_OK;
}
static void pdb_ads_init_methods(struct pdb_methods *m)
samba_level = 2;
break;
case TLDAP_DEBUG_TRACE:
- samba_level = 10;
+ samba_level = 11;
break;
};
pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
return sampass->pass_can_change_time;
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
allow = 0;
/* in normal cases, just calculate it from policy */
if (sampass->acct_ctrl & ACB_PWNOEXP)
return get_time_t_max();
- if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
+ if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
|| expire == (uint32)-1 || expire == 0)
return get_time_t_max();
if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
uchar *pwhistory;
uint32 pwHistLen;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen != 0){
uint32 current_history_len;
/* We need to make sure we don't have a race condition here - the
}
#endif
-bool pdb_get_account_policy(int policy_index, uint32 *value)
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value)
{
struct pdb_methods *pdb = pdb_get_methods();
NTSTATUS status;
become_root();
- status = pdb->get_account_policy(pdb, policy_index, value);
+ status = pdb->get_account_policy(pdb, type, value);
unbecome_root();
return NT_STATUS_IS_OK(status);
}
-bool pdb_set_account_policy(int policy_index, uint32 value)
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value)
{
struct pdb_methods *pdb = pdb_get_methods();
NTSTATUS status;
become_root();
- status = pdb->set_account_policy(pdb, policy_index, value);
+ status = pdb->set_account_policy(pdb, type, value);
unbecome_root();
return NT_STATUS_IS_OK(status);
return NT_STATUS_OK;
}
-static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
{
- return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
{
- return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
const char **attr)
{
char *filter = NULL;
- char *escape_user = escape_ldap_string_alloc(user);
+ char *escape_user = escape_ldap_string(talloc_tos(), user);
int ret = -1;
if (!escape_user) {
filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
get_objclass_filter(ldap_state->schema_ver));
if (!filter) {
- SAFE_FREE(escape_user);
+ TALLOC_FREE(escape_user);
return LDAP_NO_MEMORY;
}
/*
filter = talloc_all_string_sub(talloc_tos(),
filter, "%u", escape_user);
- SAFE_FREE(escape_user);
+ TALLOC_FREE(escape_user);
if (!filter) {
return LDAP_NO_MEMORY;
}
pwHistLen = 0;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen > 0){
uint8 *pwhist = NULL;
int i;
if (need_update(sampass, PDB_PWHISTORY)) {
char *pwstr = NULL;
uint32 pwHistLen = 0;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
pwstr = SMB_MALLOC_ARRAY(char, 1024);
if (!pwstr) {
uint16 badcount = pdb_get_bad_password_count(sampass);
time_t badtime = pdb_get_bad_password_time(sampass);
uint32 pol;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
(unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
char *utf8_password;
char *utf8_dn;
size_t converted_size;
+ int ret;
if (!ldap_state->is_nds_ldap) {
}
if ((ber_printf (ber, "{") < 0) ||
- (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn) < 0) ||
- (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password) < 0) ||
- (ber_printf (ber, "n}") < 0)) {
- DEBUG(0,("ldapsam_modify_entry: ber_printf returns a value <0\n"));
- ber_free(ber,1);
- TALLOC_FREE(utf8_dn);
- TALLOC_FREE(utf8_password);
- return NT_STATUS_UNSUCCESSFUL;
+ (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
+ utf8_dn) < 0)) {
+ DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+ "value <0\n"));
+ ber_free(ber,1);
+ TALLOC_FREE(utf8_dn);
+ TALLOC_FREE(utf8_password);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if ((utf8_password != NULL) && (*utf8_password != '\0')) {
+ ret = ber_printf(ber, "ts}",
+ LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
+ utf8_password);
+ } else {
+ ret = ber_printf(ber, "}");
+ }
+
+ if (ret < 0) {
+ DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+ "value <0\n"));
+ ber_free(ber,1);
+ TALLOC_FREE(utf8_dn);
+ TALLOC_FREE(utf8_password);
+ return NT_STATUS_UNSUCCESSFUL;
}
if ((rc = ber_flatten (ber, &bv))<0) {
/* does the entry already exist but without a samba attributes?
we need to return the samba attributes here */
- escape_user = escape_ldap_string_alloc( username );
+ escape_user = escape_ldap_string(talloc_tos(), username);
filter = talloc_strdup(attr_list, "(uid=%u)");
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto fn_exit;
}
filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
+ TALLOC_FREE(escape_user);
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto fn_exit;
}
- SAFE_FREE(escape_user);
rc = smbldap_search_suffix(ldap_state->smbldap_state,
filter, attr_list, &result);
fn_exit:
TALLOC_FREE(ctx);
- SAFE_FREE(escape_user);
if (result) {
ldap_msgfree(result);
}
const char *name)
{
char *filter = NULL;
- char *escape_name = escape_ldap_string_alloc(name);
+ char *escape_name = escape_ldap_string(talloc_tos(), name);
NTSTATUS status;
if (!escape_name) {
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
escape_name) < 0) {
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
status = ldapsam_getgroup(methods, filter, map);
SAFE_FREE(filter);
return status;
for (memberuid = values; *memberuid != NULL; memberuid += 1) {
char *escape_memberuid;
- escape_memberuid = escape_ldap_string_alloc(*memberuid);
+ escape_memberuid = escape_ldap_string(talloc_tos(),
+ *memberuid);
if (escape_memberuid == NULL) {
ret = NT_STATUS_NO_MEMORY;
goto done;
}
filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
+ TALLOC_FREE(escape_memberuid);
if (filter == NULL) {
- SAFE_FREE(escape_memberuid);
ret = NT_STATUS_NO_MEMORY;
goto done;
}
-
- SAFE_FREE(escape_memberuid);
}
filter = talloc_asprintf_append_buffer(filter, "))");
return NT_STATUS_INVALID_PARAMETER;
}
- escape_name = escape_ldap_string_alloc(pdb_get_username(user));
+ escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
if (escape_name == NULL)
return NT_STATUS_NO_MEMORY;
done:
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
return ret;
}
}
static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
- int policy_index,
+ enum pdb_policy_type type,
uint32 value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_INVALID_PARAMETER;
}
- policy_attr = get_account_policy_attr(policy_index);
+ policy_attr = get_account_policy_attr(type);
if (policy_attr == NULL) {
DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
"policy\n"));
return ntstatus;
}
- if (!cache_account_policy_set(policy_index, value)) {
+ if (!cache_account_policy_set(type, value)) {
DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
"update local tdb cache\n"));
return ntstatus;
}
static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
- int policy_index, uint32 value)
+ enum pdb_policy_type type,
+ uint32_t value)
{
- return ldapsam_set_account_policy_in_ldap(methods, policy_index,
+ return ldapsam_set_account_policy_in_ldap(methods, type,
value);
}
static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
- int policy_index,
+ enum pdb_policy_type type,
uint32 *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_INVALID_PARAMETER;
}
- policy_attr = get_account_policy_attr(policy_index);
+ policy_attr = get_account_policy_attr(type);
if (!policy_attr) {
DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
- "policy index: %d\n", policy_index));
+ "policy index: %d\n", type));
return ntstatus;
}
Guenther
*/
static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
- int policy_index, uint32 *value)
+ enum pdb_policy_type type,
+ uint32_t *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
- if (cache_account_policy_get(policy_index, value)) {
+ if (cache_account_policy_get(type, value)) {
DEBUG(11,("ldapsam_get_account_policy: got valid value from "
"cache\n"));
return NT_STATUS_OK;
}
- ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index,
+ ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
value);
if (NT_STATUS_IS_OK(ntstatus)) {
goto update_cache;
#if 0
/* should we automagically migrate old tdb value here ? */
- if (account_policy_get(policy_index, value))
+ if (account_policy_get(type, value))
goto update_ldap;
DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
- "default\n", policy_index));
+ "default\n", type));
#endif
- if (!account_policy_get_default(policy_index, value)) {
+ if (!account_policy_get_default(type, value)) {
return ntstatus;
}
/* update_ldap: */
- ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
+ ntstatus = ldapsam_set_account_policy(methods, type, *value);
if (!NT_STATUS_IS_OK(ntstatus)) {
return ntstatus;
}
update_cache:
- if (!cache_account_policy_set(policy_index, *value)) {
+ if (!cache_account_policy_set(type, *value)) {
DEBUG(0,("ldapsam_get_account_policy: failed to update local "
"tdb as a cache\n"));
return NT_STATUS_UNSUCCESSFUL;
goto done;
}
- escaped = escape_ldap_string_alloc(username);
+ escaped = escape_ldap_string(talloc_tos(), username);
if (escaped == NULL) goto done;
result = talloc_string_sub(mem_ctx, filter, "%u", username);
done:
SAFE_FREE(filter);
- SAFE_FREE(escaped);
+ TALLOC_FREE(escaped);
return result;
}
is_machine = True;
}
- username = escape_ldap_string_alloc(name);
+ username = escape_ldap_string(talloc_tos(), name);
filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
username, LDAP_OBJ_POSIXACCOUNT);
- SAFE_FREE(username);
+ TALLOC_FREE(username);
rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
if (rc != LDAP_SUCCESS) {
gid_t gid = -1;
int rc;
- groupname = escape_ldap_string_alloc(name);
+ groupname = escape_ldap_string(talloc_tos(), name);
filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
groupname, LDAP_OBJ_POSIXGROUP);
- SAFE_FREE(groupname);
+ TALLOC_FREE(groupname);
rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
if (rc != LDAP_SUCCESS) {
return NT_STATUS_NO_MEMORY;
}
- escape_username = escape_ldap_string_alloc(pdb_get_username(sampass));
+ escape_username = escape_ldap_string(talloc_tos(),
+ pdb_get_username(sampass));
if (escape_username== NULL) {
return NT_STATUS_NO_MEMORY;
}
LDAP_OBJ_POSIXACCOUNT,
LDAP_OBJ_SAMBASAMACCOUNT);
- SAFE_FREE(escape_username);
+ TALLOC_FREE(escape_username);
if (filter == NULL) {
return NT_STATUS_NO_MEMORY;
return result;
}
-static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
{
return NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
{
return NT_STATUS_UNSUCCESSFUL;
}
const char *name)
{
NTSTATUS result = NT_STATUS_OK;
- char *user_name = NULL;
- char *domain = NULL;
+ const char *domain = "";
DOM_SID sid;
gid_t gid;
enum lsa_SidType name_type;
- if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) {
+ if (!winbind_lookup_name(domain, name, &sid, &name_type)) {
result = NT_STATUS_NO_SUCH_GROUP;
goto done;
}
goto done;
}
- if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) {
+ if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) {
result = NT_STATUS_NO_SUCH_GROUP;
goto done;
}
return NT_STATUS_ACCESS_DENIED; /* No errno around here */
}
+ status = create_synthetic_smb_fname(fsp,
+ print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL,
+ NULL, &fsp->fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
+ return status;
+ }
/* setup a full fsp */
fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
GetTimeOfDay(&fsp->open_time);
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
- string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
fsp->wcp = NULL;
SMB_VFS_FSTAT(fsp, psbuf);
fsp->mode = psbuf->st_ex_mode;
}
if (fsp->fsp_name) {
- string_free(&fsp->fsp_name);
+ TALLOC_FREE(fsp->fsp_name);
}
if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 2007-2009
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
static struct db_context *regdb = NULL;
static int regdb_refcount;
-static bool regdb_key_exists(const char *key);
+static bool regdb_key_exists(struct db_context *db, const char *key);
static bool regdb_key_is_base_key(const char *key);
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr);
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr);
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+ struct regval_ctr *values);
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+ struct regval_ctr *values);
/* List the deepest path into the registry. All part components will be created.*/
* Initialize a key in the registry:
* create each component key of the specified path.
*/
-static WERROR init_registry_key_internal(const char *add_path)
+static WERROR init_registry_key_internal(struct db_context *db,
+ const char *add_path)
{
WERROR werr;
TALLOC_CTX *frame = talloc_stackframe();
goto fail;
}
- regdb_fetch_keys(base, subkeys);
+ werr = regdb_fetch_keys_internal(db, base, subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto fail;
+ }
+
if (*subkeyname) {
werr = regsubkey_ctr_addkey(subkeys, subkeyname);
if (!W_ERROR_IS_OK(werr)) {
goto fail;
}
}
- if (!regdb_store_keys( base, subkeys)) {
+ if (!regdb_store_keys_internal(db, base, subkeys)) {
werr = WERR_CAN_NOT_COMPLETE;
goto fail;
}
return werr;
}
+struct init_registry_key_context {
+ const char *add_path;
+};
+
+static NTSTATUS init_registry_key_action(struct db_context *db,
+ void *private_data)
+{
+ struct init_registry_key_context *init_ctx =
+ (struct init_registry_key_context *)private_data;
+
+ return werror_to_ntstatus(init_registry_key_internal(
+ db, init_ctx->add_path));
+}
+
/**
* Initialize a key in the registry:
* create each component key of the specified path,
*/
WERROR init_registry_key(const char *add_path)
{
- WERROR werr;
+ struct init_registry_key_context init_ctx;
- if (regdb_key_exists(add_path)) {
+ if (regdb_key_exists(regdb, add_path)) {
return WERR_OK;
}
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("init_registry_key: transaction_start failed\n"));
- return WERR_REG_IO_FAILURE;
- }
+ init_ctx.add_path = add_path;
- werr = init_registry_key_internal(add_path);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
+ return ntstatus_to_werror(dbwrap_trans_do(regdb,
+ init_registry_key_action,
+ &init_ctx));
+}
+
+/***********************************************************************
+ Open the registry data in the tdb
+ ***********************************************************************/
+
+static void regdb_ctr_add_value(struct regval_ctr *ctr,
+ struct builtin_regkey_value *value)
+{
+ UNISTR2 data;
+
+ switch(value->type) {
+ case REG_DWORD:
+ regval_ctr_addvalue(ctr, value->valuename, REG_DWORD,
+ (char*)&value->data.dw_value,
+ sizeof(uint32));
+ break;
+
+ case REG_SZ:
+ init_unistr2(&data, value->data.string, UNI_STR_TERMINATE);
+ regval_ctr_addvalue(ctr, value->valuename, REG_SZ,
+ (char*)data.buffer,
+ data.uni_str_len*sizeof(uint16));
+ break;
+
+ default:
+ DEBUG(0, ("regdb_ctr_add_value: invalid value type in "
+ "registry values [%d]\n", value->type));
}
+}
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("init_registry_key: Could not commit transaction\n"));
- return WERR_REG_IO_FAILURE;
+static NTSTATUS init_registry_data_action(struct db_context *db,
+ void *private_data)
+{
+ NTSTATUS status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct regval_ctr *values;
+ int i;
+
+ /* loop over all of the predefined paths and add each component */
+
+ for (i=0; builtin_registry_paths[i] != NULL; i++) {
+ if (regdb_key_exists(db, builtin_registry_paths[i])) {
+ continue;
+ }
+ status = werror_to_ntstatus(init_registry_key_internal(db,
+ builtin_registry_paths[i]));
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
}
- return WERR_OK;
+ /* loop over all of the predefined values and add each component */
-fail:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("init_registry_key: transaction_cancel failed\n");
+ for (i=0; builtin_registry_values[i].path != NULL; i++) {
+
+ values = TALLOC_ZERO_P(frame, struct regval_ctr);
+ if (values == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ regdb_fetch_values_internal(db,
+ builtin_registry_values[i].path,
+ values);
+
+ /* preserve existing values across restarts. Only add new ones */
+
+ if (!regval_ctr_key_exists(values,
+ builtin_registry_values[i].valuename))
+ {
+ regdb_ctr_add_value(values,
+ &builtin_registry_values[i]);
+ regdb_store_values_internal(db,
+ builtin_registry_values[i].path,
+ values);
+ }
+ TALLOC_FREE(values);
}
- return werr;
-}
+ status = NT_STATUS_OK;
-/***********************************************************************
- Open the registry data in the tdb
- ***********************************************************************/
+done:
+
+ TALLOC_FREE(frame);
+ return status;
+}
WERROR init_registry_data(void)
{
TALLOC_CTX *frame = talloc_stackframe();
struct regval_ctr *values;
int i;
- UNISTR2 data;
/*
* First, check for the existence of the needed keys and values.
* If all do already exist, we can save the writes.
*/
for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (!regdb_key_exists(builtin_registry_paths[i])) {
+ if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
goto do_init;
}
}
goto done;
}
- regdb_fetch_values(builtin_registry_values[i].path, values);
+ regdb_fetch_values_internal(regdb,
+ builtin_registry_values[i].path,
+ values);
if (!regval_ctr_key_exists(values,
builtin_registry_values[i].valuename))
{
* transaction behaviour.
*/
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("init_registry_data: tdb_transaction_start "
- "failed\n"));
- werr = WERR_REG_IO_FAILURE;
- goto done;
- }
-
- /* loop over all of the predefined paths and add each component */
-
- for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (regdb_key_exists(builtin_registry_paths[i])) {
- continue;
- }
- werr = init_registry_key_internal(builtin_registry_paths[i]);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
- }
- }
-
- /* loop over all of the predefined values and add each component */
-
- for (i=0; builtin_registry_values[i].path != NULL; i++) {
-
- values = TALLOC_ZERO_P(frame, struct regval_ctr);
- if (values == NULL) {
- werr = WERR_NOMEM;
- goto fail;
- }
-
- regdb_fetch_values(builtin_registry_values[i].path, values);
-
- /* preserve existing values across restarts. Only add new ones */
-
- if (!regval_ctr_key_exists(values,
- builtin_registry_values[i].valuename))
- {
- switch(builtin_registry_values[i].type) {
- case REG_DWORD:
- regval_ctr_addvalue(values,
- builtin_registry_values[i].valuename,
- REG_DWORD,
- (char*)&builtin_registry_values[i].data.dw_value,
- sizeof(uint32));
- break;
-
- case REG_SZ:
- init_unistr2(&data,
- builtin_registry_values[i].data.string,
- UNI_STR_TERMINATE);
- regval_ctr_addvalue(values,
- builtin_registry_values[i].valuename,
- REG_SZ,
- (char*)data.buffer,
- data.uni_str_len*sizeof(uint16));
- break;
-
- default:
- DEBUG(0, ("init_registry_data: invalid value "
- "type in builtin_registry_values "
- "[%d]\n",
- builtin_registry_values[i].type));
- }
- regdb_store_values(builtin_registry_values[i].path,
- values);
- }
- TALLOC_FREE(values);
- }
-
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("init_registry_data: Could not commit "
- "transaction\n"));
- werr = WERR_REG_IO_FAILURE;
- } else {
- werr = WERR_OK;
- }
-
- goto done;
-
-fail:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("init_registry_data: tdb_transaction_cancel "
- "failed\n");
- }
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ init_registry_data_action,
+ NULL));
done:
TALLOC_FREE(frame);
}
-static WERROR regdb_delete_key_with_prefix(const char *keyname,
+static WERROR regdb_delete_key_with_prefix(struct db_context *db,
+ const char *keyname,
const char *prefix)
{
char *path;
goto done;
}
- werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path));
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path));
/* treat "not" found" as ok */
if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
}
-static WERROR regdb_delete_values(const char *keyname)
+static WERROR regdb_delete_values(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX);
+ return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX);
}
-static WERROR regdb_delete_secdesc(const char *keyname)
+static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX);
+ return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX);
}
-static WERROR regdb_delete_subkeylist(const char *keyname)
+static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, NULL);
+ return regdb_delete_key_with_prefix(db, keyname, NULL);
}
-static WERROR regdb_delete_key_lists(const char *keyname)
+static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
{
WERROR werr;
- werr = regdb_delete_values(keyname);
+ werr = regdb_delete_values(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
REG_VALUE_PREFIX, keyname, win_errstr(werr)));
goto done;
}
- werr = regdb_delete_secdesc(keyname);
+ werr = regdb_delete_secdesc(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
goto done;
}
- werr = regdb_delete_subkeylist(keyname);
+ werr = regdb_delete_subkeylist(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s failed: %s\n",
keyname, win_errstr(werr)));
fstrings
***********************************************************************/
-static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_store_keys_internal2(struct db_context *db,
+ const char *key,
+ struct regsubkey_ctr *ctr)
{
TDB_DATA dbuf;
uint8 *buffer = NULL;
int i = 0;
uint32 len, buflen;
- bool ret = true;
uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
char *keyname = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
- NTSTATUS status;
+ WERROR werr;
if (!key) {
- return false;
+ werr = WERR_INVALID_PARAM;
+ goto done;
}
keyname = talloc_strdup(ctx, key);
if (!keyname) {
- return false;
+ werr = WERR_NOMEM;
+ goto done;
}
+
keyname = normalize_reg_path(ctx, keyname);
+ if (!keyname) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
/* allocate some initial memory */
buffer = (uint8 *)SMB_MALLOC(1024);
if (buffer == NULL) {
- return false;
+ werr = WERR_NOMEM;
+ goto done;
}
buflen = 1024;
len = 0;
DEBUG(0, ("regdb_store_keys: Failed to realloc "
"memory of size [%u]\n",
(unsigned int)(len+thistime)*2));
- ret = false;
+ werr = WERR_NOMEM;
goto done;
}
buflen = (len+thistime)*2;
regsubkey_ctr_specific_key(ctr, i));
if (thistime2 != thistime) {
DEBUG(0, ("tdb_pack failed\n"));
- ret = false;
+ werr = WERR_CAN_NOT_COMPLETE;
goto done;
}
}
dbuf.dptr = buffer;
dbuf.dsize = len;
- status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE);
- if (!NT_STATUS_IS_OK(status)) {
- ret = false;
- goto done;
- }
+ werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf,
+ TDB_REPLACE));
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
/*
* Delete a sorted subkey cache for regdb_key_exists, will be
*/
keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
keyname);
- if (keyname != NULL) {
- dbwrap_delete_bystring(regdb, keyname);
+ if (keyname == NULL) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
+
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
+
+ /* don't treat WERR_NOT_FOUND as an error here */
+ if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
+ werr = WERR_OK;
}
done:
TALLOC_FREE(ctx);
SAFE_FREE(buffer);
- return ret;
+ return werr;
}
/***********************************************************************
do not currently exist
***********************************************************************/
-bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+struct regdb_store_keys_context {
+ const char *key;
+ struct regsubkey_ctr *ctr;
+};
+
+static NTSTATUS regdb_store_keys_action(struct db_context *db,
+ void *private_data)
{
- int num_subkeys, old_num_subkeys, i;
+ struct regdb_store_keys_context *store_ctx;
+ WERROR werr;
+ int num_subkeys, i;
char *path = NULL;
struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
char *oldkeyname = NULL;
- TALLOC_CTX *ctx = talloc_stackframe();
- WERROR werr;
-
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
- goto fail;
- }
-
- /*
- * fetch a list of the old subkeys so we can determine if anything has
- * changed
- */
-
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- return false;
- }
-
- regdb_fetch_keys(key, old_subkeys);
-
- num_subkeys = regsubkey_ctr_numkeys(ctr);
- old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
- if ((num_subkeys && old_num_subkeys) &&
- (num_subkeys == old_num_subkeys)) {
-
- for (i = 0; i < num_subkeys; i++) {
- if (strcmp(regsubkey_ctr_specific_key(ctr, i),
- regsubkey_ctr_specific_key(old_subkeys, i))
- != 0)
- {
- break;
- }
- }
- if (i == num_subkeys) {
- /*
- * Nothing changed, no point to even start a tdb
- * transaction
- */
- TALLOC_FREE(old_subkeys);
- return true;
- }
- }
-
- TALLOC_FREE(old_subkeys);
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("regdb_store_keys: transaction_start failed\n"));
- goto fail;
- }
+ store_ctx = (struct regdb_store_keys_context *)private_data;
/*
* Re-fetch the old keys inside the transaction
*/
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &old_subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- regdb_fetch_keys(key, old_subkeys);
+ werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto done;
+ }
/*
* Make the store operation as safe as possible without transactions:
for (i=0; i<num_subkeys; i++) {
oldkeyname = regsubkey_ctr_specific_key(old_subkeys, i);
- if (regsubkey_ctr_key_exists(ctr, oldkeyname)) {
+ if (regsubkey_ctr_key_exists(store_ctx->ctr, oldkeyname)) {
/*
* It's still around, don't delete
*/
-
continue;
}
- path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ oldkeyname);
if (!path) {
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
- werr = regdb_delete_key_lists(path);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ werr = regdb_delete_key_lists(db, path);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
TALLOC_FREE(path);
}
/* (2) store the subkey list for the parent */
- if (!regdb_store_keys_internal(key, ctr) ) {
+ werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
- "for parent [%s]\n", key));
- goto cancel;
+ "for parent [%s]: %s\n", store_ctx->key,
+ win_errstr(werr)));
+ goto done;
}
/* (3) now create records for any subkeys that don't already exist */
- num_subkeys = regsubkey_ctr_numkeys(ctr);
+ num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
if (num_subkeys == 0) {
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (!regdb_store_keys_internal(key, subkeys)) {
+ werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]\n", key));
- goto cancel;
+ "new record for key [%s]: %s\n",
+ store_ctx->key, win_errstr(werr)));
+ goto done;
}
TALLOC_FREE(subkeys);
-
}
for (i=0; i<num_subkeys; i++) {
- path = talloc_asprintf(ctx, "%s/%s",
- key,
- regsubkey_ctr_specific_key(ctr, i));
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ regsubkey_ctr_specific_key(store_ctx->ctr, i));
if (!path) {
- goto cancel;
- }
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (regdb_fetch_keys( path, subkeys ) == -1) {
+ werr = regdb_fetch_keys_internal(db, path, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
/* create a record with 0 subkeys */
- if (!regdb_store_keys_internal(path, subkeys)) {
+ werr = regdb_store_keys_internal2(db, path, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]\n", path));
- goto cancel;
+ "new record for key [%s]: %s\n", path,
+ win_errstr(werr)));
+ goto done;
}
}
TALLOC_FREE(path);
}
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("regdb_store_keys: Could not commit transaction\n"));
- goto fail;
+ werr = WERR_OK;
+
+done:
+ talloc_free(mem_ctx);
+ return werror_to_ntstatus(werr);
+}
+
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr)
+{
+ int num_subkeys, old_num_subkeys, i;
+ struct regsubkey_ctr *old_subkeys = NULL;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ WERROR werr;
+ bool ret = false;
+ struct regdb_store_keys_context store_ctx;
+
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
+ goto done;
}
- TALLOC_FREE(ctx);
- return true;
+ /*
+ * fetch a list of the old subkeys so we can determine if anything has
+ * changed
+ */
+
+ werr = regsubkey_ctr_init(ctx, &old_subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+ goto done;
+ }
-cancel:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("regdb_store_keys: transaction_cancel failed\n");
+ werr = regdb_fetch_keys_internal(db, key, old_subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto done;
}
-fail:
+ num_subkeys = regsubkey_ctr_numkeys(ctr);
+ old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
+ if ((num_subkeys && old_num_subkeys) &&
+ (num_subkeys == old_num_subkeys)) {
+
+ for (i = 0; i < num_subkeys; i++) {
+ if (strcmp(regsubkey_ctr_specific_key(ctr, i),
+ regsubkey_ctr_specific_key(old_subkeys, i))
+ != 0)
+ {
+ break;
+ }
+ }
+ if (i == num_subkeys) {
+ /*
+ * Nothing changed, no point to even start a tdb
+ * transaction
+ */
+
+ ret = true;
+ goto done;
+ }
+ }
+
+ TALLOC_FREE(old_subkeys);
+
+ store_ctx.key = key;
+ store_ctx.ctr = ctr;
+
+ werr = ntstatus_to_werror(dbwrap_trans_do(db,
+ regdb_store_keys_action,
+ &store_ctx));
+
+ ret = W_ERROR_IS_OK(werr);
+
+done:
TALLOC_FREE(ctx);
- return false;
+ return ret;
+}
+
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+ return regdb_store_keys_internal(regdb, key, ctr);
+}
+
+/**
+ * create a subkey of a given key
+ */
+
+struct regdb_create_subkey_context {
+ const char *key;
+ const char *subkey;
+};
+
+static NTSTATUS regdb_create_subkey_action(struct db_context *db,
+ void *private_data)
+{
+ WERROR werr;
+ struct regdb_create_subkey_context *create_ctx;
+ struct regsubkey_ctr *subkeys;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ create_ctx = (struct regdb_create_subkey_context *)private_data;
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, (__location__ " failed to store new subkey list for "
+ "parent key %s: %s\n", create_ctx->key,
+ win_errstr(werr)));
+ }
+
+done:
+ talloc_free(mem_ctx);
+ return werror_to_ntstatus(werr);
}
static WERROR regdb_create_subkey(const char *key, const char *subkey)
WERROR werr;
struct regsubkey_ctr *subkeys;
TALLOC_CTX *mem_ctx = talloc_stackframe();
+ struct regdb_create_subkey_context create_ctx;
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
werr = regsubkey_ctr_init(mem_ctx, &subkeys);
W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto done;
- }
+ werr = regdb_fetch_keys_internal(regdb, key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
if (regsubkey_ctr_key_exists(subkeys, subkey)) {
werr = WERR_OK;
talloc_free(subkeys);
- werr = regdb_transaction_start();
- W_ERROR_NOT_OK_GOTO_DONE(werr);
+ create_ctx.key = key;
+ create_ctx.subkey = subkey;
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ regdb_create_subkey_action,
+ &create_ctx));
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
+done:
+ talloc_free(mem_ctx);
+ return werr;
+}
- werr = regsubkey_ctr_addkey(subkeys, subkey);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+/**
+ * create a subkey of a given key
+ */
- if (!regdb_store_keys_internal(key, subkeys)) {
- DEBUG(0, (__location__ " failed to store new subkey list for "
- "parent key %s\n", key));
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
+struct regdb_delete_subkey_context {
+ const char *key;
+ const char *subkey;
+ const char *path;
+};
- werr = regdb_transaction_commit();
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to commit transaction: %s\n",
- win_errstr(werr)));
- }
+static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
+ void *private_data)
+{
+ WERROR werr;
+ struct regdb_delete_subkey_context *delete_ctx;
+ struct regsubkey_ctr *subkeys;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- goto done;
+ delete_ctx = (struct regdb_delete_subkey_context *)private_data;
+
+ werr = regdb_delete_key_lists(db, delete_ctx->path);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
-cancel:
- werr = regdb_transaction_cancel();
+ werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys);
if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
+ DEBUG(0, (__location__ " failed to store new subkey_list for "
+ "parent key %s: %s\n", delete_ctx->key,
win_errstr(werr)));
}
done:
talloc_free(mem_ctx);
- return werr;
+ return werror_to_ntstatus(werr);
}
static WERROR regdb_delete_subkey(const char *key, const char *subkey)
{
- WERROR werr, werr2;
- struct regsubkey_ctr *subkeys;
+ WERROR werr;
char *path;
+ struct regdb_delete_subkey_context delete_ctx;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
goto done;
}
- if (!regdb_key_exists(path)) {
+ if (!regdb_key_exists(regdb, path)) {
werr = WERR_OK;
goto done;
}
- werr = regdb_transaction_start();
- W_ERROR_NOT_OK_GOTO_DONE(werr);
-
- werr = regdb_delete_key_lists(path);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
-
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
-
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
-
- werr = regsubkey_ctr_delkey(subkeys, subkey);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ delete_ctx.key = key;
+ delete_ctx.subkey = subkey;
+ delete_ctx.path = path;
- if (!regdb_store_keys_internal(key, subkeys)) {
- DEBUG(0, (__location__ " failed to store new subkey_list for "
- "parent key %s\n", key));
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
-
- werr = regdb_transaction_commit();
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to commit transaction: %s\n",
- win_errstr(werr)));
- }
-
- goto done;
-
-cancel:
- werr2 = regdb_transaction_cancel();
- if (!W_ERROR_IS_OK(werr2)) {
- DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
- win_errstr(werr2)));
- }
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ regdb_delete_subkey_action,
+ &delete_ctx));
done:
talloc_free(mem_ctx);
return werr;
}
-static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
+static TDB_DATA regdb_fetch_key_internal(struct db_context *db,
+ TALLOC_CTX *mem_ctx, const char *key)
{
char *path = NULL;
TDB_DATA data;
return make_tdb_data(NULL, 0);
}
- data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+ data = dbwrap_fetch_bystring(db, mem_ctx, path);
TALLOC_FREE(path);
return data;
* parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
* the potentially large subkey record.
*
- * The sorted subkey record is deleted in regdb_store_keys_internal and
+ * The sorted subkey record is deleted in regdb_store_keys_internal2 and
* recreated on demand.
*/
return StrCaseCmp(*((char **)p1), *((char **)p2));
}
-static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+struct create_sorted_subkeys_context {
+ const char *key;
+ const char *sorted_keyname;
+};
+
+static NTSTATUS create_sorted_subkeys_action(struct db_context *db,
+ void *private_data)
{
char **sorted_subkeys;
struct regsubkey_ctr *ctr;
- bool result = false;
NTSTATUS status;
char *buf;
char *p;
- int i, res;
+ int i;
size_t len;
int num_subkeys;
- WERROR werr;
+ struct create_sorted_subkeys_context *sorted_ctx;
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("create_sorted_subkeys: transaction_start "
- "failed\n"));
- return false;
- }
+ sorted_ctx = (struct create_sorted_subkeys_context *)private_data;
- werr = regsubkey_ctr_init(talloc_tos(), &ctr);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
+ /*
+ * In this function, we only treat failing of the actual write to
+ * the db as a real error. All preliminary errors, at a stage when
+ * nothing has been written to the DB yet are treated as success
+ * to be committed (as an empty transaction).
+ *
+ * The reason is that this (disposable) call might be nested in other
+ * transactions. Doing a cancel here would destroy the possibility of
+ * a transaction_commit for transactions that we might be wrapped in.
+ */
+
+ status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr));
+ if (!NT_STATUS_IS_OK(status)) {
+ /* don't treat this as an error */
+ status = NT_STATUS_OK;
+ goto done;
}
- res = regdb_fetch_keys(key, ctr);
- if (res == -1) {
- goto fail;
+ status = werror_to_ntstatus(regdb_fetch_keys_internal(db,
+ sorted_ctx->key,
+ ctr));
+ if (!NT_STATUS_IS_OK(status)) {
+ /* don't treat this as an error */
+ status = NT_STATUS_OK;
+ goto done;
}
num_subkeys = regsubkey_ctr_numkeys(ctr);
sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
if (sorted_subkeys == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
len = 4 + 4*num_subkeys;
sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
regsubkey_ctr_specific_key(ctr, i));
if (sorted_subkeys[i] == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
len += strlen(sorted_subkeys[i])+1;
}
buf = talloc_array(ctr, char, len);
if (buf == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
p = buf + 4 + 4*num_subkeys;
}
status = dbwrap_store_bystring(
- regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len),
+ db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf,
+ len),
TDB_REPLACE);
- if (!NT_STATUS_IS_OK(status)) {
- /*
- * Don't use a "goto fail;" here, this would commit the broken
- * transaction. See below for an explanation.
- */
- if (regdb->transaction_cancel(regdb) == -1) {
- DEBUG(0, ("create_sorted_subkeys: transaction_cancel "
- "failed\n"));
- }
- TALLOC_FREE(ctr);
- return false;
- }
- result = true;
- fail:
- /*
- * We only get here via the "goto fail" when we did not write anything
- * yet. Using transaction_commit even in a failure case is necessary
- * because this (disposable) call might be nested in other
- * transactions. Doing a cancel here would destroy the possibility of
- * a transaction_commit for transactions that we might be wrapped in.
- */
- if (regdb->transaction_commit(regdb) == -1) {
- DEBUG(0, ("create_sorted_subkeys: transaction_start "
- "failed\n"));
- goto fail;
- }
+done:
+ talloc_free(ctr);
+ return status;
+}
- TALLOC_FREE(ctr);
- return result;
+static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+{
+ NTSTATUS status;
+ struct create_sorted_subkeys_context sorted_ctx;
+
+ sorted_ctx.key = key;
+ sorted_ctx.sorted_keyname = sorted_keyname;
+
+ status = dbwrap_trans_do(regdb,
+ create_sorted_subkeys_action,
+ &sorted_ctx);
+
+ return NT_STATUS_IS_OK(status);
}
struct scan_subkey_state {
return 0;
}
-static bool scan_parent_subkeys(const char *parent, const char *name)
+static bool scan_parent_subkeys(struct db_context *db, const char *parent,
+ const char *name)
{
char *path = NULL;
char *key = NULL;
}
state.scanned = false;
- res = regdb->parse_record(regdb, string_term_tdb_data(key),
- parent_subkey_scanner, &state);
+ res = db->parse_record(db, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
if (state.scanned) {
result = state.found;
if (!create_sorted_subkeys(path, key)) {
goto fail;
}
- res = regdb->parse_record(regdb, string_term_tdb_data(key),
- parent_subkey_scanner, &state);
+ res = db->parse_record(db, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
if ((res == 0) && (state.scanned)) {
result = state.found;
}
* The exeption of this are keys without a parent key,
* i.e. the "base" keys (HKLM, HKCU, ...).
*/
-static bool regdb_key_exists(const char *key)
+static bool regdb_key_exists(struct db_context *db, const char *key)
{
TALLOC_CTX *mem_ctx = talloc_stackframe();
TDB_DATA value;
p = strrchr(path, '/');
if (p == NULL) {
/* this is a base key */
- value = regdb_fetch_key_internal(mem_ctx, path);
+ value = regdb_fetch_key_internal(db, mem_ctx, path);
ret = (value.dptr != NULL);
} else {
*p = '\0';
- ret = scan_parent_subkeys(path, p+1);
+ ret = scan_parent_subkeys(db, path, p+1);
}
done:
released by the caller.
***********************************************************************/
-int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr)
{
WERROR werr;
- uint32 num_items;
+ uint32_t num_items;
uint8 *buf;
uint32 buflen, len;
int i;
fstring subkeyname;
- int ret = -1;
TALLOC_CTX *frame = talloc_stackframe();
TDB_DATA value;
DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
- if (!regdb_key_exists(key)) {
- goto done;
- }
+ frame = talloc_stackframe();
- werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum());
- if (!W_ERROR_IS_OK(werr)) {
+ if (!regdb_key_exists(db, key)) {
+ DEBUG(10, ("key [%s] not found\n", key));
+ werr = WERR_NOT_FOUND;
goto done;
}
- value = regdb_fetch_key_internal(frame, key);
+ werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db));
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ value = regdb_fetch_key_internal(db, frame, key);
if (value.dptr == NULL) {
DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
key));
- ret = 0;
goto done;
}
buflen = value.dsize;
len = tdb_unpack( buf, buflen, "d", &num_items);
+ werr = regsubkey_ctr_reinit(ctr);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
for (i=0; i<num_items; i++) {
len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
werr = regsubkey_ctr_addkey(ctr, subkeyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
"failed: %s\n", win_errstr(werr)));
+ num_items = 0;
goto done;
}
}
DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
- ret = num_items;
done:
TALLOC_FREE(frame);
- return ret;
+ return werr;
+}
+
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+ WERROR werr;
+
+ werr = regdb_fetch_keys_internal(regdb, key, ctr);
+ if (!W_ERROR_IS_OK(werr)) {
+ return -1;
+ }
+
+ return regsubkey_ctr_numkeys(ctr);
}
/****************************************************************************
released by the caller.
***********************************************************************/
-int regdb_fetch_values(const char* key, struct regval_ctr *values)
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+ struct regval_ctr *values)
{
char *keystr = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(db, key)) {
goto done;
}
goto done;
}
- values->seqnum = regdb_get_seqnum();
+ values->seqnum = db->get_seqnum(db);
- value = regdb_fetch_key_internal(ctx, keystr);
+ value = regdb_fetch_key_internal(db, ctx, keystr);
if (!value.dptr) {
/* all keys have zero values by default */
return ret;
}
-bool regdb_store_values(const char *key, struct regval_ctr *values)
+int regdb_fetch_values(const char* key, struct regval_ctr *values)
+{
+ return regdb_fetch_values_internal(regdb, key, values);
+}
+
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+ struct regval_ctr *values)
{
TDB_DATA old_data, data;
char *keystr = NULL;
DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(db, key)) {
goto done;
}
goto done;
}
- old_data = dbwrap_fetch_bystring(regdb, ctx, keystr);
+ old_data = dbwrap_fetch_bystring(db, ctx, keystr);
if ((old_data.dptr != NULL)
&& (old_data.dsize == data.dsize)
goto done;
}
- status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE);
+ status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE);
result = NT_STATUS_IS_OK(status);
return result;
}
+bool regdb_store_values(const char *key, struct regval_ctr *values)
+{
+ return regdb_store_values_internal(regdb, key, values);
+}
+
static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
struct security_descriptor **psecdesc)
{
DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(regdb, key)) {
err = WERR_BADFILE;
goto done;
}
WERROR err = WERR_NOMEM;
TDB_DATA tdbdata;
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(regdb, key)) {
err = WERR_BADFILE;
goto done;
}
{
uint32 dwValue;
- if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
+ if (!pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
dwValue = 0;
}
return WERR_OK;
}
+/**
+ * re-initialize the list of subkeys (to the emtpy list)
+ * in an already allocated regsubkey_ctr
+ */
+
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr)
+{
+ if (ctr == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ talloc_free(ctr->subkeys_hash);
+ ctr->subkeys_hash = db_open_rbt(ctr);
+ W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash);
+
+ TALLOC_FREE(ctr->subkeys);
+
+ ctr->num_subkeys = 0;
+ ctr->seqnum = 0;
+
+ return WERR_OK;
+}
+
WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
{
if (ctr == NULL) {
{
WERROR werr;
- werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash,
+ werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash,
keyname,
make_tdb_data((uint8 *)&idx,
sizeof(idx)),
{
WERROR werr;
- werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash,
+ werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash,
keyname));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("error unhashing key '%s' in container: %s\n",
return WERR_INVALID_PARAM;
}
- data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname);
+ data = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname);
if (data.dptr == NULL) {
return WERR_NOT_FOUND;
}
return True;
}
-/*******************************************************************
- Stream a uint16* (allocate memory if unmarshalling)
- ********************************************************************/
-
-bool prs_pointer( const char *name, prs_struct *ps, int depth,
- void *dta, size_t data_size,
- bool (*prs_fn)(const char*, prs_struct*, int, void*) )
-{
- void ** data = (void **)dta;
- uint32 data_p;
-
- /* output f000baaa to stream if the pointer is non-zero. */
-
- data_p = *data ? 0xf000baaa : 0;
-
- if ( !prs_uint32("ptr", ps, depth, &data_p ))
- return False;
-
- /* we're done if there is no data */
-
- if ( !data_p )
- return True;
-
- if (UNMARSHALLING(ps)) {
- if (data_size) {
- if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) )
- return False;
- } else {
- *data = NULL;
- }
- }
-
- return prs_fn(name, ps, depth, *data);
-}
-
-
/*******************************************************************
Stream a uint16.
********************************************************************/
}
}
-/*******************************************************************
- Stream a NTSTATUS
- ********************************************************************/
-
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
-{
- char *q = prs_mem_get(ps, sizeof(uint32));
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data)
- *status = NT_STATUS(RIVAL(q,0));
- else
- *status = NT_STATUS(IVAL(q,0));
- } else {
- if (ps->bigendian_data)
- RSIVAL(q,0,NT_STATUS_V(*status));
- else
- SIVAL(q,0,NT_STATUS_V(*status));
- }
-
- DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
- nt_errstr(*status)));
-
- ps->data_offset += sizeof(uint32);
-
- return True;
-}
-
/*******************************************************************
Stream a DCE error code
********************************************************************/
return True;
}
-
-/*******************************************************************
- Stream a WERROR
- ********************************************************************/
-
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
-{
- char *q = prs_mem_get(ps, sizeof(uint32));
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data)
- *status = W_ERROR(RIVAL(q,0));
- else
- *status = W_ERROR(IVAL(q,0));
- } else {
- if (ps->bigendian_data)
- RSIVAL(q,0,W_ERROR_V(*status));
- else
- SIVAL(q,0,W_ERROR_V(*status));
- }
-
- DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
- win_errstr(*status)));
-
- ps->data_offset += sizeof(uint32);
-
- return True;
-}
-
-
/******************************************************************
Stream an array of uint8s. Length is number of uint8s.
********************************************************************/
return True;
}
-/******************************************************************
- Start using a function for streaming unicode chars. If unmarshalling,
- output must be little-endian, if marshalling, input must be little-endian.
- ********************************************************************/
-
-static void dbg_rw_punival(bool charmode, const char *name, int depth, prs_struct *ps,
- char *in_buf, char *out_buf, int len)
-{
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data) {
- for (i = 0; i < len; i++)
- SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i));
- } else {
- for (i = 0; i < len; i++)
- SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i));
- }
- } else {
- if (ps->bigendian_data) {
- for (i = 0; i < len; i++)
- RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
- } else {
- for (i = 0; i < len; i++)
- SSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
- }
- }
-
- DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name));
- if (charmode)
- print_asc(5, (unsigned char*)out_buf, 2*len);
- else {
- for (i = 0; i < len; i++)
- DEBUGADD(5,("%04x ", out_buf[i]));
- }
- DEBUGADD(5,("\n"));
-}
-
-/******************************************************************
- Stream a unistr. Always little endian.
- ********************************************************************/
-
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
-{
- char *q = prs_mem_get(ps, len * sizeof(uint16));
- if (q == NULL)
- return False;
-
- dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len);
- ps->data_offset += (len * sizeof(uint16));
-
- return True;
-}
-
/******************************************************************
Stream an array of uint32s. Length is number of uint32s.
********************************************************************/
return True;
}
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str)
-{
- size_t len;
- char *tmp_str;
-
- if (UNMARSHALLING(ps)) {
- len = strlen(&ps->data_p[ps->data_offset]);
- } else {
- len = strlen(*str);
- }
-
- tmp_str = PRS_ALLOC_MEM(ps, char, len+1);
-
- if (tmp_str == NULL) {
- return False;
- }
-
- if (MARSHALLING(ps)) {
- strncpy(tmp_str, *str, len);
- }
-
- if (!prs_string(name, ps, depth, tmp_str, len+1)) {
- return False;
- }
-
- *str = tmp_str;
- return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
-{
- *offset = ps->data_offset;
- if (UNMARSHALLING(ps)) {
- /* reading. */
- return prs_uint16(name, ps, depth, data16);
- } else {
- char *q = prs_mem_get(ps, sizeof(uint16));
- if(q ==NULL)
- return False;
- ps->data_offset += sizeof(uint16);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
- uint32 ptr_uint16, uint32 start_offset)
-{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint16 data_size = ps->data_offset - start_offset;
- uint32 old_offset = ps->data_offset;
-
- ps->data_offset = ptr_uint16;
- if(!prs_uint16(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
- } else {
- ps->data_offset = start_offset + (uint32)(*data16);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper. Call this and it sets up a pointer to where the
- uint32 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
-{
- *offset = ps->data_offset;
- if (UNMARSHALLING(ps) && (data32 != NULL)) {
- /* reading. */
- return prs_uint32(name, ps, depth, data32);
- } else {
- ps->data_offset += sizeof(uint32);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper. call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
- uint32 ptr_uint32, uint32 data_size)
-{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint32 old_offset = ps->data_offset;
- ps->data_offset = ptr_uint32;
- if(!prs_uint32(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
- }
- return True;
-}
-
-/* useful function to store a structure in rpc wire format */
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps)
-{
- TDB_DATA dbuf;
- dbuf.dptr = (uint8 *)ps->data_p;
- dbuf.dsize = prs_offset(ps);
- return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE);
-}
-
-/* useful function to fetch a structure into rpc wire format */
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx)
-{
- TDB_DATA dbuf;
-
- prs_init_empty(ps, mem_ctx, UNMARSHALL);
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- return -1;
-
- prs_give_memory(ps, (char *)dbuf.dptr, dbuf.dsize, True);
-
- return 0;
-}
-
-/*******************************************************************
- hash a stream.
- ********************************************************************/
-
-bool prs_hash1(prs_struct *ps, uint32 offset, int len)
-{
- char *q;
-
- q = ps->data_p;
- q = &q[offset];
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("prs_hash1\n"));
- dump_data(100, (uint8 *)ps->sess_key, 16);
- dump_data(100, (uint8 *)q, len);
-#endif
- arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len);
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, (uint8 *)q, len);
-#endif
-
- return True;
-}
-
/*******************************************************************
Create a digest over the entire packet (including the data), and
MD5 it with the session key.
NTSTATUS status;
/* Work out max allowed. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
/* map the generic bits to the lsa policy ones */
se_map_generic(&des_access, &lsa_policy_mapping);
const char *name;
DOM_SID *sid = NULL;
union lsa_PolicyInformation *info = NULL;
+ uint32_t acc_required = 0;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
return NT_STATUS_INVALID_HANDLE;
}
+ switch (r->in.level) {
+ case LSA_POLICY_INFO_AUDIT_LOG:
+ case LSA_POLICY_INFO_AUDIT_EVENTS:
+ acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_PD:
+ acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_ROLE:
+ case LSA_POLICY_INFO_REPLICA:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_QUOTA:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_MOD:
+ case LSA_POLICY_INFO_AUDIT_FULL_SET:
+ /* according to MS-LSAD 3.1.4.4.3 */
+ return NT_STATUS_INVALID_PARAMETER;
+ case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
+ acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_DNS:
+ case LSA_POLICY_INFO_DNS_INT:
+ case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ default:
+ break;
+ }
+
+ if (!(handle->access & acc_required)) {
+ /* return NT_STATUS_ACCESS_DENIED; */
+ }
+
info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
if (!info) {
return NT_STATUS_NO_MEMORY;
break;
}
break;
- case LSA_POLICY_INFO_DNS: {
+ case LSA_POLICY_INFO_DNS:
+ case LSA_POLICY_INFO_DNS_INT: {
struct pdb_domain_info *dominfo;
if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
return status;
}
+/***************************************************************************
+ _lsa_QueryInfoPolicy2
+ ***************************************************************************/
+
+NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
+ struct lsa_QueryInfoPolicy2 *r2)
+{
+ struct lsa_QueryInfoPolicy r;
+
+ if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
+ p->rng_fault_state = True;
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ ZERO_STRUCT(r);
+ r.in.handle = r2->in.handle;
+ r.in.level = r2->in.level;
+ r.out.info = r2->out.info;
+
+ return _lsa_QueryInfoPolicy(p, &r);
+}
+
/***************************************************************************
_lsa_lookup_sids_internal
***************************************************************************/
return NT_STATUS_ACCESS_DENIED;
}
- status = privilege_delete_account(&info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
- nt_errstr(status)));
+ switch (info->type) {
+ case LSA_HANDLE_ACCOUNT_TYPE:
+ status = privilege_delete_account(&info->sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+ break;
+ default:
+ return NT_STATUS_INVALID_HANDLE;
}
+ close_policy_hnd(p, r->in.handle);
+ ZERO_STRUCTP(r->out.handle);
+
return status;
}
NTSTATUS _lsa_CreateAccount(pipes_struct *p,
struct lsa_CreateAccount *r)
{
+ NTSTATUS status;
struct lsa_info *handle;
struct lsa_info *info;
+ uint32_t acc_granted;
+ struct security_descriptor *psd;
+ uint32_t sd_size;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
/* check if the user has enough rights */
- /*
- * I don't know if it's the right one. not documented.
- * but guessed with rpcclient.
- */
- if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT))
+ if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* map the generic bits to the lsa policy ones */
+ se_map_generic(&r->in.access_mask, &lsa_account_mapping);
+
+ status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
+ &lsa_account_mapping,
+ r->in.sid, LSA_POLICY_ALL_ACCESS);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = access_check_object(psd, p->server_info->ptok,
+ NULL, 0, r->in.access_mask,
+ &acc_granted, "_lsa_CreateAccount");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if ( is_privileged_sid( r->in.sid ) )
return NT_STATUS_OBJECT_NAME_COLLISION;
}
info->sid = *r->in.sid;
- info->access = r->in.access_mask;
+ info->access = acc_granted;
info->type = LSA_HANDLE_ACCOUNT_TYPE;
/* get a (unique) handle. open a policy on it. */
* handle - so don't check against policy handle. */
/* Work out max allowed. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
/* map the generic bits to the lsa account ones */
se_map_generic(&des_access, &lsa_account_mapping);
return NT_STATUS_OK;
}
+/***************************************************************************
+ _lsa_LookupPrivName
+ ***************************************************************************/
+
+NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
+ struct lsa_LookupPrivName *r)
+{
+ struct lsa_info *info = NULL;
+ const char *name;
+ struct lsa_StringLarge *lsa_name;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (info->type != LSA_HANDLE_POLICY_TYPE) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ name = luid_to_privilege_name((LUID *)r->in.luid);
+ if (!name) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
+ if (!lsa_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ lsa_name->string = talloc_strdup(lsa_name, name);
+ if (!lsa_name->string) {
+ TALLOC_FREE(lsa_name);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *r->out.name = lsa_name;
+
+ return NT_STATUS_OK;
+}
+
/***************************************************************************
_lsa_QuerySecurity
***************************************************************************/
return status;
}
- switch (r->in.sec_info) {
- case 1:
- /* SD contains only the owner */
- if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- case 4:
- /* SD contains only the ACL */
- if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
+ *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
+ if (!*r->out.sdbuf) {
+ return NT_STATUS_NO_MEMORY;
}
return status;
return NT_STATUS_OK;
}
+/***************************************************************************
+ _lsa_EnumAccountsWithUserRight
+ ***************************************************************************/
+
+NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
+ struct lsa_EnumAccountsWithUserRight *r)
+{
+ NTSTATUS status;
+ struct lsa_info *info = NULL;
+ struct dom_sid *sids = NULL;
+ int num_sids = 0;
+ uint32_t i;
+ SE_PRIV mask;
+
+ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (info->type != LSA_HANDLE_POLICY_TYPE) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!r->in.name || !r->in.name->string) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ if (!se_priv_from_name(r->in.name->string, &mask)) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ status = privilege_enum_sids(&mask, p->mem_ctx,
+ &sids, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ r->out.sids->num_sids = num_sids;
+ r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
+ r->out.sids->num_sids);
+
+ for (i=0; i < r->out.sids->num_sids; i++) {
+ r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
+ &sids[i]);
+ if (!r->out.sids->sids[i].sid) {
+ TALLOC_FREE(r->out.sids->sids);
+ r->out.sids->num_sids = 0;
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
+ _lsa_Delete
+ ***************************************************************************/
+
+NTSTATUS _lsa_Delete(pipes_struct *p,
+ struct lsa_Delete *r)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
/*
* From here on the server routines are just dummy ones to make smbd link with
* librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
* pulling the server stubs across one by one.
*/
-NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
- struct lsa_QueryInfoPolicy2 *r2)
-{
- struct lsa_QueryInfoPolicy r;
-
- if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- ZERO_STRUCT(r);
- r.in.handle = r2->in.handle;
- r.in.level = r2->in.level;
- r.out.info = r2->out.info;
-
- return _lsa_QueryInfoPolicy(p, &r);
-}
-
NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
{
p->rng_fault_state = True;
Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
********************************************************************/
-void map_max_allowed_access(const NT_USER_TOKEN *token,
- uint32_t *pacc_requested)
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+ const struct unix_user_token *unix_token,
+ uint32_t *pacc_requested)
{
if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
return;
*pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
/* root gets anything. */
- if (geteuid() == sec_initial_uid()) {
+ if (unix_token->uid == sec_initial_uid()) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
/* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
- if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
- is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
+ if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
+ is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
DOM_SID domadmin_sid;
sid_copy( &domadmin_sid, get_global_sam_sid() );
sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
- if (is_sid_in_token(token, &domadmin_sid)) {
+ if (is_sid_in_token(nt_token, &domadmin_sid)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
}
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
se_map_generic( &des_access, &dom_generic_mapping );
switch (sid_type) {
case SID_NAME_USER:
become_root();
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&min_password_length);
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&password_properties);
unbecome_root();
/* AS ROOT !!! */
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
dominfo->min_password_length = tmp;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
dominfo->password_history_length = tmp;
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&dominfo->password_properties);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
/* !AS ROOT */
return NT_STATUS_NO_SUCH_USER;
/* check if access can be granted as requested by client. */
-
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
se_map_generic(&des_access, &usr_generic_mapping);
/* AS ROOT !!! */
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
r->min_password_length = account_policy_temp;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
r->password_history_length = account_policy_temp;
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&r->password_properties);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
/* !AS ROOT */
r->num_groups = count_sam_groups(dinfo->disp_info);
r->num_aliases = count_sam_aliases(dinfo->disp_info);
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
+ pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
{
uint32_t ul;
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
+ pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
u_logout = (time_t)ul;
}
become_root();
- pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1) {
u_lock_duration *= 60;
}
- pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
r->lockout_threshold = account_policy_temp;
/* !AS ROOT */
/* AS ROOT !!! */
- pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1) {
u_lock_duration *= 60;
}
- pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
r->lockout_threshold = account_policy_temp;
/* !AS ROOT */
sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
&sid, SAMR_USR_RIGHTS_WRITE_PW);
was observed from a win98 client trying to enumerate users (when configured
user level access control on shares) --jerry */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
se_map_generic( &des_access, &sam_generic_mapping );
return NT_STATUS_ACCESS_DENIED;
}
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
se_map_generic(&des_access, &sam_generic_mapping);
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
se_map_generic(&des_access,&ali_generic_mapping);
}
become_root();
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&min_password_length);
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&password_properties);
unbecome_root();
}
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
se_map_generic(&des_access,&grp_generic_mapping);
u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
- pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
(uint32_t)r->min_password_length);
- pdb_set_account_policy(AP_PASSWORD_HISTORY,
+ pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
(uint32_t)r->password_history_length);
- pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
(uint32_t)r->password_properties);
- pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
- pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
+ pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
+ pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
return NT_STATUS_OK;
}
u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
- pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
+ pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
return NT_STATUS_OK;
}
u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
- pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
- pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
- pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+ pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
+ pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
+ pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
(uint32_t)r->lockout_threshold);
return NT_STATUS_OK;
uint32_t pwd_max_age = 0;
time_t now = time(NULL);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age);
if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
pwd_max_age = get_time_t_max();
Delete a printer given a handle.
****************************************************************************/
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
+static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
{
char *cmd = lp_deleteprinter_cmd();
char *command = NULL;
return WERR_BADFID; /* What to return here? */
/* go ahead and re-read the services immediately */
+ become_root();
reload_services(false);
+ unbecome_root();
if ( lp_servicenumber( sharename ) < 0 )
return WERR_ACCESS_DENIED;
/****************************************************************************
****************************************************************************/
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
+static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
{
char *cmd = lp_addport_cmd();
char *command = NULL;
}
/* reload our services immediately */
+ become_root();
reload_services(false);
+ unbecome_root();
numlines = 0;
/* Get lines and convert them back to dos-codepage */
wrapper around the enumer ports command
****************************************************************************/
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
+static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
{
char *cmd = lp_enumports_cmd();
char **qlines = NULL;
if (lp_browseable(snum) && lp_snum_ok(snum) &&
is_enumeration_allowed(p, snum) &&
(all_shares || !is_hidden_share(snum)) ) {
- DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
+ DEBUG(10, ("counting service %s\n",
+ lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
allowed[snum] = true;
num_entries++;
} else {
- DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
+ DEBUG(10, ("NOT counting service %s\n",
+ lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
}
}
conn,
false,
r->in.file,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
conn,
false,
r->in.file,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
return result;
}
+static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_CreateSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_lsa_DeleteObject(cli, mem_ctx,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF_PTR new_val;
+ NTTIME new_mtime = 0;
+ struct lsa_DATA_BUF_PTR old_val;
+ NTTIME old_mtime = 0;
+ DATA_BLOB session_key;
+ DATA_BLOB new_blob = data_blob_null;
+ DATA_BLOB old_blob = data_blob_null;
+ char *new_secret, *old_secret;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ ZERO_STRUCT(new_val);
+ ZERO_STRUCT(old_val);
+
+ status = rpccli_lsa_QuerySecret(cli, mem_ctx,
+ &sec_handle,
+ &new_val,
+ &new_mtime,
+ &old_val,
+ &old_mtime);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (new_val.buf) {
+ new_blob = data_blob_const(new_val.buf->data, new_val.buf->length);
+ }
+ if (old_val.buf) {
+ old_blob = data_blob_const(old_val.buf->data, old_val.buf->length);
+ }
+
+ new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key);
+ old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key);
+ if (new_secret) {
+ d_printf("new secret: %s\n", new_secret);
+ }
+ if (old_secret) {
+ d_printf("old secret: %s\n", old_secret);
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF new_val;
+ struct lsa_DATA_BUF old_val;
+ DATA_BLOB enc_key;
+ DATA_BLOB session_key;
+
+ if (argc < 3) {
+ printf("Usage: %s name secret\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ ZERO_STRUCT(new_val);
+ ZERO_STRUCT(old_val);
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ enc_key = sess_encrypt_string(argv[2], &session_key);
+
+ new_val.length = enc_key.length;
+ new_val.size = enc_key.length;
+ new_val.data = enc_key.data;
+
+ status = rpccli_lsa_SetSecret(cli, mem_ctx,
+ &sec_handle,
+ &new_val,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF *val;
+ DATA_BLOB session_key;
+ DATA_BLOB blob;
+ char *secret;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ ZERO_STRUCT(val);
+
+ status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx,
+ &handle,
+ &name,
+ &val);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (val) {
+ blob = data_blob_const(val->data, val->length);
+ }
+
+ secret = sess_decrypt_string(mem_ctx, &blob, &session_key);
+ if (secret) {
+ d_printf("secret: %s\n", secret);
+ }
+
+ done:
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF val;
+ DATA_BLOB session_key;
+ DATA_BLOB enc_key;
+
+ if (argc < 3) {
+ printf("Usage: %s name secret\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ ZERO_STRUCT(val);
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ enc_key = sess_encrypt_string(argv[2], &session_key);
+
+ val.length = enc_key.length;
+ val.size = enc_key.length;
+ val.data = enc_key.data;
+
+ status = rpccli_lsa_StorePrivateData(cli, mem_ctx,
+ &handle,
+ &name,
+ &val);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
/* List of commands exported by this module */
{ "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
{ "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" },
{ "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" },
+ { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" },
+ { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" },
+ { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" },
+ { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" },
+ { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" },
+ { "storeprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_store_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Store Private Data", "" },
{ NULL }
};
return werror;
}
+static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ WERROR result;
+ NTSTATUS status;
+ struct policy_handle handle, gdi_handle;
+ const char *printername;
+ struct spoolss_DevmodeContainer devmode_ctr;
+
+ RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
+
+ result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
+ printername,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
+ &handle,
+ &gdi_handle,
+ &devmode_ctr,
+ &result);
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&gdi_handle)) {
+ rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+ }
+
+ return result;
+}
+
/* List of commands exported by this module */
struct cmd_set spoolss_commands[] = {
{ "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
{ "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
{ "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
+ { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },
{ NULL }
};
. $incdir/test_functions.sh
}
+SMB_CONF_PATH="$CONFFILE"
+export SMB_CONF_PATH
+
tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7"
#tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE "
tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE "
tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K"
tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1"
tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST"
+tests="$tests LOCAL-BASE64 LOCAL-GENCACHE"
skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN"
skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST"
DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
"offset %.0f, len = %u (mid = %u)\n",
- fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
+ fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
(unsigned int)aio_ex->req->mid ));
outstanding_aio_calls++;
DEBUG(10,("schedule_aio_write_and_X: failed to schedule "
"aio_write for file %s, offset %.0f, len = %u "
"(mid = %u)\n",
- fsp->fsp_name, (double)startpos,
+ fsp_str_dbg(fsp), (double)startpos,
(unsigned int)numtowrite,
(unsigned int)req->mid ));
return False;
"failed.");
}
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
- "behind for file %s\n", fsp->fsp_name ));
+ "behind for file %s\n", fsp_str_dbg(fsp)));
}
outstanding_aio_calls++;
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
"%s, offset %.0f, len = %u (mid = %u) "
"outstanding_aio_calls = %d\n",
- fsp->fsp_name, (double)startpos, (unsigned int)numtowrite,
+ fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite,
(unsigned int)aio_ex->req->mid, outstanding_aio_calls ));
return True;
DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. "
"Error = %s\n",
- aio_ex->fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(aio_ex->fsp), strerror(errno)));
ret = errno;
ERROR_NT(map_nt_error_from_unix(ret));
DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
"nread=%d\n",
- aio_ex->fsp->fsp_name,
+ fsp_str_dbg(aio_ex->fsp),
(int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed "
"for file %s, offset %.0f, len = %u\n",
- aio_ex->fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+ fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)nread ));
return ret;
DEBUG(5,("handle_aio_write_complete: "
"aio_write_behind failed ! File %s "
"is corrupt ! Error %s\n",
- fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
ret = errno;
} else {
DEBUG(0,("handle_aio_write_complete: "
"aio_write_behind failed ! File %s "
"is corrupt ! Wanted %u bytes but "
- "only wrote %d\n", fsp->fsp_name,
+ "only wrote %d\n", fsp_str_dbg(fsp),
(unsigned int)numtowrite,
(int)nwritten ));
ret = EIO;
} else {
DEBUG(10,("handle_aio_write_complete: "
"aio_write_behind completed for file %s\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
}
return 0;
}
if(nwritten == -1) {
DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. "
"nwritten == %d. Error = %s\n",
- fsp->fsp_name, (unsigned int)numtowrite,
+ fsp_str_dbg(fsp), (unsigned int)numtowrite,
(int)nwritten, strerror(errno) ));
/* If errno is ECANCELED then don't return anything to the
ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
}
aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten;
DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
"for file %s, offset %.0f, requested %u, written = %u\n",
- fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+ fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)numtowrite, (unsigned int)nwritten ));
return ret;
if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
DEBUG(10,( "handle_aio_completed: operation mid %u still in "
"process for file %s\n",
- aio_ex->req->mid, aio_ex->fsp->fsp_name ));
+ aio_ex->req->mid, fsp_str_dbg(aio_ex->fsp)));
return False;
}
"expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
(unsigned int)blr->expire_time.tv_sec,
(unsigned int)blr->expire_time.tv_usec, lock_timeout,
- blr->fsp->fnum, blr->fsp->fsp_name ));
+ blr->fsp->fnum, fsp_str_dbg(blr->fsp)));
return True;
}
* Success - we got all the locks.
*/
- DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
- fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
+ DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
+ "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
+ (unsigned int)locktype, num_locks));
reply_lockingX_success(blr);
return True;
DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
Waiting....\n",
- blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
+ blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
return False;
}
DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
"request type %d for file %s fnum = %d\n",
- blr->req->cmd, fsp->fsp_name, fsp->fnum));
+ blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
blr_cancelled = blocking_lock_cancel(fsp,
blr->lock_pid,
if (br_lck) {
DEBUG(10, ("remove_pending_lock_requests_by_mid - "
"removing request type %d for file %s fnum "
- "= %d\n", blr->req->cmd, fsp->fsp_name,
+ "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
fsp->fnum ));
brl_lock_cancel(br_lck,
DEBUG(5,("process_blocking_lock_queue: "
"pending lock fnum = %d for file %s "
"timed out.\n", blr->fsp->fnum,
- blr->fsp->fsp_name ));
+ fsp_str_dbg(blr->fsp)));
brl_lock_cancel(br_lck,
blr->lock_pid,
int i;
uint32 pwHisLen, curr_pwHisLen;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen);
if (pwHisLen == 0) {
return False;
}
* denies machines to change the password. *
* Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */
if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) {
- if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
+ if (pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
DEBUG(1, ("Machine %s cannot change password now, "
"denied by Refuse Machine Password Change policy\n",
username));
return NT_STATUS_ACCOUNT_RESTRICTION;
}
- if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
+ if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
DEBUG(1, ("user %s cannot change password - password too short\n",
username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
TALLOC_CTX *ctx = NULL;
const char *p;
struct connection_struct *conn = fsp->conn;
+ char *fname = NULL;
+ NTSTATUS status;
if (!*lp_magicscript(SNUM(conn))) {
return NT_STATUS_OK;
}
- DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
+ DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
+
+ ctx = talloc_stackframe();
- if (!(p = strrchr_m(fsp->fsp_name,'/'))) {
- p = fsp->fsp_name;
+ fname = fsp->fsp_name->base_name;
+
+ if (!(p = strrchr_m(fname,'/'))) {
+ p = fname;
} else {
p++;
}
if (!strequal(lp_magicscript(SNUM(conn)),p)) {
- return NT_STATUS_OK;
+ status = NT_STATUS_OK;
+ goto out;
}
- ctx = talloc_stackframe();
-
if (*lp_magicoutput(SNUM(conn))) {
magic_output = lp_magicoutput(SNUM(conn));
} else {
magic_output = talloc_asprintf(ctx,
"%s.out",
- fsp->fsp_name);
+ fname);
}
if (!magic_output) {
- TALLOC_FREE(ctx);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
/* Ensure we don't depend on user's PATH. */
- p = talloc_asprintf(ctx, "./%s", fsp->fsp_name);
+ p = talloc_asprintf(ctx, "./%s", fname);
if (!p) {
- TALLOC_FREE(ctx);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
- if (chmod(fsp->fsp_name,0755) == -1) {
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(errno);
+ if (chmod(fname, 0755) == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
ret = smbrun(p,&tmp_fd);
DEBUG(3,("Invoking magic command %s gave %d\n",
p,ret));
- unlink(fsp->fsp_name);
+ unlink(fname);
if (ret != 0 || tmp_fd == -1) {
if (tmp_fd != -1) {
close(tmp_fd);
}
- TALLOC_FREE(ctx);
- return NT_STATUS_UNSUCCESSFUL;
+ status = NT_STATUS_UNSUCCESSFUL;
+ goto out;
}
outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
if (outfd == -1) {
int err = errno;
close(tmp_fd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
if (sys_fstat(tmp_fd,&st) == -1) {
int err = errno;
close(tmp_fd);
close(outfd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
int err = errno;
close(tmp_fd);
close(outfd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
close(tmp_fd);
if (close(outfd) == -1) {
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
+
+ status = NT_STATUS_OK;
+
+ out:
TALLOC_FREE(ctx);
- return NT_STATUS_OK;
+ return status;
}
/****************************************************************************
bool delete_file = false;
bool changed_user = false;
struct share_mode_lock *lck = NULL;
- struct smb_filename *smb_fname = NULL;
- char *fname = NULL;
NTSTATUS status = NT_STATUS_OK;
int ret;
struct file_id id;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
/*
* Lock the share entries, and determine if we should delete
* on close. If so delete whilst the lock is still in effect.
if (lck == NULL) {
DEBUG(0, ("close_remove_share_mode: Could not get share mode "
- "lock for file %s\n", smb_fname_str_dbg(smb_fname)));
+ "lock for file %s\n", fsp_str_dbg(fsp)));
status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_remove_share_mode: Could not delete share "
"entry for file %s\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
}
if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
*/
DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
- "- deleting file.\n", smb_fname_str_dbg(smb_fname)));
+ "- deleting file.\n", fsp_str_dbg(fsp)));
/*
* Don't try to update the write time when we delete the file
DEBUG(5,("close_remove_share_mode: file %s. "
"Change user to uid %u\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
(unsigned int)lck->delete_token->uid));
if (!push_sec_ctx()) {
hasn't been renamed. */
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(conn, smb_fname);
+ ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(conn, smb_fname);
+ ret = SMB_VFS_STAT(conn, fsp->fsp_name);
}
if (ret != 0) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and stat failed with error %s\n",
- smb_fname_str_dbg(smb_fname), strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
/*
* Don't save the errno here, we ignore this error
*/
goto done;
}
- id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
if (!file_id_equal(&fsp->file_id, &id)) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and dev and/or inode does not match\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
"stat file_id %s\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
file_id_string_tos(&id)));
/*
}
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && !is_ntfs_stream_smb_fname(smb_fname)) {
+ && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
- status = delete_all_streams(conn, smb_fname->base_name);
+ status = delete_all_streams(conn, fsp->fsp_name->base_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("delete_all_streams failed: %s\n",
}
- if (SMB_VFS_UNLINK(conn, smb_fname) != 0) {
+ if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
/*
* This call can potentially fail as another smbd may
* have had the file open with delete on close set and
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and unlink failed with error %s\n",
- smb_fname_str_dbg(smb_fname), strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
status = map_nt_error_from_unix(errno);
}
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
notify_fname(conn, NOTIFY_ACTION_REMOVED,
FILE_NOTIFY_CHANGE_FILE_NAME,
- fname);
-
- TALLOC_FREE(fname);
+ fsp->fsp_name->base_name);
/* As we now have POSIX opens which can unlink
* with other open files we may have taken
}
TALLOC_FREE(lck);
- TALLOC_FREE(smb_fname);
return status;
}
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
{
- struct smb_filename *smb_fname = NULL;
struct smb_file_time ft;
NTSTATUS status;
int ret = -1;
fsp->close_write_time = timespec_current();
}
- /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
} else {
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(fsp->conn, smb_fname);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(fsp->conn, smb_fname);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
}
if (ret == -1) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
- if (!VALID_STAT(smb_fname->st)) {
+ if (!VALID_STAT(fsp->fsp_name->st)) {
/* if it doesn't seem to be a real file */
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
ft.mtime = fsp->close_write_time;
- status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true);
+ status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ return status;
}
- out:
- TALLOC_FREE(smb_fname);
return status;
}
status = ntstatus_keeperror(status, tmp);
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
- conn->server_info->unix_name,fsp->fsp_name,
+ conn->server_info->unix_name, fsp_str_dbg(fsp),
conn->num_files_open - 1,
nt_errstr(status) ));
enum file_close_type close_type)
{
struct share_mode_lock *lck = NULL;
- struct smb_filename *smb_dname = NULL;
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_dname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/*
* NT can set delete_on_close of the last open
* reference to a directory also.
if (lck == NULL) {
DEBUG(0, ("close_directory: Could not get share mode lock for "
- "%s\n", smb_fname_str_dbg(smb_dname)));
+ "%s\n", fsp_str_dbg(fsp)));
status = NT_STATUS_INVALID_PARAMETER;
goto out;
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_directory: Could not delete share entry for "
- "%s\n", smb_fname_str_dbg(smb_dname)));
+ "%s\n", fsp_str_dbg(fsp)));
}
if (fsp->initial_delete_on_close) {
become_user(fsp->conn, fsp->vuid);
became_user = True;
}
- send_stat_cache_delete_message(fsp->fsp_name);
+ send_stat_cache_delete_message(fsp->fsp_name->base_name);
set_delete_on_close_lck(lck, True, ¤t_user.ut);
if (became_user) {
unbecome_user();
TALLOC_FREE(lck);
- status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname);
+ status = rmdir_internals(talloc_tos(), fsp->conn,
+ fsp->fsp_name);
DEBUG(5,("close_directory: %s. Delete on close was set - "
"deleting directory returned %s.\n",
- smb_fname_str_dbg(smb_dname), nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
/* unbecome user. */
pop_sec_ctx();
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
- smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno,
+ fsp_str_dbg(fsp), fsp->fh->fd, errno,
strerror(errno)));
}
out:
TALLOC_FREE(lck);
- TALLOC_FREE(smb_dname);
return status;
}
if (S_ISDIR(smb_fname->st.st_ex_mode))
*dosmode |= aDIR;
- *dosmode |= set_sparse_flag(smb_fname->st);
- *dosmode |= set_link_read_only_flag(smb_fname->st);
+ *dosmode |= set_sparse_flag(&smb_fname->st);
+ *dosmode |= set_link_read_only_flag(&smb_fname->st);
return true;
}
}
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name);
+ FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
return true;
}
reply_nterror(req, status);
}
}
-
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
- NTSTATUS defstatus, int line, const char *file)
-{
- int eclass=defclass;
- int ecode=defcode;
- NTSTATUS ntstatus = defstatus;
- int i=0;
-
- TALLOC_FREE(req->outbuf);
- reply_outbuf(req, 0, 0);
-
- if (errno != 0) {
- DEBUG(3,("unix_error_packet: error string = %s\n",
- strerror(errno)));
-
- while (unix_dos_nt_errmap[i].dos_class != 0) {
- if (unix_dos_nt_errmap[i].unix_error == errno) {
- eclass = unix_dos_nt_errmap[i].dos_class;
- ecode = unix_dos_nt_errmap[i].dos_code;
- ntstatus = unix_dos_nt_errmap[i].nt_error;
- break;
- }
- i++;
- }
- }
-
- error_packet_set((char *)req->outbuf, eclass, ecode, ntstatus,
- line, file);
-}
Does this name match a fake filename ?
****************************************************************************/
-enum FAKE_FILE_TYPE is_fake_file(const char *fname)
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
{
#ifdef HAVE_SYS_QUOTAS
int i;
+ char *fname = NULL;
+ NTSTATUS status;
#endif
- if (!fname) {
+ if (!smb_fname) {
return FAKE_FILE_TYPE_NONE;
}
#ifdef HAVE_SYS_QUOTAS
+ status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return FAKE_FILE_TYPE_NONE;
+ }
+
for (i=0;fake_files[i].name!=NULL;i++) {
if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
+ TALLOC_FREE(fname);
return fake_files[i].type;
}
}
+ TALLOC_FREE(fname);
#endif
return FAKE_FILE_TYPE_NONE;
NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
uint16_t current_vuid,
enum FAKE_FILE_TYPE fake_file_type,
- const char *fname,
+ const struct smb_filename *smb_fname,
uint32 access_mask,
files_struct **result)
{
if (conn->server_info->utok.uid != 0) {
DEBUG(3, ("open_fake_file_shared: access_denied to "
"service[%s] file[%s] user[%s]\n",
- lp_servicename(SNUM(conn)), fname,
+ lp_servicename(SNUM(conn)),
+ smb_fname_str_dbg(smb_fname),
conn->server_info->unix_name));
return NT_STATUS_ACCESS_DENIED;
}
DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
- fname, fsp->fnum, (unsigned int)access_mask));
+ smb_fname_str_dbg(smb_fname), fsp->fnum,
+ (unsigned int)access_mask));
fsp->conn = conn;
fsp->fh->fd = -1;
fsp->fh->pos = -1;
fsp->can_lock = False; /* Should this be true ? - No, JRA */
fsp->access_mask = access_mask;
- string_set(&fsp->fsp_name,fname);
-
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(req, fsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+
fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
if (fsp->fake_file_handle==NULL) {
NTSTATUS status;
uint32_t access_granted;
struct security_descriptor *secdesc = NULL;
- char *fname = NULL;
bool ret;
if (conn->server_info->utok.uid == 0 || conn->admin_user) {
return true;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- ret = false;
- goto out;
- }
-
- status = SMB_VFS_GET_NT_ACL(conn, fname,
+ status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION),
access_mask, &access_granted);
ret = NT_STATUS_IS_OK(status);
out:
- TALLOC_FREE(fname);
TALLOC_FREE(secdesc);
return ret;
}
/* you can't read from print files */
if (fsp->print_file) {
+ errno = EBADF;
return -1;
}
}
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
- fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
fsp->fh->pos += ret;
fsp->fh->position_information = fsp->fh->pos;
}
DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
- fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
if (ret != -1) {
fsp->fh->pos += ret;
wcp->file_size = wcp->offset + wcp->data_size;
ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size);
if (ret == -1) {
- DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
- fsp->fsp_name, (double)wcp->file_size, strerror(errno) ));
+ DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f "
+ "error %s\n", fsp_str_dbg(fsp),
+ (double)wcp->file_size, strerror(errno)));
}
return ret;
}
/* Remove the timed event handler. */
TALLOC_FREE(fsp->update_write_time_event);
- DEBUG(5, ("Update write time on %s\n", fsp->fsp_name));
+ DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
/* change the write time if not already changed by someone else */
update_write_time(fsp);
}
TALLOC_FREE(fsp->update_write_time_event);
- DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name));
+ DEBUG(5, ("Update write time immediate on %s\n",
+ fsp_str_dbg(fsp)));
fsp->update_write_time_triggered = true;
}
if (!fsp->modified) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
fsp->modified = True;
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) {
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) {
int dosmode;
trigger_write_time_update(fsp);
- dosmode = dos_mode(fsp->conn, smb_fname);
+ dosmode = dos_mode(fsp->conn, fsp->fsp_name);
if ((lp_store_dos_attributes(SNUM(fsp->conn)) ||
MAP_ARCHIVE(fsp->conn)) &&
!IS_DOS_ARCHIVE(dosmode)) {
- file_set_dosmode(fsp->conn, smb_fname,
- dosmode | aARCH, NULL, false);
+ file_set_dosmode(fsp->conn, fsp->fsp_name,
+ dosmode | aARCH, NULL, false);
}
/*
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
setup_write_cache(fsp,
- smb_fname->st.st_ex_size);
+ fsp->fsp_name->st.st_ex_size);
wcp = fsp->wcp;
}
}
- TALLOC_FREE(smb_fname);
}
#ifdef WITH_PROFILE
return total_written;
}
- DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
- fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
+ DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f "
+ "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd,
+ (double)pos, (unsigned int)n, (double)wcp->offset,
+ (unsigned int)wcp->data_size));
fsp->fh->pos = pos + n;
SAFE_FREE(wcp->data);
SAFE_FREE(fsp->wcp);
- DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name ));
+ DEBUG(10,("delete_write_cache: File %s deleted write cache\n",
+ fsp_str_dbg(fsp)));
}
/****************************************************************************
allocated_write_caches++;
DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
- fsp->fsp_name, (unsigned long)wcp->alloc_size ));
+ fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size));
return True;
}
char *msg;
if (asprintf(&msg, "set_filelen_write_cache: size change "
"on file %s with write cache size = %lu\n",
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
(unsigned long)fsp->wcp->data_size) != -1) {
smb_panic(msg);
} else {
int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
{
if (fsp->fh->fd == -1) {
- return vfs_stat_smb_fname(fsp->conn, fsp->fsp_name, pst);
+ int ret;
+
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
+ if (ret != -1) {
+ *pst = fsp->fsp_name->st;
+ }
+ return ret;
} else {
return SMB_VFS_FSTAT(fsp, pst);
}
}
}
-/**
- * XXX: This is temporary and there should be no callers of this outside of
- * this file once smb_filename is plumbed through all path based operations.
- * The one legitimate caller currently is smb_fname_str_dbg(), which this
- * could be made static for.
- */
-NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
- char **full_name)
-{
- if (smb_fname->stream_name) {
- *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
- smb_fname->stream_name);
- } else {
- *full_name = talloc_strdup(ctx, smb_fname->base_name);
- }
-
- if (!*full_name) {
- return NT_STATUS_NO_MEMORY;
- }
-
- return NT_STATUS_OK;
-}
-
-/**
- * There are actually legitimate callers of this such as functions that
- * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
- * operate on each stream.
- */
-NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
- const char *stream_name,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
-{
- struct smb_filename smb_fname_loc;
-
- ZERO_STRUCT(smb_fname_loc);
-
- /* Setup the base_name/stream_name. */
- smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
- smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
-
- /* Copy the psbuf if one was given. */
- if (psbuf)
- smb_fname_loc.st = *psbuf;
-
- /* Let copy_smb_filename() do the heavy lifting. */
- return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
- const char *fname,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
-{
- NTSTATUS status;
- const char *stream_name = NULL;
- char *base_name = NULL;
-
- if (!lp_posix_pathnames()) {
- stream_name = strchr_m(fname, ':');
- }
-
- /* Setup the base_name/stream_name. */
- if (stream_name) {
- base_name = talloc_strndup(ctx, fname,
- PTR_DIFF(stream_name, fname));
- } else {
- base_name = talloc_strdup(ctx, fname);
- }
-
- if (!base_name) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
- smb_fname_out);
- TALLOC_FREE(base_name);
- return status;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf)
-{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- int ret;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- ret = SMB_VFS_STAT(conn, smb_fname);
- if (ret != -1) {
- *psbuf = smb_fname->st;
- }
-
- TALLOC_FREE(smb_fname);
- return ret;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf)
-{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- int ret;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- ret = SMB_VFS_LSTAT(conn, smb_fname);
- if (ret != -1) {
- *psbuf = smb_fname->st;
- }
-
- TALLOC_FREE(smb_fname);
- return ret;
-}
-
-/**
- * Return a string using the debug_ctx()
- */
-const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
-{
- char *fname = NULL;
- NTSTATUS status;
-
- if (smb_fname == NULL) {
- return "";
- }
- status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return "";
- }
- return fname;
-}
-
-NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
- const struct smb_filename *smb_fname_in,
- struct smb_filename **smb_fname_out)
-{
-
- *smb_fname_out = talloc_zero(ctx, struct smb_filename);
- if (*smb_fname_out == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (smb_fname_in->base_name) {
- (*smb_fname_out)->base_name =
- talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
- if (!(*smb_fname_out)->base_name)
- goto no_mem_err;
- }
-
- if (smb_fname_in->stream_name) {
- (*smb_fname_out)->stream_name =
- talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
- if (!(*smb_fname_out)->stream_name)
- goto no_mem_err;
- }
-
- if (smb_fname_in->original_lcomp) {
- (*smb_fname_out)->original_lcomp =
- talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
- if (!(*smb_fname_out)->original_lcomp)
- goto no_mem_err;
- }
-
- (*smb_fname_out)->st = smb_fname_in->st;
- return NT_STATUS_OK;
-
- no_mem_err:
- TALLOC_FREE(*smb_fname_out);
- return NT_STATUS_NO_MEMORY;
-}
-
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format changes,
struct smb_filename **smb_fname_out,
uint32_t ucf_flags)
{
- SMB_STRUCT_STAT st;
struct smb_filename *smb_fname = NULL;
char *start, *end;
char *dirpath = NULL;
- char *name = NULL;
char *stream = NULL;
bool component_was_mangled = False;
bool name_has_wildcard = False;
bool posix_pathnames = false;
bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
- NTSTATUS result;
+ NTSTATUS status;
int ret = -1;
*smb_fname_out = NULL;
- smb_fname = talloc_zero(talloc_tos(), struct smb_filename);
+ smb_fname = talloc_zero(ctx, struct smb_filename);
if (smb_fname == NULL) {
return NT_STATUS_NO_MEMORY;
}
filename - so don't convert them */
if (!(smb_fname->base_name = talloc_strdup(smb_fname,
orig_path))) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- *smb_fname_out = smb_fname;
- return NT_STATUS_OK;
+ goto done;
}
DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
*/
if (!*orig_path) {
- if (!(name = talloc_strdup(ctx,"."))) {
- return NT_STATUS_NO_MEMORY;
+ if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- if (vfs_stat_smb_fname(conn,name,&st) == 0) {
- smb_fname->st = st;
- } else {
- return map_nt_error_from_unix(errno);
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+ status = map_nt_error_from_unix(errno);
+ goto err;
}
- DEBUG(5,("conversion finished \"\" -> %s\n",name));
+ DEBUG(5, ("conversion finished \"\" -> %s\n",
+ smb_fname->base_name));
goto done;
}
orig_path[1] == '\0')) {
/* Start of pathname can't be "." only. */
if (orig_path[1] == '\0' || orig_path[2] == '\0') {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
} else {
- result =determine_path_error(
- &orig_path[2], allow_wcard_last_component);
+ status =determine_path_error(&orig_path[2],
+ allow_wcard_last_component);
}
- return result;
+ goto err;
}
- if (!(name = talloc_strdup(ctx, orig_path))) {
+ /* Start with the full orig_path as given by the caller. */
+ if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) {
DEBUG(0, ("talloc_strdup failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
/*
if (conn->case_sensitive && !conn->case_preserve &&
!conn->short_case_preserve) {
- strnorm(name, lp_defaultcase(SNUM(conn)));
+ strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn)));
}
/*
*/
if(save_last_component) {
- end = strrchr_m(name, '/');
+ end = strrchr_m(smb_fname->base_name, '/');
if (end) {
- smb_fname->original_lcomp = talloc_strdup(ctx,
+ smb_fname->original_lcomp = talloc_strdup(smb_fname,
end + 1);
} else {
- smb_fname->original_lcomp = talloc_strdup(ctx, name);
+ smb_fname->original_lcomp =
+ talloc_strdup(smb_fname, smb_fname->base_name);
+ }
+ if (smb_fname->original_lcomp == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
posix_pathnames = lp_posix_pathnames();
- /* Strip off the stream. Should we use any of the other stream parsing
- * at this point? Also, should we set the is_stream bit? */
+ /*
+ * Strip off the stream, and add it back when we're done with the
+ * base_name.
+ */
if (!posix_pathnames) {
- stream = strchr_m(name, ':');
+ stream = strchr_m(smb_fname->base_name, ':');
if (stream != NULL) {
- char *tmp = talloc_strdup(ctx, stream);
+ char *tmp = talloc_strdup(smb_fname, stream);
if (tmp == NULL) {
- TALLOC_FREE(name);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
+ /*
+ * Since this is actually pointing into
+ * smb_fname->base_name this truncates base_name.
+ */
*stream = '\0';
stream = tmp;
}
}
- start = name;
+ start = smb_fname->base_name;
- /* If we're providing case insentive semantics or
+ /*
+ * If we're providing case insentive semantics or
* the underlying filesystem is case insensitive,
* then a case-normalized hit in the stat-cache is
* authoratitive. JRA.
+ *
+ * Note: We're only checking base_name. The stream_name will be
+ * added and verified in build_stream_path().
*/
- if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
- stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
- smb_fname->st = st;
+ if((!conn->case_sensitive || !(conn->fs_capabilities &
+ FILE_CASE_SENSITIVE_SEARCH)) &&
+ stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start,
+ &smb_fname->st)) {
goto done;
}
if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
DEBUG(0, ("talloc_strdup failed\n"));
- TALLOC_FREE(name);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
/*
- * stat the name - if it exists then we are all done!
+ * stat the name - if it exists then we can add the stream back (if
+ * there was one) and be done!
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name,&st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name,&st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
if (ret == 0) {
/* Ensure we catch all names with in "/."
this is disallowed under Windows. */
- const char *p = strstr(name, "/."); /* mb safe. */
+ const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
if (p) {
if (p[2] == '/') {
/* Error code within a pathname. */
- result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto fail;
} else if (p[2] == '\0') {
/* Error code at the end of a pathname. */
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
}
- stat_cache_add(orig_path, name, conn->case_sensitive);
- DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
- smb_fname->st = st;
+ /* Add the path (not including the stream) to the cache. */
+ stat_cache_add(orig_path, smb_fname->base_name,
+ conn->case_sensitive);
+ DEBUG(5,("conversion of base_name finished %s -> %s\n",
+ orig_path, smb_fname->base_name));
goto done;
}
DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
- name, dirpath, start));
+ smb_fname->base_name, dirpath, start));
/*
* A special case - if we don't have any mangling chars and are case
* won't help.
*/
- if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
- !mangle_is_mangled(name, conn->params)) {
+ if ((conn->case_sensitive || !(conn->fs_capabilities &
+ FILE_CASE_SENSITIVE_SEARCH)) &&
+ !mangle_is_mangled(smb_fname->base_name, conn->params)) {
goto done;
}
if (save_last_component) {
TALLOC_FREE(smb_fname->original_lcomp);
- smb_fname->original_lcomp = talloc_strdup(ctx,
+ smb_fname->original_lcomp = talloc_strdup(smb_fname,
end ? end + 1 : start);
if (!smb_fname->original_lcomp) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
if (ISDOT(start)) {
if (!end) {
/* Error code at the end of a pathname. */
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
} else {
- result = determine_path_error(end+1,
+ status = determine_path_error(end+1,
allow_wcard_last_component);
}
goto fail;
/* Wildcard not valid anywhere. */
if (name_has_wildcard && !allow_wcard_last_component) {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
/* Wildcards never valid within a pathname. */
if (name_has_wildcard && end) {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name, &st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name, &st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
if (ret == 0) {
* It exists. it must either be a directory or this must
* be the last part of the path for it to be OK.
*/
- if (end && !S_ISDIR(st.st_ex_mode)) {
+ if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) {
/*
* An intermediate part of the name isn't
* a directory.
* applications depend on the difference between
* these two errors.
*/
- result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto fail;
}
- if (!end) {
- /*
- * We just scanned for, and found the end of
- * the path. We must return the valid stat
- * struct. JRA.
- */
-
- smb_fname->st = st;
- }
-
} else {
char *found_name = NULL;
/* Stat failed - ensure we don't use it. */
- SET_STAT_INVALID(st);
+ SET_STAT_INVALID(smb_fname->st);
/*
* Reset errno so we can detect
if (errno == ENOENT ||
errno == ENOTDIR ||
errno == ELOOP) {
- result =
+ status =
NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
else {
- result =
+ status =
map_nt_error_from_unix(errno);
}
goto fail;
*/
if (errno == ENOTDIR ||
errno == ELOOP) {
- result =
+ status =
NT_STATUS_OBJECT_PATH_NOT_FOUND;
} else {
- result =
+ status =
map_nt_error_from_unix(errno);
}
goto fail;
&unmangled,
conn->params)) {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
- "%s/%s", dirpath,
- unmangled);
+ tmp = talloc_asprintf(
+ smb_fname, "%s/%s",
+ dirpath, unmangled);
TALLOC_FREE(unmangled);
}
else {
}
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start =
+ smb_fname->base_name + start_ofs;
end = start + strlen(start);
}
*/
if (end) {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s/%s", dirpath,
found_name, end+1);
}
else {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s", found_name,
end+1);
}
if (tmp == NULL) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start = smb_fname->base_name + start_ofs;
end = start + strlen(found_name);
*end = '\0';
} else {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s", dirpath,
found_name);
} else {
- tmp = talloc_strdup(ctx,
+ tmp = talloc_strdup(smb_fname,
found_name);
}
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start = smb_fname->base_name + start_ofs;
/*
* We just scanned for, and found the end of
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name,
- &st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name,
- &st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
- if (ret == 0) {
- smb_fname->st = st;
- } else {
- SET_STAT_INVALID(st);
+ if (ret != 0) {
+ SET_STAT_INVALID(smb_fname->st);
}
}
* We should never provide different behaviors
* depending on DEVELOPER!!!
*/
- if (VALID_STAT(st)) {
+ if (VALID_STAT(smb_fname->st)) {
bool delete_pending;
- get_file_infos(vfs_file_id_from_sbuf(conn, &st),
+ get_file_infos(vfs_file_id_from_sbuf(conn,
+ &smb_fname->st),
&delete_pending, NULL);
if (delete_pending) {
- result = NT_STATUS_DELETE_PENDING;
+ status = NT_STATUS_DELETE_PENDING;
goto fail;
}
}
"%s/%s", dirpath, start);
if (!tmp) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
TALLOC_FREE(dirpath);
dirpath = tmp;
TALLOC_FREE(dirpath);
if (!(dirpath = talloc_strdup(ctx,start))) {
DEBUG(0, ("talloc_strdup failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
/*
- * Don't cache a name with mangled or wildcard components
- * as this can change the size.
+ * Cache the dirpath thus far. Don't cache a name with mangled
+ * or wildcard components as this can change the size.
*/
-
if(!component_was_mangled && !name_has_wildcard) {
stat_cache_add(orig_path, dirpath,
conn->case_sensitive);
}
/*
- * Don't cache a name with mangled or wildcard components
- * as this can change the size.
+ * Cache the full path. Don't cache a name with mangled or wildcard
+ * components as this can change the size.
*/
if(!component_was_mangled && !name_has_wildcard) {
- stat_cache_add(orig_path, name, conn->case_sensitive);
+ stat_cache_add(orig_path, smb_fname->base_name,
+ conn->case_sensitive);
}
/*
* The name has been resolved.
*/
- DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
+ DEBUG(5,("conversion finished %s -> %s\n", orig_path,
+ smb_fname->base_name));
done:
- smb_fname->base_name = name;
-
+ /* Add back the stream if one was stripped off originally. */
if (stream != NULL) {
smb_fname->stream_name = stream;
/* Check path now that the base_name has been converted. */
- result = build_stream_path(ctx, conn, orig_path, smb_fname);
- if (!NT_STATUS_IS_OK(result)) {
+ status = build_stream_path(ctx, conn, orig_path, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
}
fail:
DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
if (*dirpath != '\0') {
- smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath,
- start);
+ smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s",
+ dirpath, start);
} else {
- smb_fname->base_name = talloc_strdup(ctx, start);
+ smb_fname->base_name = talloc_strdup(smb_fname, start);
}
if (!smb_fname->base_name) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
*smb_fname_out = smb_fname;
- TALLOC_FREE(name);
TALLOC_FREE(dirpath);
- return result;
+ return status;
+ err:
+ TALLOC_FREE(smb_fname);
+ return status;
}
/****************************************************************************
struct stream_struct *streams = NULL;
if (SMB_VFS_STAT(conn, smb_fname) == 0) {
+ DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
return NT_STATUS_OK;
}
TALLOC_FREE(smb_fname->stream_name);
- smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name);
+ smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name);
+ if (smb_fname->stream_name == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
SET_STAT_INVALID(smb_fname->st);
if (SMB_VFS_STAT(conn, smb_fname) == 0) {
- char *result = NULL;
-
- status = get_full_smb_filename(mem_ctx, smb_fname, &result);
- if (!NT_STATUS_IS_OK(status)) {
- status = NT_STATUS_NO_MEMORY;
- goto fail;
- }
-
- stat_cache_add(orig_path, result, conn->case_sensitive);
- TALLOC_FREE(result);
+ DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
}
status = NT_STATUS_OK;
fail:
connection_struct *conn,
bool dfs_path,
const char *name_in,
- struct smb_filename **pp_smb_fname,
- char **pp_name)
+ struct smb_filename **pp_smb_fname)
{
NTSTATUS status;
char *fname = NULL;
return status;
}
- status = get_full_smb_filename(ctx, *pp_smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = check_name(conn, fname);
+ status = check_name(conn, (*pp_smb_fname)->base_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("filename_convert: check_name failed "
"for name %s with %s\n",
- fname,
+ smb_fname_str_dbg(*pp_smb_fname),
nt_errstr(status) ));
+ TALLOC_FREE(*pp_smb_fname);
return status;
}
- if (pp_name != NULL) {
- *pp_name = fname;
- }
return status;
}
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+ Filename utility functions.
+ Copyright (C) Tim Prouty 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "includes.h"
+
+/**
+ * XXX: This is temporary and there should be no callers of this outside of
+ * this file once smb_filename is plumbed through all path based operations.
+ * The one legitimate caller currently is smb_fname_str_dbg(), which this
+ * could be made static for.
+ */
+NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname,
+ char **full_name)
+{
+ if (smb_fname->stream_name) {
+ /* stream_name must always be NULL if there is no stream. */
+ SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+
+ *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
+ smb_fname->stream_name);
+ } else {
+ *full_name = talloc_strdup(ctx, smb_fname->base_name);
+ }
+
+ if (!*full_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/**
+ * There are actually legitimate callers of this such as functions that
+ * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
+ * operate on each stream.
+ */
+NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
+ const char *stream_name,
+ const SMB_STRUCT_STAT *psbuf,
+ struct smb_filename **smb_fname_out)
+{
+ struct smb_filename smb_fname_loc;
+
+ ZERO_STRUCT(smb_fname_loc);
+
+ /* Setup the base_name/stream_name. */
+ smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
+ smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
+
+ /* Copy the psbuf if one was given. */
+ if (psbuf)
+ smb_fname_loc.st = *psbuf;
+
+ /* Let copy_smb_filename() do the heavy lifting. */
+ return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
+ const char *fname,
+ const SMB_STRUCT_STAT *psbuf,
+ struct smb_filename **smb_fname_out)
+{
+ NTSTATUS status;
+ const char *stream_name = NULL;
+ char *base_name = NULL;
+
+ if (!lp_posix_pathnames()) {
+ stream_name = strchr_m(fname, ':');
+ }
+
+ /* Setup the base_name/stream_name. */
+ if (stream_name) {
+ base_name = talloc_strndup(ctx, fname,
+ PTR_DIFF(stream_name, fname));
+ } else {
+ base_name = talloc_strdup(ctx, fname);
+ }
+
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
+ smb_fname_out);
+ TALLOC_FREE(base_name);
+ return status;
+}
+
+/**
+ * Return a string using the debug_ctx()
+ */
+const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
+{
+ char *fname = NULL;
+ NTSTATUS status;
+
+ if (smb_fname == NULL) {
+ return "";
+ }
+ status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return "";
+ }
+ return fname;
+}
+
+/**
+ * Return a debug string using the debug_ctx(). This can only be called from
+ * DEBUG() macros due to the debut_ctx().
+ */
+const char *fsp_str_dbg(const struct files_struct *fsp)
+{
+ return smb_fname_str_dbg(fsp->fsp_name);
+}
+
+NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname_in,
+ struct smb_filename **smb_fname_out)
+{
+ /* stream_name must always be NULL if there is no stream. */
+ if (smb_fname_in->stream_name) {
+ SMB_ASSERT(smb_fname_in->stream_name[0] != '\0');
+ }
+
+ *smb_fname_out = talloc_zero(ctx, struct smb_filename);
+ if (*smb_fname_out == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (smb_fname_in->base_name) {
+ (*smb_fname_out)->base_name =
+ talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
+ if (!(*smb_fname_out)->base_name)
+ goto no_mem_err;
+ }
+
+ if (smb_fname_in->stream_name) {
+ (*smb_fname_out)->stream_name =
+ talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
+ if (!(*smb_fname_out)->stream_name)
+ goto no_mem_err;
+ }
+
+ if (smb_fname_in->original_lcomp) {
+ (*smb_fname_out)->original_lcomp =
+ talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
+ if (!(*smb_fname_out)->original_lcomp)
+ goto no_mem_err;
+ }
+
+ (*smb_fname_out)->st = smb_fname_in->st;
+ return NT_STATUS_OK;
+
+ no_mem_err:
+ TALLOC_FREE(*smb_fname_out);
+ return NT_STATUS_NO_MEMORY;
+}
+
+/****************************************************************************
+ Simple check to determine if the filename is a stream.
+ ***************************************************************************/
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+ /* stream_name must always be NULL if there is no stream. */
+ if (smb_fname->stream_name) {
+ SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+ }
+
+ if (lp_posix_pathnames()) {
+ return false;
+ }
+
+ return smb_fname->stream_name;
+}
+
+/****************************************************************************
+ Returns true if the filename's stream == "::$DATA"
+ ***************************************************************************/
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+ if (!is_ntfs_stream_smb_fname(smb_fname)) {
+ return false;
+ }
+
+ return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
+}
{
int i;
files_struct *fsp;
+ NTSTATUS status;
/* we want to give out file handles differently on each new
connection because of a common bug in MS clients where they try to
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
- fsp = SMB_MALLOC_P(files_struct);
+ /*
+ * Make a child of the connection_struct as an fsp can't exist
+ * indepenedent of a connection.
+ */
+ fsp = talloc_zero(conn, struct files_struct);
if (!fsp) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(fsp);
-
- fsp->fh = SMB_MALLOC_P(struct fd_handle);
+ /*
+ * This can't be a child of fsp because the file_handle can be ref'd
+ * when doing a dos/fcb open, which will then share the file_handle
+ * across multiple fsps.
+ */
+ fsp->fh = talloc_zero(conn, struct fd_handle);
if (!fsp->fh) {
- SAFE_FREE(fsp);
+ TALLOC_FREE(fsp);
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(fsp->fh);
-
fsp->fh->ref_count = 1;
fsp->fh->fd = -1;
fsp->fnum = i + FILE_HANDLE_OFFSET;
SMB_ASSERT(fsp->fnum < 65536);
- string_set(&fsp->fsp_name,"");
-
+ /*
+ * Create an smb_filename with "" for the base_name. There are very
+ * few NULL checks, so make sure it's initialized with something. to
+ * be safe until an audit can be done.
+ */
+ status = create_synthetic_smb_fname(fsp, "", NULL, NULL,
+ &fsp->fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(fsp);
+ TALLOC_FREE(fsp->fh);
+ }
+
DLIST_ADD(Files, fsp);
DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n",
files_struct *fsp;
for (fsp=Files;fsp;fsp=fsp->next,count++) {
- DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n",
- count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
+ DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, "
+ "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp),
+ fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
file_id_string_tos(&fsp->file_id)));
}
}
if ((fsp->fh->fd == -1) &&
(fsp->oplock_type != NO_OPLOCK) &&
(fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
- DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \
-oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name,
+ DEBUG(0,("file_find_dif: file %s file_id = "
+ "%s, gen = %u oplock_type = %u is a "
+ "stat open with oplock type !\n",
+ fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
(unsigned int)fsp->fh->gen_id,
(unsigned int)fsp->oplock_type ));
{
files_struct *fsp;
size_t dlen;
- char *d_fullname = talloc_asprintf(talloc_tos(),
- "%s/%s",
- dir_fsp->conn->connectpath,
- dir_fsp->fsp_name);
+ char *d_fullname;
+
+ d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
+ dir_fsp->conn->connectpath,
+ dir_fsp->fsp_name->base_name);
if (!d_fullname) {
return false;
d1_fullname = talloc_asprintf(talloc_tos(),
"%s/%s",
fsp->conn->connectpath,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
if (strnequal(d_fullname, d1_fullname, dlen)) {
TALLOC_FREE(d_fullname);
{
DLIST_REMOVE(Files, fsp);
- string_free(&fsp->fsp_name);
-
TALLOC_FREE(fsp->fake_file_handle);
if (fsp->fh->ref_count == 1) {
- SAFE_FREE(fsp->fh);
+ TALLOC_FREE(fsp->fh);
} else {
fsp->fh->ref_count--;
}
information */
ZERO_STRUCTP(fsp);
- SAFE_FREE(fsp);
+ /* fsp->fsp_name is a talloc child and is free'd automatically. */
+ TALLOC_FREE(fsp);
}
/****************************************************************************
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
uint32 create_options, files_struct *to)
{
- SAFE_FREE(to->fh);
+ TALLOC_FREE(to->fh);
to->fh = from->fh;
to->fh->ref_count++;
to->modified = from->modified;
to->is_directory = from->is_directory;
to->aio_write_behind = from->aio_write_behind;
- string_set(&to->fsp_name,from->fsp_name);
+ return fsp_set_smb_fname(to, from->fsp_name);
+}
+
+/**
+ * The only way that the fsp->fsp_name field should ever be set.
+ */
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+ const struct smb_filename *smb_fname_in)
+{
+ NTSTATUS status;
+ struct smb_filename *smb_fname_new;
+
+ status = copy_smb_filename(fsp, smb_fname_in, &smb_fname_new);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ TALLOC_FREE(fsp->fsp_name);
+ fsp->fsp_name = smb_fname_new;
+
+ return NT_STATUS_OK;
}
ZERO_STRUCT(conn_ctx_stack);
ZERO_STRUCT(sec_ctx_stack);
+
+ smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
+ if (!smbd_server_conn) {
+ exit_server("failed to create smbd_server_connection");
+ }
}
const struct iovec *vector,
int count);
+struct smbd_lock_element {
+ uint32_t smbpid;
+ enum brl_type brltype;
+ uint64_t offset;
+ uint64_t count;
+};
+
+NTSTATUS smbd_do_locking(struct smb_request *req,
+ files_struct *fsp,
+ uint8_t type,
+ int32_t timeout,
+ uint16_t num_ulocks,
+ struct smbd_lock_element *ulocks,
+ uint16_t num_locks,
+ struct smbd_lock_element *locks,
+ bool *async);
+
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ bool delete_pending,
+ struct timespec write_time_ts,
+ bool ms_dfs_link,
+ struct ea_list *ea_list,
+ int lock_data_count,
+ char *lock_data,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ unsigned int *pdata_size);
+
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ struct smb_filename *smb_fname,
+ char **ppdata, int total_data,
+ int *ret_data_size);
+
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ int *ret_data_len);
+
void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
const char *reason,
const char *location);
}
DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n",
- subcommand, fsp->fsp_name, pnum));
+ subcommand, fsp_str_dbg(fsp), pnum));
DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt));
char **pp_link_target,
SMB_STRUCT_STAT *sbufp)
{
- SMB_STRUCT_STAT st;
int referral_len = 0;
#if defined(HAVE_BROKEN_READLINK)
char link_target_buf[PATH_MAX];
#endif
size_t bufsize = 0;
char *link_target = NULL;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
if (pp_link_target) {
bufsize = 1024;
link_target = link_target_buf;
}
- if (sbufp == NULL) {
- sbufp = &st;
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err;
}
- if (vfs_lstat_smb_fname(conn, path, sbufp) != 0) {
+ if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n",
path));
+ TALLOC_FREE(smb_fname);
goto err;
}
-
- if (!S_ISLNK(sbufp->st_ex_mode)) {
+ if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
path));
+ TALLOC_FREE(smb_fname);
goto err;
}
+ if (sbufp != NULL) {
+ *sbufp = smb_fname->st;
+ }
+ TALLOC_FREE(smb_fname);
referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1);
if (referral_len == -1) {
static void notify_callback(void *private_data, const struct notify_event *e)
{
files_struct *fsp = (files_struct *)private_data;
- DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name));
+ DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
notify_fsp(fsp, e->action, e->path);
}
return NT_STATUS_NO_MEMORY;
}
+ /* Do notify operations on the base_name. */
if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath,
- fsp->fsp_name) == -1) {
+ fsp->fsp_name->base_name) == -1) {
DEBUG(0, ("asprintf failed\n"));
TALLOC_FREE(fsp->notify);
return NT_STATUS_NO_MEMORY;
struct smbd_server_connection *sconn = smbd_server_conn;
DEBUG(10, ("change_notify_add_request: Adding request for %s: "
- "max_param = %d\n", fsp->fsp_name, (int)max_param));
+ "max_param = %d\n", fsp_str_dbg(fsp), (int)max_param));
if (!(request = talloc(NULL, struct notify_change_request))
|| !(map = talloc(request, struct notify_mid_map))) {
}
}
-/****************************************************************************
- Simple check to determine if the filename is a stream.
- ***************************************************************************/
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
-{
- if (lp_posix_pathnames()) {
- return false;
- }
-
- return smb_fname->stream_name;
-}
-
-/****************************************************************************
- Returns true if the filename's stream == "::$DATA"
- ***************************************************************************/
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
-{
- if (!is_ntfs_stream_smb_fname(smb_fname)) {
- return false;
- }
-
- return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
-}
-
/****************************************************************************
Reply to an NT create and X call on a pipe
****************************************************************************/
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
security_acl_map_generic(psd->sacl, &file_generic_mapping);
if (DEBUGLEVEL >= 10) {
- DEBUG(10,("set_sd for file %s\n", fsp->fsp_name ));
+ DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, psd);
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
if (req->wct < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
attrs = SVAL(req->vwv+0, 0);
&status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
if (ms_has_wild(oldname)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
p++;
&status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- oldname,
- &smb_fname_old,
- &oldname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBntrename);
- return;
- }
- reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ /* The newname must begin with a ':' if the oldname contains a ':'. */
+ if (strchr_m(oldname, ':') && (newname[0] != ':')) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ goto out;
}
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- newname,
- &smb_fname_new,
- &newname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBntrename);
- return;
+ /* rename_internals() calls unix_convert(), so don't call it here. */
+ if (rename_type != RENAME_FLAG_RENAME) {
+ status = filename_convert(ctx, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ oldname,
+ &smb_fname_old);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ goto out;
+ }
+ reply_nterror(req, status);
+ goto out;
}
- reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
- }
- /* The new name must begin with a ':' if the old name is a stream. */
- if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBntrename);
- return;
- }
+ status = filename_convert(ctx, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ newname,
+ &smb_fname_new);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ goto out;
+ }
+ reply_nterror(req, status);
+ goto out;
+ }
- DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
+ DEBUG(3,("reply_ntrename: %s -> %s\n",
+ smb_fname_str_dbg(smb_fname_old),
+ smb_fname_str_dbg(smb_fname_new)));
+ }
switch(rename_type) {
case RENAME_FLAG_RENAME:
+ status = resolve_dfspath(ctx, conn,
+ (req->flags2 &
+ FLAGS2_DFS_PATHNAMES),
+ oldname, &oldname);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("resolve_dfspath failed for name %s "
+ "with %s\n", oldname,
+ nt_errstr(status)));
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = resolve_dfspath(ctx, conn,
+ (req->flags2 &
+ FLAGS2_DFS_PATHNAMES),
+ newname, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("resolve_dfspath failed for name %s "
+ "with %s\n", newname,
+ nt_errstr(status)));
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ DEBUG(3,("reply_ntrename: %s -> %s\n", oldname,
+ newname));
+
status = rename_internals(ctx, conn, req, oldname,
newname, attrs, False, src_has_wcard,
dest_has_wcard, DELETE_ACCESS);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
reply_outbuf(req, 0, 0);
-
+ out:
END_PROFILE(SMBntrename);
return;
}
DEBUG(3,("call_nt_transact_notify_change: notify change "
"called on %s, filter = %s, recursive = %d\n",
- fsp->fsp_name, filter_string, recursive));
+ fsp_str_dbg(fsp), filter_string, recursive));
TALLOC_FREE(filter_string);
}
send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
- fsp->fsp_name, new_name));
+ fsp_str_dbg(fsp), new_name));
return;
}
security_info_wanted = IVAL(params,4);
- DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
- (unsigned int)security_info_wanted ));
+ DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
+ "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
+ (unsigned int)security_info_wanted));
params = nttrans_realloc(ppparams, 4);
if(params == NULL) {
DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
if (DEBUGLEVEL >= 10) {
- DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name));
+ DEBUG(10,("call_nt_transact_query_security_desc for file %s\n",
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, psd);
}
security_info_sent = IVAL(params,4);
- DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
- (unsigned int)security_info_sent ));
+ DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
+ fsp_str_dbg(fsp), (unsigned int)security_info_sent));
if (data_count == 0) {
reply_doserror(req, ERRDOS, ERRnoaccess);
cur_pdata+=12;
DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
- shadow_data->num_volumes,fsp->fsp_name));
+ shadow_data->num_volumes, fsp_str_dbg(fsp)));
if (labels && shadow_data->labels) {
for (i=0;i<shadow_data->num_volumes;i++) {
srvstr_push(pdata, req->flags2,
"on %s: %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status)));
+ TALLOC_FREE(sd);
return status;
}
if (ret == -1) {
DEBUG(0,("change_file_owner_to_parent: failed to fchown "
"file %s to parent directory uid %u. Error "
- "was %s\n", fsp->fsp_name,
+ "was %s\n", fsp_str_dbg(fsp),
(unsigned int)smb_fname_parent->st.st_ex_uid,
strerror(errno) ));
}
DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
- "parent directory uid %u.\n", fsp->fsp_name,
+ "parent directory uid %u.\n", fsp_str_dbg(fsp),
(unsigned int)smb_fname_parent->st.st_ex_uid));
TALLOC_FREE(smb_fname_parent);
uint32 access_mask, /* client requested access mask. */
uint32 open_access_mask) /* what we're actually using in the open. */
{
- char *path = NULL;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
* wildcard characters are allowed in stream names
* only test the basefilename
*/
- wild = fsp->base_fsp->fsp_name;
+ wild = fsp->base_fsp->fsp_name->base_name;
} else {
wild = smb_fname->base_name;
}
conn->case_sensitive)) {
fsp->aio_write_behind = True;
}
-
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &path);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ errno = map_errno_from_nt_status(status);
return status;
}
- string_set(&fsp->fsp_name, path);
- TALLOC_FREE(path);
-
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
str = talloc_asprintf(talloc_tos(),
"validate_my_share_entries: "
"file %s, oplock_type = 0x%x, op_type = 0x%x\n",
- fsp->fsp_name, (unsigned int)fsp->oplock_type,
+ fsp->fsp_name->base_name,
+ (unsigned int)fsp->oplock_type,
(unsigned int)share_entry->op_type );
smb_panic(str);
}
}
DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
- fsp->oplock_type, fsp->fsp_name));
+ fsp->oplock_type, fsp_str_dbg(fsp)));
/* No delay. */
return false;
uint32 create_options)
{
files_struct *fsp;
- char *fname = NULL;
- NTSTATUS status;
-
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
"file %s.\n", smb_fname_str_dbg(smb_fname)));
DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
"vuid = %u, file_pid = %u, private_options = 0x%x "
- "access_mask = 0x%x\n", fsp->fsp_name,
+ "access_mask = 0x%x\n", fsp_str_dbg(fsp),
fsp->fh->fd, (unsigned int)fsp->vuid,
(unsigned int)fsp->file_pid,
(unsigned int)fsp->fh->private_options,
(fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
(fsp->access_mask & FILE_WRITE_DATA) &&
- strequal(fsp->fsp_name, fname)) {
+ strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
+ strequal(fsp->fsp_name->stream_name,
+ smb_fname->stream_name)) {
DEBUG(10,("fcb_or_dos_open: file match\n"));
break;
}
}
/* We need to duplicate this fsp. */
- dup_file_fsp(req, fsp, access_mask, share_access,
- create_options, fsp_to_dup_into);
-
- return NT_STATUS_OK;
+ return dup_file_fsp(req, fsp, access_mask, share_access,
+ create_options, fsp_to_dup_into);
}
/****************************************************************************
Open a file with a share mode - old openX method - map into NTCreate.
****************************************************************************/
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+ int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
uint32 *pcreate_disposition,
DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
"open_func = 0x%x\n",
- fname, (unsigned int)deny_mode, (unsigned int)open_func ));
+ smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
+ (unsigned int)open_func ));
/* Create the NT compatible access_mask. */
switch (GET_OPENX_MODE(deny_mode)) {
case DENY_DOS:
create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
- if (is_executable(fname)) {
+ if (is_executable(smb_fname->base_name)) {
share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
} else {
if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
"share_mode = 0x%x, create_disposition = 0x%x, "
"create_options = 0x%x\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
(unsigned int)access_mask,
(unsigned int)share_mode,
(unsigned int)create_disposition,
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
-
- string_set(&fsp->fsp_name, smb_dname->base_name);
+ status = fsp_set_smb_fname(fsp, smb_dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
mtimespec = smb_dname->st.st_ex_mtime;
bn_len = strlen(base_name);
stream_name = sharepath + sp_len + 1 + bn_len + 1;
+ /* stream_name must always be NULL if there is no stream. */
+ if (stream_name[0] == '\0') {
+ stream_name = NULL;
+ }
+
status = create_synthetic_smb_fname(talloc_tos(), base_name,
stream_name, NULL, &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
- char *newname = NULL;
DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
- fsp->fnum, fsp->fsp_name,
+ fsp->fnum, fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname)));
- status = get_full_smb_filename(talloc_tos(),
- smb_fname, &newname);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- string_set(&fsp->fsp_name, newname);
- TALLOC_FREE(newname);
} else {
/* TODO. JRA. */
/* Now we have the complete path we can work out if this is
fsp->conn->connectpath,
sharepath,
fsp->fnum,
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname)));
}
}
}
DEBUG(10, ("Closing stream # %d, %s\n", i,
- streams[i]->fsp_name));
+ fsp_str_dbg(streams[i])));
close_file(NULL, streams[i], NORMAL_CLOSE);
}
dir_fsp = file_fsp(req, root_dir_fid);
+ if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
+ status = NT_STATUS_INVALID_HANDLE;
+ goto out;
+ }
+
if (dir_fsp == NULL) {
status = NT_STATUS_INVALID_HANDLE;
goto out;
goto out;
}
- if (ISDOT(dir_fsp->fsp_name)) {
+ if (ISDOT(dir_fsp->fsp_name->base_name)) {
/*
* We're at the toplevel dir, the final file name
* must not contain ./, as this is filtered out
goto out;
}
} else {
- size_t dir_name_len = strlen(dir_fsp->fsp_name);
+ size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
/*
* Copy in the base directory name.
status = NT_STATUS_NO_MEMORY;
goto out;
}
- memcpy(parent_fname, dir_fsp->fsp_name,
+ memcpy(parent_fname, dir_fsp->fsp_name->base_name,
dir_name_len+1);
/*
*/
if (is_ntfs_stream_smb_fname(smb_fname)) {
- char *fname = NULL;
enum FAKE_FILE_TYPE fake_file_type;
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- fake_file_type = is_fake_file(fname);
+ fake_file_type = is_fake_file(smb_fname);
if (fake_file_type != FAKE_FILE_TYPE_NONE) {
* close it
*/
status = open_fake_file(req, conn, req->vuid,
- fake_file_type, fname,
+ fake_file_type, smb_fname,
access_mask, &fsp);
- TALLOC_FREE(fname);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
ZERO_STRUCT(smb_fname->st);
goto done;
}
- TALLOC_FREE(fname);
if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, "
"tv_sec = %x, tv_usec = %x\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, (int)fsp->open_time.tv_sec,
(int)fsp->open_time.tv_usec ));
NULL);
if (lck == NULL) {
DEBUG(0,("remove_oplock: failed to lock share entry for "
- "file %s\n", fsp->fsp_name ));
+ "file %s\n", fsp_str_dbg(fsp)));
return False;
}
ret = remove_share_oplock(lck, fsp);
if (!ret) {
DEBUG(0,("remove_oplock: failed to remove share oplock for "
"file %s fnum %d, %s\n",
- fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+ fsp_str_dbg(fsp), fsp->fnum,
+ file_id_string_tos(&fsp->file_id)));
}
release_file_oplock(fsp);
TALLOC_FREE(lck);
NULL);
if (lck == NULL) {
DEBUG(0,("downgrade_oplock: failed to lock share entry for "
- "file %s\n", fsp->fsp_name ));
+ "file %s\n", fsp_str_dbg(fsp)));
return False;
}
ret = downgrade_share_oplock(lck, fsp);
if (!ret) {
DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
"for file %s fnum %d, file_id %s\n",
- fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+ fsp_str_dbg(fsp), fsp->fnum,
+ file_id_string_tos(&fsp->file_id)));
}
downgrade_file_oplock(fsp);
if(fsp->oplock_type == NO_OPLOCK) {
if( DEBUGLVL( 3 ) ) {
- dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
+ dbgtext( "initial_break_processing: file %s ",
+ fsp_str_dbg(fsp));
dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n",
file_id_string_tos(&id), fsp->fh->gen_id );
dbgtext( "Allowing break to succeed regardless.\n" );
/* Remove the timed event handler. */
TALLOC_FREE(fsp->oplock_timeout);
- DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name));
+ DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n",
+ fsp_str_dbg(fsp)));
global_client_failed_oplock_break = True;
remove_oplock(fsp);
reply_to_oplock_break_requests(fsp);
DEBUG(10,("process_oplock_async_level2_break_message: sending break "
"to none message for fid %d, file %s\n", fsp->fnum,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/* Now send a break to none message to our client. */
break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(3, ("Already downgraded oplock on %s: %s\n",
file_id_string_tos(&fsp->file_id),
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/* We just send the same message back. */
messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
(uint8 *)data->data,
NULL);
if (lck == NULL) {
DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
- "share mode entry for file %s.\n", fsp->fsp_name ));
+ "share mode entry for file %s.\n", fsp_str_dbg(fsp)));
return;
}
DEBUG(0,("irix_set_kernel_oplock: Unable to get "
"kernel oplock on file %s, file_id %s "
"gen_id = %ul. Error was %s\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id,
strerror(errno) ));
} else {
"file %s, fd = %d, file_id = %s, "
"gen_id = %ul. Another process had the file "
"open.\n",
- fsp->fsp_name, fsp->fh->fd,
+ fsp_str_dbg(fsp), fsp->fh->fd,
file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id ));
}
DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s "
"gen_id = %ul\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id));
return True;
int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1);
dbgtext("irix_release_kernel_oplock: file %s, file_id = %s"
"gen_id = %ul, has kernel oplock state "
- "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ "of %x.\n", fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, state );
}
"removing kernel oplock on file " );
dbgtext("%s, file_id = %s gen_id = %ul. "
"Error was %s\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id,
strerror(errno) );
}
if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) {
DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, "
"fd = %d, file_id = %s. (%s)\n",
- fsp->fsp_name, fsp->fh->fd,
+ fsp_str_dbg(fsp), fsp->fh->fd,
file_id_string_tos(&fsp->file_id),
strerror(errno)));
return False;
DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, "
"file_id = %s gen_id = %lu\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id));
return True;
int state = fcntl(fsp->fh->fd, F_GETLEASE, 0);
dbgtext("linux_release_kernel_oplock: file %s, file_id = %s "
"gen_id = %lu has kernel oplock state "
- "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ "of %x.\n", fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, state );
}
dbgtext("linux_release_kernel_oplock: Error when "
"removing kernel oplock on file " );
dbgtext("%s, file_id = %s, gen_id = %lu. "
- "Error was %s\n", fsp->fsp_name,
+ "Error was %s\n", fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, strerror(errno) );
}
struct onefs_callback_record *callback_recs;
/**
- * Convert a onefs_callback_record to a string.
+ * Convert a onefs_callback_record to a debug string using the dbg_ctx().
*/
-static char *onefs_callback_record_str_static(const struct onefs_callback_record *r)
+const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r)
{
- static fstring result;
+ char *result;
if (r == NULL) {
- fstrcpy(result, "NULL callback record");
+ result = talloc_strdup(dbg_ctx(), "NULL callback record");
return result;
}
switch (r->state) {
case ONEFS_OPEN_FILE:
- fstr_sprintf(result, "cb record %llu for file %s",
- r->id, r->data.fsp->fsp_name);
- break;
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu for file "
+ "%s", r->id,
+ fsp_str_dbg(r->data.fsp));
case ONEFS_WAITING_FOR_OPLOCK:
- fstr_sprintf(result, "cb record %llu for pending mid %d",
- r->id, (int)r->data.mid);
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu for "
+ "pending mid %d", r->id,
+ (int)r->data.mid);
break;
default:
- fstr_sprintf(result, "cb record %llu unknown state %d",
- r->id, r->state);
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu unknown "
+ "state %d", r->id, r->state);
break;
}
DEBUG(10, ("cb records (%s):\n", fn));
for (rec = callback_recs; rec; rec = rec->next) {
- DEBUGADD(10, ("%s\n", onefs_callback_record_str_static(rec)));
+ DEBUGADD(10, ("%s\n", onefs_cb_record_dbg_str(rec)));
}
}
for (rec = callback_recs; rec; rec = rec->next) {
if (rec->id == id) {
DEBUG(10, ("found %s\n",
- onefs_callback_record_str_static(rec)));
+ onefs_cb_record_dbg_str(rec)));
break;
}
}
if (rec->state != expected_state) {
DEBUG(0, ("Expected cb type %d, got %s", expected_state,
- onefs_callback_record_str_static(rec)));
+ onefs_cb_record_dbg_str(rec)));
SMB_ASSERT(0);
return NULL;
}
}
DEBUG(10, ("oplock_break_to_none_handler called for file %s\n",
- cb->data.fsp->fsp_name));
+ cb->data.fsp_str_dbg(fsp)));
init_share_mode_entry(&sme, cb, FORCE_OPLOCK_BREAK_TO_NONE);
share_mode_entry_to_message(msg, &sme);
}
DEBUG(10, ("oplock_break_to_level_two_handler called for file %s\n",
- cb->data.fsp->fsp_name));
+ cb->data.fsp_str_dbg(fsp)));
init_share_mode_entry(&sme, cb, LEVEL_II_OPLOCK);
share_mode_entry_to_message(msg, &sme);
SMB_ASSERT(fsp->oplock_timeout == NULL);
DEBUG(0,("Level 1 oplock break failed for file %s. Forcefully "
- "revoking oplock\n", fsp->fsp_name));
+ "revoking oplock\n", fsp_str_dbg(fsp)));
global_client_failed_oplock_break = True;
remove_oplock(fsp);
char *msg;
if (asprintf(&msg, "Semlock available on an open that wasn't "
"deferred: %s\n",
- onefs_callback_record_str_static(cb)) != -1) {
+ onefs_cb_record_dbg_str(cb)) != -1) {
smb_panic(msg);
}
smb_panic("Semlock available on an open that wasn't "
char *msg;
if (asprintf(&msg, "Semlock failure on an open that wasn't "
"deferred: %s\n",
- onefs_callback_record_str_static(cb)) != -1) {
+ onefs_cb_record_dbg_str(cb)) != -1) {
smb_panic(msg);
}
smb_panic("Semlock failure on an open that wasn't deferred\n");
enum oplock_type oplock = onefs_samba_oplock_to_oplock(oplock_type);
DEBUG(10, ("onefs_release_kernel_oplock: Releasing %s to type %s\n",
- fsp->fsp_name, onefs_oplock_str(oplock)));
+ fsp_str_dbg(fsp), onefs_oplock_str(oplock)));
if (fsp->fh->fd == -1) {
DEBUG(1, ("no fd\n"));
if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return true;
- } else {
+ }
- /*
- * Ok, innetgr is case sensitive. Try once more with lowercase
- * just in case. Attempt to fix #703. JRA.
- */
+ /*
+ * Ok, innetgr is case sensitive. Try once more with lowercase
+ * just in case. Attempt to fix #703. JRA.
+ */
+ fstrcpy(lowercase_user, user);
+ strlower_m(lowercase_user);
- fstrcpy(lowercase_user, user);
- strlower_m(lowercase_user);
+ if (strcmp(user,lowercase_user) == 0) {
+ /* user name was already lower case! */
+ return false;
+ }
- DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
- lowercase_user,
- sconn->smb1.sessions.my_yp_domain?
- sconn->smb1.sessions.my_yp_domain:"(ANY)",
- ngname));
+ DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
+ lowercase_user,
+ sconn->smb1.sessions.my_yp_domain?
+ sconn->smb1.sessions.my_yp_domain:"(ANY)",
+ ngname));
- if (innetgr(ngname, NULL, lowercase_user,
- sconn->smb1.sessions.my_yp_domain)) {
- DEBUG(5,("user_in_netgroup: Found\n"));
- return true;
- }
+ if (innetgr(ngname, NULL, lowercase_user,
+ sconn->smb1.sessions.my_yp_domain)) {
+ DEBUG(5,("user_in_netgroup: Found\n"));
+ return true;
}
#endif /* HAVE_NETGROUP */
return false;
{
struct connection_struct *conn = smb_req->conn;
struct files_struct *fsp;
+ struct smb_filename *smb_fname = NULL;
NTSTATUS status;
status = file_new(smb_req, conn, &fsp);
fsp->vuid = smb_req->vuid;
fsp->can_lock = false;
fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA;
- string_set(&fsp->fsp_name, name);
+
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(smb_req, fsp);
+ return status;
+ }
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ TALLOC_FREE(smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(smb_req, fsp);
+ return status;
+ }
status = np_open(NULL, name, conn->client_address,
conn->server_info, &fsp->fake_file_handle);
data = req->buf + 3;
DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
- fsp->fsp_name, (int)state->numtowrite));
+ fsp_str_dbg(fsp), (int)state->numtowrite));
subreq = np_write_send(state, smbd_event_context(),
fsp->fake_file_handle, data, state->numtowrite);
status = np_write_recv(subreq, &nwritten);
TALLOC_FREE(subreq);
- if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ if (nwritten < 0) {
+ reply_nterror(req, status);
+ goto send;
+ }
+
+ /* Looks bogus to me now. Needs to be removed ? JRA. */
+ if ((nwritten == 0 && state->numtowrite != 0)) {
+ reply_doserror(req, ERRDOS, ERRnoaccess);
goto send;
}
== (PIPE_START_MESSAGE|PIPE_RAW_MODE));
DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
- (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite));
+ (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite));
data = (uint8_t *)smb_base(req->inbuf) + smb_doff;
DEBUG(0,("reply_pipe_write_and_X: start of message "
"set and not enough data sent.(%u)\n",
(unsigned int)state->numtowrite ));
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
status = np_write_recv(subreq, &nwritten);
TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) {
- reply_unixerror(req, ERRDOS,ERRnoaccess);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto done;
+ }
+
+ /* Looks bogus to me now. Is this error message correct ? JRA. */
+ if (nwritten != state->numtowrite) {
+ reply_doserror(req, ERRDOS,ERRnoaccess);
goto done;
}
ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, store_size, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, store_size, 0);
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+ SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, store_size, 0);
}
SAFE_FREE(pai_buf);
DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n",
(unsigned int)sd_type,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
if (ret == -1 && !no_acl_syscall_error(errno)) {
DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, pai_buf_size);
} else {
- ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, pai_buf_size);
+ ret = SMB_VFS_GETXATTR(fsp->conn,
+ fsp->fsp_name->base_name,
+ SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, pai_buf_size);
}
if (ret == -1) {
}
} while (ret == -1);
- DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
+ DEBUG(10,("load_inherited_info: ret = %lu for file %s\n",
+ (unsigned long)ret, fsp_str_dbg(fsp)));
if (ret == -1) {
/* No attribute or not supported. */
if (paiv) {
DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n",
- (unsigned int)paiv->sd_type,
- fsp->fsp_name));
+ (unsigned int)paiv->sd_type, fsp_str_dbg(fsp)));
}
SAFE_FREE(pai_buf);
got_dir_allow = True;
if ((current_ace->attr == DENY_ACE) && got_dir_allow) {
- DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+ DEBUG(0,("create_canon_ace_lists: "
+ "malformed ACL in "
+ "inheritable ACL! Deny entry "
+ "after Allow entry. Failing "
+ "to set on file %s.\n",
+ fsp_str_dbg(fsp)));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
got_file_allow = True;
if ((current_ace->attr == DENY_ACE) && got_file_allow) {
- DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+ DEBUG(0,("create_canon_ace_lists: malformed "
+ "ACL in file ACL ! Deny entry after "
+ "Allow entry. Failing to set on file "
+ "%s.\n", fsp_str_dbg(fsp)));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
mode_t mode;
if (interitable_mode) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return 0;
- }
- mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname,
- NULL);
+ mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,
+ fsp->fsp_name, NULL);
} else {
mode = S_IRUSR;
}
SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS);
bool needs_mask = False;
mode_t mask_perms = 0;
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- psbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
+ /* Use the psbuf that was passed in. */
+ fsp->fsp_name->st = *psbuf;
#if defined(POSIX_ACL_NEEDS_MASK)
/* HP-UX always wants to have a mask (called "class" there). */
*/
if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
- if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name,
the_acl_type, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
*pacl_set_support = False;
}
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group "
"control on and current user in file "
"%s primary group.\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret = SMB_VFS_SYS_ACL_SET_FILE(conn,
- smb_fname->base_name, the_acl_type,
+ fsp->fsp_name->base_name, the_acl_type,
the_acl);
unbecome_root();
if (sret == 0) {
"file %s (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ?
"directory default" : "file",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
goto fail;
}
}
*pacl_set_support = False;
}
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group "
"control on and current user in file "
"%s primary group.\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl);
DEBUG(2,("set_canon_ace_list: "
"sys_acl_set_file failed for file %s "
"(%s).\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
goto fail;
}
}
if (the_acl != NULL) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
}
- TALLOC_FREE(smb_fname);
return ret;
}
mode_t or_bits;
if (ace_count != 3) {
- DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \
-posix perms.\n", fsp->fsp_name ));
+ DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE "
+ "entries for file %s to convert to posix perms.\n",
+ fsp_str_dbg(fsp)));
return False;
}
}
if (!owner_ace || !group_ace || !other_ace) {
- DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n",
- fsp->fsp_name ));
+ DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get "
+ "standard entries for file %s.\n", fsp_str_dbg(fsp)));
return False;
}
*posix_perms = (((*posix_perms) & and_bits)|or_bits);
- DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n",
- (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms,
- fsp->fsp_name ));
+ DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o "
+ "to perm=0%o for file %s.\n", (int)owner_ace->perms,
+ (int)group_ace->perms, (int)other_ace->perms,
+ (int)*posix_perms, fsp_str_dbg(fsp)));
return True;
}
*ppdesc = NULL;
- DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name ));
+ DEBUG(10,("posix_fget_nt_acl: called for file %s\n",
+ fsp_str_dbg(fsp)));
/* can it happen that fsp_name == NULL ? */
if (fsp->is_directory || fsp->fh->fd == -1) {
- return posix_get_nt_acl(fsp->conn, fsp->fsp_name,
+ return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name,
security_info, ppdesc);
}
pal = fload_inherited_info(fsp);
- return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal,
- posix_acl, NULL, security_info, ppdesc);
+ return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name,
+ &sbuf, pal, posix_acl, NULL,
+ security_info, ppdesc);
}
NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
uint32_t security_info, SEC_DESC **ppdesc)
{
- SMB_STRUCT_STAT sbuf;
SMB_ACL_T posix_acl = NULL;
SMB_ACL_T def_acl = NULL;
struct pai_val *pal;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
*ppdesc = NULL;
DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Get the stat struct for the owner info. */
- if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
- return map_nt_error_from_unix(errno);
+ if(SMB_VFS_STAT(conn, smb_fname) != 0) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
/* Get the ACL from the path. */
posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
/* If it's a directory get the default POSIX ACL. */
- if(S_ISDIR(sbuf.st_ex_mode)) {
+ if(S_ISDIR(smb_fname->st.st_ex_mode)) {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
def_acl = free_empty_sys_acl(conn, def_acl);
}
pal = load_inherited_info(conn, name);
- return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl,
- def_acl, security_info, ppdesc);
+ status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal,
+ posix_acl, def_acl, security_info,
+ ppdesc);
+ out:
+ TALLOC_FREE(smb_fname);
+ return status;
}
/****************************************************************************
return NT_STATUS_NO_MEMORY;
}
- if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) {
+ if (!parent_dirname(mem_ctx, fsp->fsp_name->base_name, &parent_name,
+ NULL)) {
return NT_STATUS_NO_MEMORY;
}
"ignoring non container "
"inherit flags %u on ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)se->flags,
sid_string_dbg(&se->trustee),
parent_name));
"ignoring non object "
"inherit flags %u on ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)se->flags,
sid_string_dbg(&se->trustee),
parent_name));
DEBUG(10,("append_parent_acl: path %s "
"ignoring ACE with protected sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
sid_string_dbg(&se->trustee),
parent_name));
continue;
DEBUG(10,("append_parent_acl: path %s "
"inheriting ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
sid_string_dbg(&se->trustee),
parent_name));
}
bool set_acl_as_root = false;
bool acl_set_support = false;
bool ret = false;
- struct smb_filename *smb_fname = NULL;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
DEBUG(10,("set_nt_acl: called for file %s\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
if (!CAN_WRITE(conn)) {
DEBUG(10,("set acl rejected on read-only share\n"));
- status = NT_STATUS_MEDIA_WRITE_PROTECTED;
- goto out;
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
/*
*/
if(fsp->is_directory || fsp->fh->fd == -1) {
- if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+ return map_nt_error_from_unix(errno);
}
} else {
- if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ return map_nt_error_from_unix(errno);
}
}
/* Save the original element we check against. */
- orig_mode = smb_fname->st.st_ex_mode;
+ orig_mode = fsp->fsp_name->st.st_ex_mode;
/*
* Unpack the user/group/world id's.
status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ return status;
}
/*
* Noticed by Simo.
*/
- if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) ||
- (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) {
+ if (((user != (uid_t)-1) && (fsp->fsp_name->st.st_ex_uid != user)) ||
+ (( grp != (gid_t)-1) && (fsp->fsp_name->st.st_ex_gid != grp))) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
- smb_fname_str_dbg(smb_fname), (unsigned int)user,
- (unsigned int)grp ));
+ fsp_str_dbg(fsp), (unsigned int)user,
+ (unsigned int)grp));
- if(try_chown(fsp->conn, smb_fname, user, grp) == -1) {
+ if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) {
DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error "
- "= %s.\n", smb_fname_str_dbg(smb_fname),
+ "= %s.\n", fsp_str_dbg(fsp),
(unsigned int)user, (unsigned int)grp,
strerror(errno)));
if (errno == EPERM) {
- status = NT_STATUS_INVALID_OWNER;
- goto out;
+ return NT_STATUS_INVALID_OWNER;
}
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
/*
*/
if(fsp->is_directory) {
- if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+ return map_nt_error_from_unix(errno);
}
} else {
int sret;
if(fsp->fh->fd == -1)
- sret = SMB_VFS_STAT(fsp->conn, smb_fname);
+ sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
else
- sret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
if(sret != 0)
return map_nt_error_from_unix(errno);
}
/* Save the original element we check against. */
- orig_mode = smb_fname->st.st_ex_mode;
+ orig_mode = fsp->fsp_name->st.st_ex_mode;
/* If we successfully chowned, we know we must
* be able to set the acl, so do it as root.
set_acl_as_root = true;
}
- create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid);
+ create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid);
- acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid,
+ acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid,
&file_grp_sid, &file_ace_list,
&dir_ace_list, security_info_sent, psd);
/* Ignore W2K traverse DACL set. */
if (!file_ace_list && !dir_ace_list) {
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
if (!acl_perms) {
DEBUG(3,("set_nt_acl: cannot set permissions\n"));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_ACCESS_DENIED;
- goto out;
+ return NT_STATUS_ACCESS_DENIED;
}
/*
if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
/*
become_root();
}
ret = set_canon_ace_list(fsp, file_ace_list, false,
- &smb_fname->st, &acl_set_support);
+ &fsp->fsp_name->st, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
if (acl_set_support && ret == false) {
DEBUG(3,("set_nt_acl: failed to set file acl on file "
- "%s (%s).\n", smb_fname_str_dbg(smb_fname),
+ "%s (%s).\n", fsp_str_dbg(fsp),
strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
become_root();
}
ret = set_canon_ace_list(fsp, dir_ace_list, true,
- &smb_fname->st,
+ &fsp->fsp_name->st,
&acl_set_support);
if (set_acl_as_root) {
unbecome_root();
if (ret == false) {
DEBUG(3,("set_nt_acl: failed to set default "
"acl on directory %s (%s).\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
} else {
int sret = -1;
become_root();
}
sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn,
- smb_fname->base_name);
+ fsp->fsp_name->base_name);
if (set_acl_as_root) {
unbecome_root();
}
if (sret == -1) {
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group "
"control on and current user "
"in file %s primary group. "
"Override delete_def_acl\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret =
SMB_VFS_SYS_ACL_DELETE_DEF_FILE(
conn,
- smb_fname->base_name);
+ fsp->fsp_name->base_name);
unbecome_root();
}
DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
}
free_canon_ace_list(dir_ace_list);
DEBUG(3,("set_nt_acl: failed to convert file acl to "
"posix permissions for file %s.\n",
- smb_fname_str_dbg(smb_fname)));
- status = NT_STATUS_ACCESS_DENIED;
- goto out;
+ fsp_str_dbg(fsp)));
+ return NT_STATUS_ACCESS_DENIED;
}
if (orig_mode != posix_perms) {
int sret = -1;
DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
- smb_fname_str_dbg(smb_fname),
- (unsigned int)posix_perms));
+ fsp_str_dbg(fsp), (unsigned int)posix_perms));
if (set_acl_as_root) {
become_root();
}
- sret = SMB_VFS_CHMOD(conn, smb_fname->base_name,
+ sret = SMB_VFS_CHMOD(conn, fsp->fsp_name->base_name,
posix_perms);
if (set_acl_as_root) {
unbecome_root();
}
if(sret == -1) {
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group "
"control on and current user "
"in file %s primary group. "
"Override chmod\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
- sret =
- SMB_VFS_CHMOD(conn,
- smb_fname->base_name,
- posix_perms);
+ sret = SMB_VFS_CHMOD(conn,
+ fsp->fsp_name->base_name,
+ posix_perms);
unbecome_root();
}
if (sret == -1) {
DEBUG(3,("set_nt_acl: chmod %s, 0%o "
"failed. Error = %s.\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
(unsigned int)posix_perms,
strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
}
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_OK;
- out:
- TALLOC_FREE(smb_fname);
- return status;
+ return NT_STATUS_OK;
}
/****************************************************************************
connection_struct *conn;
files_struct finfo;
struct fd_handle fh;
+ NTSTATUS status;
conn = TALLOC_ZERO_P(ctx, connection_struct);
if (conn == NULL) {
finfo.conn = conn;
finfo.fh = &fh;
finfo.fh->fd = -1;
- finfo.fsp_name = CONST_DISCARD(char *,fname);
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+ &finfo.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ conn_free_internal( conn );
+ return NULL;
+ }
if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
+ TALLOC_FREE(finfo.fsp_name);
conn_free_internal( conn );
return NULL;
}
ret_sd = dup_sec_desc( ctx, psd );
+ TALLOC_FREE(finfo.fsp_name);
conn_free_internal( conn );
return ret_sd;
TALLOC_CTX *frame = talloc_stackframe();
char remaddr[INET6_ADDRSTRLEN];
- smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
- if (!smbd_server_conn) {
- exit_server("failed to create smbd_server_connection");
- }
-
if (lp_maxprotocol() == PROTOCOL_SMB2 &&
lp_security() != SEC_SHARE) {
smbd_server_conn->allow_smb2 = true;
END_PROFILE(SMBtconX);
+ req->tid = conn->cnum;
chain_reply(req);
return;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
smb_fname_str_dbg(smb_fname),
strerror(errno)));
- reply_unixerror(req, ERRDOS,ERRbadfile);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ft.mtime = convert_time_t_to_timespec(mtime);
status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, status);
goto out;
}
if (file_set_dosmode(conn, smb_fname, mode, NULL,
false) != 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
}
START_PROFILE(SMBdskattr);
if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBdskattr);
return;
}
char *path = NULL;
const char *mask = NULL;
char *directory = NULL;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
SMB_OFF_T size;
uint32 mode;
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
if (lp_posix_pathnames()) {
reply_unknown_new(req, req->cmd);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
/* If we were called as SMBffirst then we must expect close. */
&nt_status, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
p++;
/* dirtype &= ~aDIR; */
if (status_len == 0) {
- struct smb_filename *smb_fname = NULL;
-
nt_status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
path,
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
nt_status = unix_convert(ctx, conn, path, &smb_fname,
UCF_ALLOW_WCARD_LCOMP);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
- nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
- TALLOC_FREE(smb_fname);
- if (!NT_STATUS_IS_OK(nt_status)) {
- reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
- }
+ directory = smb_fname->base_name;
nt_status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
p = strrchr_m(directory,'/');
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
memset((char *)status,'\0',21);
&conn->dirptr);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
dptr_num = dptr_dnum(conn->dirptr);
} else {
if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
0,aVOLID,0,!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
dptr_fill(buf+12,dptr_num);
if (dptr_zero(buf+12) && (status_len==0)) {
data_blob_const(buf, sizeof(buf)))
== -1) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
} else {
unsigned int i;
convert_timespec_to_time_t(date),
!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
if (!dptr_fill(buf+12,dptr_num)) {
break;
data_blob_const(buf, sizeof(buf)))
== -1) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
numentries++;
}
if ((numentries == 0) && !mask_contains_wcard) {
reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
SSVAL(req->outbuf,smb_vwv0,numentries);
dirtype,
numentries,
maxentries ));
-
+ out:
+ TALLOC_FREE(smb_fname);
END_PROFILE(SMBsearch);
return;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
goto out;
}
- if (!map_open_params_to_ntcreate(
- smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN,
- &access_mask, &share_mode, &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
+ OPENX_FILE_EXISTS_OPEN, &access_mask,
+ &share_mode, &create_disposition,
+ &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
goto out;
}
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (fattr & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
+ DEBUG(3,("attempt to open a directory %s\n",
+ fsp_str_dbg(fsp)));
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
goto out;
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
goto out;
}
- if (!map_open_params_to_ntcreate(
- smb_fname->base_name, deny_mode, smb_ofun, &access_mask,
- &share_mode, &create_disposition, &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
+ &access_mask, &share_mode,
+ &create_disposition,
+ &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
goto out;
}
DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
END_PROFILE(SMBulogoffX);
+ req->vuid = UID_FIELD_INVALID;
chain_reply(req);
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
tmpfd = mkstemp(smb_fname->base_name);
if (tmpfd == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
/* the returned filename is relative to the directory */
- s = strrchr_m(fsp->fsp_name, '/');
+ s = strrchr_m(fsp->fsp_name->base_name, '/');
if (!s) {
- s = fsp->fsp_name;
+ s = fsp->fsp_name->base_name;
} else {
s++;
}
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
- DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+ DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
+ DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
out:
TALLOC_FREE(smb_fname);
static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
uint16 dirtype, SMB_STRUCT_STAT *pst)
{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
uint32 fmode;
if (!CAN_WRITE(conn)) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- pst, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- fmode = dos_mode(conn, smb_fname);
- TALLOC_FREE(smb_fname);
+ fmode = dos_mode(conn, fsp->fsp_name);
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
return NT_STATUS_NO_SUCH_FILE;
}
while ((dname = ReadDirName(dir_hnd, &offset,
&smb_fname->st))) {
+ TALLOC_CTX *frame = talloc_stackframe();
+
if (!is_visible_file(conn, fname_dir, dname,
&smb_fname->st, true)) {
+ TALLOC_FREE(frame);
continue;
}
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(frame);
continue;
}
if(!mask_match(dname, fname_mask,
conn->case_sensitive)) {
+ TALLOC_FREE(frame);
continue;
}
if (!smb_fname->base_name) {
TALLOC_FREE(dir_hnd);
status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE(frame);
goto out;
}
status = check_name(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(frame);
goto out;
}
status = do_unlink(conn, req, smb_fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
continue;
}
count++;
DEBUG(3,("unlink_internals: successful unlink [%s]\n",
smb_fname->base_name));
+
+ TALLOC_FREE(frame);
}
TALLOC_FREE(dir_hnd);
}
if (nread < headersize) {
DEBUG(0,("sendfile_short_send: sendfile failed to send "
"header for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
exit_server_cleanly("sendfile_short_send failed");
}
}
DEBUG(0,("sendfile_short_send: filling truncated file %s "
- "with zeros !\n", fsp->fsp_name));
+ "with zeros !\n", fsp_str_dbg(fsp)));
while (nread < smb_maxcnt) {
/*
DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
if (fake_sendfile(fsp, startpos, nread) == -1) {
- DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readbraw: "
+ "fake_sendfile failed for "
+ "file %s (%s).\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readbraw fake_sendfile failed");
}
return;
}
- DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readbraw: sendfile failed for "
+ "file %s (%s). Terminating\n",
+ fsp_str_dbg(fsp), strerror(errno)));
exit_server_cleanly("send_file_readbraw sendfile failed");
} else if (sendfile_read == 0) {
/*
*/
DEBUG(3, ("send_file_readbraw: sendfile sent zero "
"bytes falling back to the normal read: "
- "%s\n", fsp->fsp_name));
+ "%s\n", fsp_str_dbg(fsp)));
goto normal_readbraw;
}
nread = read_file(fsp,data,startpos,numtoread);
if (nread < 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBlockread);
return;
}
nread = read_file(fsp,data,startpos,numtoread);
if (nread < 0) {
- reply_unixerror(req, ERRDOS,ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto strict_unlock;
}
SMB_STRUCT_STAT sbuf;
ssize_t nread = -1;
struct lock_struct lock;
+ int saved_errno = 0;
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
nread = fake_sendfile(fsp, startpos,
smb_maxcnt);
if (nread == -1) {
- DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: "
+ "fake_sendfile failed for "
+ "file %s (%s).\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
goto strict_unlock;
}
- DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: sendfile failed for file "
+ "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX sendfile failed");
} else if (nread == 0) {
/*
*/
DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
"falling back to the normal read: %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
goto normal_read;
}
/* Send out the header. */
if (write_data(smbd_server_fd(), (char *)headerbuf,
sizeof(headerbuf)) != sizeof(headerbuf)) {
- DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: write_data failed for file "
+ "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX sendfile failed");
}
nread = fake_sendfile(fsp, startpos, smb_maxcnt);
if (nread == -1) {
- DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: fake_sendfile failed for "
+ "file %s (%s).\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
goto strict_unlock;
reply_outbuf(req, 12, smb_maxcnt);
nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+ saved_errno = errno;
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
if (nread < 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
return;
}
(int)nwritten, (int)write_through));
if (nwritten < (ssize_t)numtowrite) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_doserror(req, ERRHRD, ERRdiskfull);
error_to_writebrawerr(req);
goto strict_unlock;
}
nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
if (nwritten == -1) {
TALLOC_FREE(buf);
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_nterror(req, map_nt_error_from_unix(errno));
error_to_writebrawerr(req);
goto strict_unlock;
}
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
error_to_writebrawerr(req);
goto strict_unlock;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp;
struct lock_struct lock;
+ int saved_errno = 0;
START_PROFILE(SMBwriteunlock);
nwritten = 0;
} else {
nwritten = write_file(req,fsp,data,startpos,numtowrite);
+ saved_errno = errno;
}
status = sync_file(conn, fsp, False /* write through */);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
- if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten < numtowrite) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
files_struct *fsp;
struct lock_struct lock;
NTSTATUS status;
+ int saved_errno = 0;
START_PROFILE(SMBwrite);
status = sync_file(conn, fsp, False);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten == 0) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten == 0) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
SMB_STRUCT_STAT sbuf;
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- reply_unixerror(req, ERRDOS,
- ERRnoaccess);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
END_PROFILE(SMBlseek);
return;
}
}
if(res == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBlseek);
return;
}
NTSTATUS status = sync_file(conn, fsp, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
END_PROFILE(SMBflush);
return;
*/
if (numtowrite) {
- DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
- fsp->fsp_name ));
+ DEBUG(3,("reply_writeclose: zero length write doesn't close "
+ "file %s\n", fsp_str_dbg(fsp)));
close_status = close_file(req, fsp, NORMAL_CLOSE);
}
data = (const char *)req->buf + 3;
if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBsplwr);
return;
}
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
{
files_struct *fsp;
bool did_rename = False;
- char *fname_dst = NULL;
NTSTATUS status;
for(fsp = file_find_di_first(lck->id); fsp;
}
DEBUG(10, ("rename_open_files: renaming file fnum %d "
"(file_id %s) from %s -> %s\n", fsp->fnum,
- file_id_string_tos(&fsp->file_id), fsp->fsp_name,
+ file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
- &fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- return;
+ status = fsp_set_smb_fname(fsp, smb_fname_dst);
+ if (NT_STATUS_IS_OK(status)) {
+ did_rename = True;
}
- string_set(&fsp->fsp_name, fname_dst);
- did_rename = True;
- TALLOC_FREE(fname_dst);
}
if (!did_rename) {
{
char *parent_dir_src = NULL;
char *parent_dir_dst = NULL;
- char *fname_src = NULL;
- char *fname_dst = NULL;
- NTSTATUS status;
uint32 mask;
mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
goto out;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname_src,
- &fname_src);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
- status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
- &fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
if (strcmp(parent_dir_src, parent_dir_dst) == 0) {
- notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src);
- notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst);
+ notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask,
+ smb_fname_src->base_name);
+ notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask,
+ smb_fname_dst->base_name);
}
else {
- notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src);
- notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst);
+ notify_fname(conn, NOTIFY_ACTION_REMOVED, mask,
+ smb_fname_src->base_name);
+ notify_fname(conn, NOTIFY_ACTION_ADDED, mask,
+ smb_fname_dst->base_name);
}
/* this is a strange one. w2k3 gives an additional event for
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES
|FILE_NOTIFY_CHANGE_CREATION,
- fname_dst);
+ smb_fname_dst->base_name);
}
out:
TALLOC_FREE(parent_dir_src);
TALLOC_FREE(parent_dir_dst);
- TALLOC_FREE(fname_src);
- TALLOC_FREE(fname_dst);
}
/****************************************************************************
}
/* Make a copy of the src and dst smb_fname structs */
- status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
+ status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- /*
- * This will be replaced with copy_smb_filename() when fsp->fsp_name
- * is converted to store an smb_filename struct.
- */
- status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL,
- &smb_fname_src);
+ status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
if (!target_is_directory && count) {
new_create_disposition = FILE_OPEN;
} else {
- if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name,
- 0, ofun, NULL, NULL,
+ if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
+ NULL, NULL,
&new_create_disposition,
NULL)) {
status = NT_STATUS_INVALID_PARAMETER;
const char *p;
int count=0;
int error = ERRnoaccess;
- int err = 0;
int tid2;
int ofun;
int flags;
}
if (count == 0) {
- if(err) {
- /* Error on close... */
- errno = err;
- reply_unixerror(req, ERRHRD, ERRgeneral);
- goto out;
- }
-
reply_doserror(req, ERRDOS, error);
goto out;
}
return offset;
}
+NTSTATUS smbd_do_locking(struct smb_request *req,
+ files_struct *fsp,
+ uint8_t type,
+ int32_t timeout,
+ uint16_t num_ulocks,
+ struct smbd_lock_element *ulocks,
+ uint16_t num_locks,
+ struct smbd_lock_element *locks,
+ bool *async)
+{
+ connection_struct *conn = req->conn;
+ int i;
+ NTSTATUS status = NT_STATUS_OK;
+
+ *async = false;
+
+ /* Data now points at the beginning of the list
+ of smb_unlkrng structs */
+ for(i = 0; i < (int)num_ulocks; i++) {
+ struct smbd_lock_element *e = &ulocks[i];
+
+ DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for "
+ "pid %u, file %s\n",
+ (double)e->offset,
+ (double)e->count,
+ (unsigned int)e->smbpid,
+ fsp_str_dbg(fsp)));
+
+ if (e->brltype != UNLOCK_LOCK) {
+ /* this can only happen with SMB2 */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = do_unlock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK);
+
+ DEBUG(10, ("smbd_do_locking: unlock returned %s\n",
+ nt_errstr(status)));
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ /* Setup the timeout in seconds. */
+
+ if (!lp_blocking_locks(SNUM(conn))) {
+ timeout = 0;
+ }
+
+ /* Data now points at the beginning of the list
+ of smb_lkrng structs */
+
+ for(i = 0; i < (int)num_locks; i++) {
+ struct smbd_lock_element *e = &locks[i];
+
+ DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for pid "
+ "%u, file %s timeout = %d\n",
+ (double)e->offset,
+ (double)e->count,
+ (unsigned int)e->smbpid,
+ fsp_str_dbg(fsp),
+ (int)timeout));
+
+ if (type & LOCKING_ANDX_CANCEL_LOCK) {
+ struct blocking_lock_record *blr = NULL;
+
+ if (lp_blocking_locks(SNUM(conn))) {
+
+ /* Schedule a message to ourselves to
+ remove the blocking lock record and
+ return the right error. */
+
+ blr = blocking_lock_cancel(fsp,
+ e->smbpid,
+ e->offset,
+ e->count,
+ WINDOWS_LOCK,
+ type,
+ NT_STATUS_FILE_LOCK_CONFLICT);
+ if (blr == NULL) {
+ return NT_STATUS_DOS(
+ ERRDOS,
+ ERRcancelviolation);
+ }
+ }
+ /* Remove a matching pending lock. */
+ status = do_lock_cancel(fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK,
+ blr);
+ } else {
+ bool blocking_lock = timeout ? true : false;
+ bool defer_lock = false;
+ struct byte_range_lock *br_lck;
+ uint32_t block_smbpid;
+
+ br_lck = do_lock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ e->brltype,
+ WINDOWS_LOCK,
+ blocking_lock,
+ &status,
+ &block_smbpid,
+ NULL);
+
+ if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
+ /* Windows internal resolution for blocking locks seems
+ to be about 200ms... Don't wait for less than that. JRA. */
+ if (timeout != -1 && timeout < lp_lock_spin_time()) {
+ timeout = lp_lock_spin_time();
+ }
+ defer_lock = true;
+ }
+
+ /* This heuristic seems to match W2K3 very well. If a
+ lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
+ it pretends we asked for a timeout of between 150 - 300 milliseconds as
+ far as I can tell. Replacement for do_lock_spin(). JRA. */
+
+ if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
+ NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
+ defer_lock = true;
+ timeout = lp_lock_spin_time();
+ }
+
+ if (br_lck && defer_lock) {
+ /*
+ * A blocking lock was requested. Package up
+ * this smb into a queued request and push it
+ * onto the blocking lock queue.
+ */
+ if(push_blocking_lock_request(br_lck,
+ req,
+ fsp,
+ timeout,
+ i,
+ e->smbpid,
+ e->brltype,
+ WINDOWS_LOCK,
+ e->offset,
+ e->count,
+ block_smbpid)) {
+ TALLOC_FREE(br_lck);
+ *async = true;
+ return NT_STATUS_OK;
+ }
+ }
+
+ TALLOC_FREE(br_lck);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ break;
+ }
+ }
+
+ /* If any of the above locks failed, then we must unlock
+ all of the previous locks (X/Open spec). */
+
+ if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
+
+ if (type & LOCKING_ANDX_CANCEL_LOCK) {
+ i = -1; /* we want to skip the for loop */
+ }
+
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+ for(i--; i >= 0; i--) {
+ struct smbd_lock_element *e = &locks[i];
+
+ do_unlock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK);
+ }
+ return status;
+ }
+
+ DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+ fsp->fnum, (unsigned int)type, num_locks, num_ulocks));
+
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Reply to a lockingX request.
****************************************************************************/
unsigned char oplocklevel;
uint16 num_ulocks;
uint16 num_locks;
- uint64_t count = 0, offset = 0;
- uint32 lock_pid;
int32 lock_timeout;
int i;
const uint8_t *data;
bool large_file_format;
bool err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ struct smbd_lock_element *ulocks;
+ struct smbd_lock_element *locks;
+ bool async = false;
START_PROFILE(SMBlockingX);
DEBUG(5,("reply_lockingX: Error : oplock break from "
"client for fnum = %d (oplock=%d) and no "
"oplock granted on this file (%s).\n",
- fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+ fsp->fnum, fsp->oplock_type,
+ fsp_str_dbg(fsp)));
/* if this is a pure oplock break request then don't
* send a reply */
if (!result) {
DEBUG(0, ("reply_lockingX: error in removing "
- "oplock on file %s\n", fsp->fsp_name));
+ "oplock on file %s\n", fsp_str_dbg(fsp)));
/* Hmmm. Is this panic justified? */
smb_panic("internal tdb error");
}
return;
}
+ ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks);
+ if (ulocks == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
+
+ locks = talloc_array(req, struct smbd_lock_element, num_locks);
+ if (locks == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
+
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ ulocks[i].smbpid = get_lock_pid(data, i, large_file_format);
+ ulocks[i].count = get_lock_count(data, i, large_file_format);
+ ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+ ulocks[i].brltype = UNLOCK_LOCK;
/*
* There is no error code marked "stupid client bug".... :-).
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
- DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
- "pid %u, file %s\n", (double)offset, (double)count,
- (unsigned int)lock_pid, fsp->fsp_name ));
-
- status = do_unlock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK);
-
- DEBUG(10, ("reply_lockingX: unlock returned %s\n",
- nt_errstr(status)));
-
- if (NT_STATUS_V(status)) {
- END_PROFILE(SMBlockingX);
- reply_nterror(req, status);
- return;
- }
- }
-
- /* Setup the timeout in seconds. */
-
- if (!lp_blocking_locks(SNUM(conn))) {
- lock_timeout = 0;
}
/* Now do any requested locks */
of smb_lkrng structs */
for(i = 0; i < (int)num_locks; i++) {
- enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
- READ_LOCK:WRITE_LOCK);
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ locks[i].smbpid = get_lock_pid(data, i, large_file_format);
+ locks[i].count = get_lock_count(data, i, large_file_format);
+ locks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+
+ if (locktype & LOCKING_ANDX_SHARED_LOCK) {
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ locks[i].brltype = PENDING_READ_LOCK;
+ } else {
+ locks[i].brltype = READ_LOCK;
+ }
+ } else {
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ locks[i].brltype = PENDING_WRITE_LOCK;
+ } else {
+ locks[i].brltype = WRITE_LOCK;
+ }
+ }
/*
* There is no error code marked "stupid client bug".... :-).
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
- DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
- "%u, file %s timeout = %d\n", (double)offset,
- (double)count, (unsigned int)lock_pid,
- fsp->fsp_name, (int)lock_timeout ));
-
- if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
- struct blocking_lock_record *blr = NULL;
-
- if (lp_blocking_locks(SNUM(conn))) {
-
- /* Schedule a message to ourselves to
- remove the blocking lock record and
- return the right error. */
-
- blr = blocking_lock_cancel(fsp,
- lock_pid,
- offset,
- count,
- WINDOWS_LOCK,
- locktype,
- NT_STATUS_FILE_LOCK_CONFLICT);
- if (blr == NULL) {
- END_PROFILE(SMBlockingX);
- reply_nterror(
- req,
- NT_STATUS_DOS(
- ERRDOS,
- ERRcancelviolation));
- return;
- }
- }
- /* Remove a matching pending lock. */
- status = do_lock_cancel(fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK,
- blr);
- } else {
- bool blocking_lock = lock_timeout ? True : False;
- bool defer_lock = False;
- struct byte_range_lock *br_lck;
- uint32 block_smbpid;
-
- br_lck = do_lock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- WINDOWS_LOCK,
- blocking_lock,
- &status,
- &block_smbpid,
- NULL);
-
- if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
- /* Windows internal resolution for blocking locks seems
- to be about 200ms... Don't wait for less than that. JRA. */
- if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
- lock_timeout = lp_lock_spin_time();
- }
- defer_lock = True;
- }
-
- /* This heuristic seems to match W2K3 very well. If a
- lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
- it pretends we asked for a timeout of between 150 - 300 milliseconds as
- far as I can tell. Replacement for do_lock_spin(). JRA. */
-
- if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
- NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
- defer_lock = True;
- lock_timeout = lp_lock_spin_time();
- }
-
- if (br_lck && defer_lock) {
- /*
- * A blocking lock was requested. Package up
- * this smb into a queued request and push it
- * onto the blocking lock queue.
- */
- if(push_blocking_lock_request(br_lck,
- req,
- fsp,
- lock_timeout,
- i,
- lock_pid,
- lock_type,
- WINDOWS_LOCK,
- offset,
- count,
- block_smbpid)) {
- TALLOC_FREE(br_lck);
- END_PROFILE(SMBlockingX);
- return;
- }
- }
-
- TALLOC_FREE(br_lck);
- }
-
- if (NT_STATUS_V(status)) {
- break;
- }
}
- /* If any of the above locks failed, then we must unlock
- all of the previous locks (X/Open spec). */
- if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
-
- if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
- i = -1; /* we want to skip the for loop */
- }
-
- /*
- * Ensure we don't do a remove on the lock that just failed,
- * as under POSIX rules, if we have a lock already there, we
- * will delete it (and we shouldn't) .....
- */
- for(i--; i >= 0; i--) {
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format,
- &err);
-
- /*
- * There is no error code marked "stupid client
- * bug".... :-).
- */
- if(err) {
- END_PROFILE(SMBlockingX);
- reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
- }
-
- do_unlock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK);
- }
+ status = smbd_do_locking(req, fsp,
+ locktype, lock_timeout,
+ num_ulocks, ulocks,
+ num_locks, locks,
+ &async);
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBlockingX);
reply_nterror(req, status);
return;
}
+ if (async) {
+ END_PROFILE(SMBlockingX);
+ return;
+ }
reply_outbuf(req, 2, 0);
void reply_setattrE(struct smb_request *req)
{
connection_struct *conn = req->conn;
- struct smb_filename *smb_fname = NULL;
struct smb_file_time ft;
files_struct *fsp;
NTSTATUS status;
goto out;
}
- /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- goto out;
- }
-
/*
* Convert the DOS times into unix times.
*/
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) {
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
goto out;
int ret = -1;
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(conn, smb_fname);
+ ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(conn, smb_fname);
+ ret = SMB_VFS_STAT(conn, fsp->fsp_name);
}
if (ret == -1) {
status = map_nt_error_from_unix(errno);
}
}
- status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+ status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
reply_doserror(req, ERRDOS, ERRnoaccess);
goto out;
int mode;
files_struct *fsp;
struct timespec create_ts;
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
START_PROFILE(SMBgetattrE);
/* Do an fstat on this file */
if(fsp_stat(fsp, &sbuf)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBgetattrE);
return;
}
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- &sbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBgetattrE);
- return;
- }
+ fsp->fsp_name->st = sbuf;
- mode = dos_mode(conn, smb_fname);
- TALLOC_FREE(smb_fname);
+ mode = dos_mode(conn, fsp->fsp_name);
/*
* Convert the times into dos times. Set create
{
DEBUG(10,("smb_conf_updated: Got message saying smb.conf was "
"updated. Reloading.\n"));
+ change_to_root_user();
reload_services(False);
}
if (am_parent) {
pidfile_unlink();
}
+ gencache_stabilize();
}
/* if we had any open SMB connections when we exited then we
if (do_chdir &&
vfs_ChDir(conn,conn->connectpath) != 0 &&
vfs_ChDir(conn,conn->origpath) != 0) {
- DEBUG(0,("chdir (%s) failed\n",
- conn->connectpath));
+ DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n",
+ conn->connectpath, strerror(errno)));
return(False);
}
SSVAL(req->outbuf,smb_uid,sess_vuid);
SSVAL(req->inbuf,smb_uid,sess_vuid);
+ req->vuid = sess_vuid;
if (!sconn->smb1.sessions.done_sesssetup) {
sconn->smb1.sessions.max_send =
return NT_STATUS_NO_MEMORY;
}
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
if (fsp == NULL) {
return NT_STATUS_FILE_CLOSED;
status = close_file(smbreq, fsp, NORMAL_CLOSE);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
return status;
}
files_struct *result;
int info;
SMB_STRUCT_STAT sbuf;
- struct smb_filename *smb_fname = NULL;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
}
info = FILE_WAS_CREATED;
} else {
+ struct smb_filename *smb_fname = NULL;
+
/* these are ignored for SMB2 */
in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
smbreq->conn,
smbreq->flags2 & FLAGS2_DFS_PATHNAMES,
in_name,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
+ TALLOC_FREE(smb_fname);
goto out;
}
&info);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
+ TALLOC_FREE(smb_fname);
goto out;
}
sbuf = smb_fname->st;
- }
-
- if (!smb_fname) {
- status = create_synthetic_smb_fname_split(talloc_tos(),
- result->fsp_name,
- &sbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- goto out;
- }
+ TALLOC_FREE(smb_fname);
}
smb2req->compat_chain_fsp = smbreq->chain_fsp;
state->out_allocation_size = sbuf.st_ex_blksize * sbuf.st_ex_blocks;
state->out_end_of_file = sbuf.st_ex_size;
state->out_file_attributes = dos_mode(result->conn,
- smb_fname);
+ result->fsp_name);
if (state->out_file_attributes == 0) {
state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
}
tevent_req_done(req);
out:
- TALLOC_FREE(smb_fname);
return tevent_req_post(req, ev);
}
status = sync_file(smbreq->conn, fsp, true);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_flush: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (IS_IPC(conn)) {
+ tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_info_type) {
+ case 0x01:/* SMB2_GETINFO_FILE */
+ {
+ uint16_t file_info_level;
+ char *data = NULL;
+ unsigned int data_size = 0;
+ bool delete_pending = false;
+ struct timespec write_time_ts;
+ struct file_id fileid;
+ struct ea_list *ea_list = NULL;
+ int lock_data_count = 0;
+ char *lock_data = NULL;
+ bool ms_dfs_link = false;
+ NTSTATUS status;
+
+ ZERO_STRUCT(write_time_ts);
+
+ switch (in_file_info_class) {
+ case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
+ file_info_level = 0xFF00 | in_file_info_class;
+ break;
+
+ case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
+ file_info_level = 0xFF00 | in_file_info_class;
+ break;
+
+ default:
+ /* the levels directly map to the passthru levels */
+ file_info_level = in_file_info_class + 1000;
+ break;
+ }
+
+ if (fsp->fake_file_handle) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ /* We know this name is ok, it's already passed the checks. */
+
+ } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
+ /*
+ * This is actually a QFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+
+ if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_getinfo_send: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n", fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ } else if (SMB_VFS_STAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_getinfo_send: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn,
+ &fsp->fsp_name->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ DEBUG(3, ("smbd_smb2_getinfo_send: "
+ "fstat of fnum %d failed (%s)\n",
+ fsp->fnum, strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ fileid = vfs_file_id_from_sbuf(conn,
+ &fsp->fsp_name->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ }
+
+ status = smbd_do_qfilepathinfo(conn, state,
+ file_info_level,
+ fsp,
+ fsp->fsp_name,
+ delete_pending,
+ write_time_ts,
+ ms_dfs_link,
+ ea_list,
+ lock_data_count,
+ lock_data,
+ STR_UNICODE,
+ in_output_buffer_length,
+ &data,
+ &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(data);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ if (data_size > 0) {
+ state->out_output_buffer = data_blob_talloc(state,
+ data,
+ data_size);
+ SAFE_FREE(data);
+ if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+ }
+ SAFE_FREE(data);
+ break;
+ }
+
+ case 0x02:/* SMB2_GETINFO_FS */
+ {
+ uint16_t file_info_level;
+ char *data = NULL;
+ int data_size = 0;
+ NTSTATUS status;
+
+ /* the levels directly map to the passthru levels */
+ file_info_level = in_file_info_class + 1000;
+
+ status = smbd_do_qfsinfo(conn, state,
+ file_info_level,
+ STR_UNICODE,
+ in_output_buffer_length,
+ &data,
+ &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(data);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ if (data_size > 0) {
+ state->out_output_buffer = data_blob_talloc(state,
+ data,
+ data_size);
+ SAFE_FREE(data);
+ if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+ }
+ SAFE_FREE(data);
+ break;
+ }
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
+ uint32_t in_smbpid,
uint64_t in_file_id_volatile,
uint16_t in_lock_count,
struct smbd_smb2_lock_element *in_locks);
{
const uint8_t *inhdr;
const uint8_t *inbody;
- int i = req->current_idx;
+ const int i = req->current_idx;
size_t expected_body_size = 0x30;
size_t body_size;
+ uint32_t in_smbpid;
uint16_t in_lock_count;
uint64_t in_file_id_persistent;
uint64_t in_file_id_volatile;
struct smbd_smb2_lock_element *in_locks;
struct tevent_req *subreq;
const uint8_t *lock_buffer;
+ uint16_t l;
inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
+ in_smbpid = IVAL(inhdr, SMB2_HDR_PID);
+
in_lock_count = CVAL(inbody, 0x02);
- /* 0x04 4 bytes reserved */
+ /* 0x04 - 4 bytes reserved */
in_file_id_persistent = BVAL(inbody, 0x08);
in_file_id_volatile = BVAL(inbody, 0x10);
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
}
- i = 0;
+ l = 0;
lock_buffer = inbody + 0x18;
- in_locks[i].offset = BVAL(lock_buffer, 0x00);
- in_locks[i].length = BVAL(lock_buffer, 0x08);
- in_locks[i].flags = BVAL(lock_buffer, 0x10);
+ in_locks[l].offset = BVAL(lock_buffer, 0x00);
+ in_locks[l].length = BVAL(lock_buffer, 0x08);
+ in_locks[l].flags = IVAL(lock_buffer, 0x10);
+ /* 0x14 - 4 reserved bytes */
lock_buffer = (const uint8_t *)req->in.vector[i+2].iov_base;
- for (i=1; i < in_lock_count; i++) {
- in_locks[i].offset = BVAL(lock_buffer, 0x00);
- in_locks[i].length = BVAL(lock_buffer, 0x08);
- in_locks[i].flags = BVAL(lock_buffer, 0x10);
+ for (l=1; l < in_lock_count; l++) {
+ in_locks[l].offset = BVAL(lock_buffer, 0x00);
+ in_locks[l].length = BVAL(lock_buffer, 0x08);
+ in_locks[l].flags = IVAL(lock_buffer, 0x10);
+ /* 0x14 - 4 reserved bytes */
lock_buffer += 0x18;
}
subreq = smbd_smb2_lock_send(req,
req->conn->smb2.event_ctx,
req,
+ in_smbpid,
in_file_id_volatile,
in_lock_count,
in_locks);
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
+ uint32_t in_smbpid,
uint64_t in_file_id_volatile,
uint16_t in_lock_count,
struct smbd_smb2_lock_element *in_locks)
struct smb_request *smbreq;
connection_struct *conn = smb2req->tcon->compat_conn;
files_struct *fsp;
+ int32_t timeout = -1;
+ bool isunlock = false;
+ uint16_t i;
+ struct smbd_lock_element *locks;
+ NTSTATUS status;
+ bool async = false;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_lock_state);
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ locks = talloc_array(state, struct smbd_lock_element, in_lock_count);
+ if (locks == NULL) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_locks[0].flags) {
+ case SMB2_LOCK_FLAG_SHARED:
+ case SMB2_LOCK_FLAG_EXCLUSIVE:
+ if (in_lock_count > 1) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ timeout = -1;
+ break;
+
+ case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ timeout = 0;
+ break;
+
+ case SMB2_LOCK_FLAG_UNLOCK:
+ /* only the first lock gives the UNLOCK bit - see
+ MS-SMB2 3.3.5.14 */
+ isunlock = true;
+ timeout = 0;
+ break;
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ for (i=0; i<in_lock_count; i++) {
+ uint64_t max_count;
+ bool invalid = false;
+
+ switch (in_locks[i].flags) {
+ case SMB2_LOCK_FLAG_SHARED:
+ case SMB2_LOCK_FLAG_EXCLUSIVE:
+ if (i > 0) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ if (isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ if (isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ case SMB2_LOCK_FLAG_UNLOCK:
+ if (!isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ default:
+ if (isunlock) {
+ /*
+ * is the first element was a UNLOCK
+ * we need to deferr the error response
+ * to the backend, because we need to process
+ * all unlock elements before
+ */
+ invalid = true;
+ break;
+ }
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ locks[i].smbpid = in_smbpid;
+ locks[i].offset = in_locks[i].offset;
+ locks[i].count = in_locks[i].length;
+
+ if (in_locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE) {
+ locks[i].brltype = WRITE_LOCK;
+ } else if (in_locks[i].flags & SMB2_LOCK_FLAG_SHARED) {
+ locks[i].brltype = READ_LOCK;
+ } else if (invalid) {
+ /*
+ * this is an invalid UNLOCK element
+ * and the backend needs to test for
+ * brltype != UNLOCK_LOCK and return
+ * NT_STATUS_INVALID_PARAMER
+ */
+ locks[i].brltype = READ_LOCK;
+ } else {
+ locks[i].brltype = UNLOCK_LOCK;
+ }
+
+ max_count = UINT64_MAX - locks[i].offset;
+ if (locks[i].count > max_count) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_RANGE);
+ return tevent_req_post(req, ev);
+ }
+ }
+
+ if (isunlock) {
+ status = smbd_do_locking(smbreq, fsp,
+ 0,
+ timeout,
+ in_lock_count,
+ locks,
+ 0,
+ NULL,
+ &async);
+ } else {
+ status = smbd_do_locking(smbreq, fsp,
+ 0,
+ timeout,
+ 0,
+ NULL,
+ in_lock_count,
+ locks,
+ &async);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+ status = NT_STATUS_LOCK_NOT_GRANTED;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ if (async) {
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
DEBUG(3,("smbd_smb2_notify_send: notify change "
"called on %s, filter = %s, recursive = %d\n",
- fsp->fsp_name, filter_string, recursive));
+ fsp_str_dbg(fsp), filter_string, recursive));
TALLOC_FREE(filter_string);
}
if (nread < 0) {
DEBUG(5,("smbd_smb2_read: read_file[%s] nread[%lld]\n",
- fsp->fsp_name, (long long)nread));
+ fsp_str_dbg(fsp), (long long)nread));
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
return tevent_req_post(req, ev);
}
if (nread == 0 && in_length != 0) {
DEBUG(5,("smbd_smb2_read: read_file[%s] end of file\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
tevent_req_nterror(req, NT_STATUS_END_OF_FILE);
return tevent_req_post(req, ev);
}
if (invalid) {
/* the caller should check this */
- body_size = 0;
+ body_size = 2;
}
if ((body_size % 2) != 0) {
*/
memcpy(body, hdr + SMB2_HDR_BODY, 2);
vector[0].iov_base = body + 2;
- vector[0].iov_len = req->in.vector[idx].iov_len - 2;
+ vector[0].iov_len = body_size - 2;
vector[1] = req->in.vector[idx+1];
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (IS_IPC(conn)) {
+ tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_info_type) {
+ case 0x01:/* SMB2_SETINFO_FILE */
+ {
+ uint16_t file_info_level;
+ char *data;
+ int data_size;
+ int ret_size = 0;
+ NTSTATUS status;
+
+
+ file_info_level = in_file_info_class + 1000;
+ if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
+ file_info_level = 0xFF00 + in_file_info_class;
+ }
+
+ if (fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a SETFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n", fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) {
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "fileinfo of %s failed (%s)\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ }
+ } else if (fsp->print_file) {
+ /*
+ * Doing a DELETE_ON_CLOSE should cancel a print job.
+ */
+ if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO)
+ && in_input_buffer.length >= 1
+ && CVAL(in_input_buffer.data,0)) {
+ fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "Cancelling print job (%s)\n",
+ fsp_str_dbg(fsp)));
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ } else {
+ tevent_req_nterror(req,
+ NT_STATUS_OBJECT_PATH_INVALID);
+ return tevent_req_post(req, ev);
+ }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ DEBUG(3,("smbd_smb2_setinfo_send: fstat "
+ "of fnum %d failed (%s)\n", fsp->fnum,
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ }
+
+ data = NULL;
+ data_size = in_input_buffer.length;
+ if (data_size > 0) {
+ data = (char *)SMB_MALLOC_ARRAY(char, data_size);
+ if (tevent_req_nomem(data, req)) {
+
+ }
+ memcpy(data, in_input_buffer.data, data_size);
+ }
+
+ status = smbd_do_setfilepathinfo(conn, smbreq, state,
+ file_info_level,
+ fsp,
+ fsp->fsp_name,
+ &data,
+ data_size,
+ &ret_size);
+ SAFE_FREE(data);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ break;
+ }
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) {
DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
tevent_req_nterror(req, NT_STATUS_DISK_FULL);
return tevent_req_post(req, ev);
}
DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n",
- fsp->fnum, fsp->fsp_name, (int)in_data.length,
+ fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length,
(int)in_offset, (int)nwritten));
if (in_flags & 0x00000001) {
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
DATA_BLOB data_val;
char *name;
TALLOC_CTX *ctx = talloc_tos();
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
*pp_dirpath = NULL;
*pp_start = *pp_name;
"-> [%s]\n", chk_name, translated_path ));
DO_PROFILE_INC(statcache_hits);
- if (vfs_stat_smb_fname(conn, translated_path, pst) != 0) {
+ status = create_synthetic_smb_fname(talloc_tos(), translated_path,
+ NULL, NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(chk_name);
+ TALLOC_FREE(translated_path);
+ return false;
+ }
+
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
/* Discard this entry - it doesn't exist in the filesystem. */
memcache_delete(smbd_memcache(), STAT_CACHE,
data_blob_const(chk_name, strlen(chk_name)));
TALLOC_FREE(chk_name);
TALLOC_FREE(translated_path);
+ TALLOC_FREE(smb_fname);
return False;
}
+ *pst = smb_fname->st;
+ TALLOC_FREE(smb_fname);
if (!sizechanged) {
memcpy(*pp_name, translated_path,
return ret_data_size;
}
+static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
+ char *pdata,
+ unsigned int total_data_size,
+ unsigned int *ret_data_size,
+ connection_struct *conn,
+ struct ea_list *ea_list)
+{
+ uint8_t *p = (uint8_t *)pdata;
+ uint8_t *last_start = NULL;
+
+ *ret_data_size = 0;
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return NT_STATUS_NO_EAS_ON_FILE;
+ }
+
+ for (; ea_list; ea_list = ea_list->next) {
+ size_t dos_namelen;
+ fstring dos_ea_name;
+ size_t this_size;
+
+ if (last_start) {
+ SIVAL(last_start, 0, PTR_DIFF(p, last_start));
+ }
+ last_start = p;
+
+ push_ascii_fstring(dos_ea_name, ea_list->ea.name);
+ dos_namelen = strlen(dos_ea_name);
+ if (dos_namelen > 255 || dos_namelen == 0) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ if (ea_list->ea.value.length > 65535) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
+
+ if (ea_list->next) {
+ size_t pad = 4 - (this_size % 4);
+ this_size += pad;
+ }
+
+ if (this_size > total_data_size) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ /* We know we have room. */
+ SIVAL(p, 0x00, 0); /* next offset */
+ SCVAL(p, 0x04, ea_list->ea.flags);
+ SCVAL(p, 0x05, dos_namelen);
+ SSVAL(p, 0x06, ea_list->ea.value.length);
+ fstrcpy((char *)(p+0x08), dos_ea_name);
+ memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
+
+ total_data_size -= this_size;
+ p += this_size;
+ }
+
+ *ret_data_size = PTR_DIFF(p, pdata);
+ DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
+ return NT_STATUS_OK;
+}
+
static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
{
size_t total_ea_len = 0;
const struct smb_filename *smb_fname, struct ea_list *ea_list)
{
char *fname = NULL;
- NTSTATUS status;
if (!lp_ea_support(SNUM(conn))) {
return NT_STATUS_EAS_NOT_SUPPORTED;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ /* For now setting EAs on streams isn't supported. */
+ fname = smb_fname->base_name;
for (;ea_list; ea_list = ea_list->next) {
int ret;
if (ea_list->ea.value.length == 0) {
/* Remove the attribute. */
if (fsp && (fsp->fh->fd != -1)) {
- DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
+ DEBUG(10,("set_ea: deleting ea name %s on "
+ "file %s by file descriptor.\n",
+ unix_ea_name, fsp_str_dbg(fsp)));
ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
} else {
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
#endif
} else {
if (fsp && (fsp->fh->fd != -1)) {
- DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
+ DEBUG(10,("set_ea: setting ea name %s on file "
+ "%s by file descriptor.\n",
+ unix_ea_name, fsp_str_dbg(fsp)));
ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
ea_list->ea.value.data, ea_list->ea.value.length, 0);
} else {
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
goto out;
}
- if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
- open_ofun,
- &access_mask,
- &share_mode,
- &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
+ &access_mask, &share_mode,
+ &create_disposition,
+ &create_options)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
goto out;
}
SIVAL(params,20,inode);
SSVAL(params,24,0); /* Padding. */
if (flags & 8) {
- uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
+ uint32 ea_size = estimate_ea_size(conn, fsp,
+ fsp->fsp_name->base_name);
SIVAL(params, 26, ea_size);
} else {
SIVAL(params, 26, 0);
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
dirtype = SVAL(params,0);
ask_sharemode = false;
if (!lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ goto out;
}
break;
default:
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ goto out;
}
srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
STR_TERMINATE, &ntstatus, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
ntstatus = resolve_dfspath_wcard(ctx, conn,
if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- return;
+ goto out;
}
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
(UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
mask = smb_dname->original_lcomp;
- ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
- TALLOC_FREE(smb_dname);
- if (!NT_STATUS_IS_OK(ntstatus)) {
- reply_nterror(req, ntstatus);
- return;
- }
+ directory = smb_dname->base_name;
ntstatus = check_name(conn, directory);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
p = strrchr_m(directory,'/');
mask = talloc_strdup(ctx,"*");
if (!mask) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
mask_contains_wcard = True;
}
directory = talloc_strdup(talloc_tos(), "./");
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
} else {
*p = 0;
if (total_data < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
ea_size = IVAL(pdata,0);
DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
if (!lp_ea_support(SNUM(conn))) {
reply_doserror(req, ERRDOS, ERReasnotsupported);
- return;
+ goto out;
}
/* Pull out the list of names. */
ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
}
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL ) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
pdata = *ppdata;
data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
*pparams = (char *)SMB_REALLOC(*pparams, 10);
if (*pparams == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
params = *pparams;
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
dptr_num = dptr_dnum(conn->dirptr);
dptr_close(&dptr_num);
if (Protocol < PROTOCOL_NT1) {
reply_doserror(req, ERRDOS, ERRnofiles);
- return;
+ goto out;
} else {
reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
ERRDOS, ERRbadfile);
- return;
+ goto out;
}
}
char mangled_name[13];
name_to_8_3(mask, mangled_name, True, conn->params);
}
-
+ out:
+ TALLOC_FREE(smb_dname);
return;
}
"%s", samba_version_string());
}
-/****************************************************************************
- Reply to a TRANS2_QFSINFO (query filesystem info).
-****************************************************************************/
-
-static void call_trans2qfsinfo(connection_struct *conn,
- struct smb_request *req,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ int *ret_data_len)
{
char *pdata, *end_data;
- char *params = *pparams;
- uint16 info_level;
- int data_len, len;
- SMB_STRUCT_STAT st;
+ int data_len = 0, len;
const char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
uint32 additional_flags = 0;
-
- if (total_params < 2) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- info_level = SVAL(params,0);
+ struct smb_filename *smb_fname_dot = NULL;
+ SMB_STRUCT_STAT st;
+ NTSTATUS status;
if (IS_IPC(conn)) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
- DEBUG(0,("call_trans2qfsinfo: not an allowed "
+ DEBUG(0,("smbd_do_qfsinfo: not an allowed "
"info level (0x%x) on IPC$.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
+ return NT_STATUS_ACCESS_DENIED;
}
}
- if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
- if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
- DEBUG(0,("call_trans2qfsinfo: encryption required "
- "and info level 0x%x sent.\n",
- (unsigned int)info_level));
- exit_server_cleanly("encryption required "
- "on connection");
- return;
- }
- }
+ DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
- DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+ status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL,
+ &smb_fname_dot);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- if(vfs_stat_smb_fname(conn,".",&st)!=0) {
- DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
- reply_doserror(req, ERRSRV, ERRinvdevice);
- return;
+ if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) {
+ DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
+ TALLOC_FREE(smb_fname_dot);
+ return map_nt_error_from_unix(errno);
}
+ st = smb_fname_dot->st;
+ TALLOC_FREE(smb_fname_dot);
+
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
- if (*ppdata == NULL ) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ if (*ppdata == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
pdata = *ppdata;
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 18;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
* the pushed string. The change here was adding the STR_TERMINATE. JRA.
*/
len = srvstr_push(
- pdata, req->flags2,
+ pdata, flags2,
pdata+l2_vol_szVolLabel, vname,
PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
STR_NOALIGN|STR_TERMINATE);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
- DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
+ DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
(unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
len, vname));
break;
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
and will think we can't do long filenames */
- len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
+ len = srvstr_push(pdata, flags2, pdata+12, fstype,
PTR_DIFF(end_data, pdata+12),
STR_UNICODE);
SIVAL(pdata,8,len);
case SMB_QUERY_FS_LABEL_INFO:
case SMB_FS_LABEL_INFORMATION:
- len = srvstr_push(pdata, req->flags2, pdata+4, vname,
+ len = srvstr_push(pdata, flags2, pdata+4, vname,
PTR_DIFF(end_data, pdata+4), 0);
data_len = 4 + len;
SIVAL(pdata,0,len);
(str_checksum(get_local_machine_name())<<16));
/* Max label len is 32 characters. */
- len = srvstr_push(pdata, req->flags2, pdata+18, vname,
+ len = srvstr_push(pdata, flags2, pdata+18, vname,
PTR_DIFF(end_data, pdata+18),
STR_UNICODE);
SIVAL(pdata,12,len);
data_len = 18+len;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
(int)strlen(vname),vname, lp_servicename(snum)));
break;
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
if (bsize < block_size) {
}
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
SBIG_UINT(pdata,0,dsize);
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
if (bsize < block_size) {
}
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
fsp.fnum = -1;
/* access check */
- if (conn->server_info->utok.uid != 0) {
+ if (conn->server_info->utok.uid != sec_initial_uid()) {
DEBUG(0,("set_user_quota: access_denied "
"service [%s] user [%s]\n",
lp_servicename(SNUM(conn)),
conn->server_info->unix_name));
- reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
+ return NT_STATUS_ACCESS_DENIED;
}
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
- return;
+ return map_nt_error_from_unix(errno);
}
data_len = 48;
- DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
+ lp_servicename(SNUM(conn))));
/* Unknown1 24 NULL bytes*/
SBIG_UINT(pdata,0,(uint64_t)0);
int encrypt_caps = 0;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
switch (conn->encrypt_level) {
vfs_statvfs_struct svfs;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
rc = SMB_VFS_STATVFS(conn, ".", &svfs);
SBIG_UINT(pdata,32,svfs.TotalFileNodes);
SBIG_UINT(pdata,40,svfs.FreeFileNodes);
SBIG_UINT(pdata,48,svfs.FsIdentifier);
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
#ifdef EOPNOTSUPP
} else if (rc == EOPNOTSUPP) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
#endif /* EOPNOTSUPP */
} else {
DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRerror);
}
break;
}
int i;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
if (max_data_bytes < 40) {
- reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
- return;
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
/* We ARE guest if global_sid_Builtin_Guests is
}
/* drop through */
default:
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ *ret_data_len = data_len;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFSINFO (query filesystem info).
+****************************************************************************/
+
+static void call_trans2qfsinfo(connection_struct *conn,
+ struct smb_request *req,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ uint16_t info_level;
+ int data_len = 0;
+ NTSTATUS status;
+
+ if (total_params < 2) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ info_level = SVAL(params,0);
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: encryption required "
+ "and info level 0x%x sent.\n",
+ (unsigned int)info_level));
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
+ }
}
+ DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+
+ status = smbd_do_qfsinfo(conn, req,
+ info_level,
+ req->flags2,
+ max_data_bytes,
+ ppdata, &data_len);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
- send_trans2_replies(conn, req, params, 0, pdata, data_len,
+ send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
ZERO_STRUCT(quotas);
/* access check */
- if ((conn->server_info->utok.uid != 0)
+ if ((conn->server_info->utok.uid != sec_initial_uid())
||!CAN_WRITE(conn)) {
DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
lp_servicename(SNUM(conn)),
conn->server_info->unix_name));
- reply_doserror(req, ERRSRV, ERRaccess);
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
/* now set the quotas */
if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
+ reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
return;
}
-/****************************************************************************
- Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
- file name or file id).
-****************************************************************************/
-
-static void call_trans2qfilepathinfo(connection_struct *conn,
- struct smb_request *req,
- unsigned int tran_call,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ bool delete_pending,
+ struct timespec write_time_ts,
+ bool ms_dfs_link,
+ struct ea_list *ea_list,
+ int lock_data_count,
+ char *lock_data,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ unsigned int *pdata_size)
{
- char *params = *pparams;
char *pdata = *ppdata;
char *dstart, *dend;
- uint16 info_level;
- int mode=0;
- int nlink;
- SMB_OFF_T file_size=0;
- uint64_t allocation_size=0;
- unsigned int data_size = 0;
- unsigned int param_size = 2;
+ unsigned int data_size;
+ struct timespec create_time_ts, mtime_ts, atime_ts;
+ time_t create_time, mtime, atime;
SMB_STRUCT_STAT sbuf;
- char *dos_fname = NULL;
- char *fname = NULL;
- struct smb_filename *smb_fname = NULL;
- char *fullpathname;
- char *base_name;
char *p;
- SMB_OFF_T pos = 0;
- bool delete_pending = False;
- int len;
- time_t create_time, mtime, atime;
- struct timespec create_time_ts, mtime_ts, atime_ts;
- struct timespec write_time_ts;
- files_struct *fsp = NULL;
- struct file_id fileid;
- struct ea_list *ea_list = NULL;
- char *lock_data = NULL;
- bool ms_dfs_link = false;
- TALLOC_CTX *ctx = talloc_tos();
- NTSTATUS status = NT_STATUS_OK;
+ char *fname;
+ char *base_name;
+ char *dos_fname;
+ int mode;
+ int nlink;
+ NTSTATUS status;
+ uint64_t file_size = 0;
+ uint64_t pos = 0;
+ uint64_t allocation_size = 0;
+ uint64_t file_index = 0;
+ uint32_t access_mask = 0;
- if (!params) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
+ sbuf = smb_fname->st;
- ZERO_STRUCT(write_time_ts);
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+ return NT_STATUS_INVALID_LEVEL;
+ }
- if (tran_call == TRANSACT2_QFILEINFO) {
- if (total_params < 4) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
+ status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- if (IS_IPC(conn)) {
- call_trans2qpipeinfo(conn, req, tran_call,
- pparams, total_params,
- ppdata, total_data,
- max_data_bytes);
- return;
- }
+ DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
+ smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
+ info_level, max_data_bytes));
- fsp = file_fsp(req, SVAL(params,0));
- info_level = SVAL(params,2);
+ if (ms_dfs_link) {
+ mode = dos_mode_msdfs(conn, smb_fname);
+ } else {
+ mode = dos_mode(conn, smb_fname);
+ }
+ if (!mode)
+ mode = FILE_ATTRIBUTE_NORMAL;
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+ nlink = sbuf.st_ex_nlink;
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
- }
-
- /* Initial check for valid fsp ptr. */
- if (!check_fsp_open(conn, req, fsp)) {
- return;
- }
+ if (nlink && (mode&aDIR)) {
+ nlink = 1;
+ }
- fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
- if (!fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
+ if ((nlink > 0) && delete_pending) {
+ nlink -= 1;
+ }
- status = create_synthetic_smb_fname_split(talloc_tos(), fname,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
+ data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
+ *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
+ if (*ppdata == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ pdata = *ppdata;
+ dstart = pdata;
+ dend = dstart + data_size - 1;
- if(fsp->fake_file_handle) {
- /*
- * This is actually for the QUOTA_FAKE_FILE --metze
- */
+ if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
+ update_stat_ex_mtime(&sbuf, write_time_ts);
+ }
- /* We know this name is ok, it's already passed the checks. */
+ create_time_ts = sbuf.st_ex_btime;
+ mtime_ts = sbuf.st_ex_mtime;
+ atime_ts = sbuf.st_ex_atime;
- } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
- /*
- * This is actually a QFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
+ if (lp_dos_filetime_resolution(SNUM(conn))) {
+ dos_filetime_timespec(&create_time_ts);
+ dos_filetime_timespec(&mtime_ts);
+ dos_filetime_timespec(&atime_ts);
+ }
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else if (SMB_VFS_STAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_STAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
+ create_time = convert_timespec_to_time_t(create_time_ts);
+ mtime = convert_timespec_to_time_t(mtime_ts);
+ atime = convert_timespec_to_time_t(atime_ts);
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
- } else {
- /*
- * Original code - this is an open file.
- */
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
+ p = strrchr_m(smb_fname->base_name,'/');
+ if (!p)
+ base_name = smb_fname->base_name;
+ else
+ base_name = p+1;
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- DEBUG(3, ("fstat of fnum %d failed (%s)\n",
- fsp->fnum, strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadfid);
- return;
- }
- pos = fsp->fh->position_information;
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
+ /* NT expects the name to be in an exact form of the *full*
+ filename. See the trans2 torture test */
+ if (ISDOT(base_name)) {
+ dos_fname = talloc_strdup(mem_ctx, "\\");
+ if (!dos_fname) {
+ return NT_STATUS_NO_MEMORY;
}
-
} else {
- /* qpathinfo */
- if (total_params < 7) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ dos_fname = talloc_asprintf(mem_ctx,
+ "\\%s",
+ fname);
+ if (!dos_fname) {
+ return NT_STATUS_NO_MEMORY;
}
+ string_replace(dos_fname, '/', '\\');
+ }
- info_level = SVAL(params,0);
-
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf);
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ if (!fsp) {
+ /* Do we have this path open ? */
+ files_struct *fsp1;
+ struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ fsp1 = file_find_di_first(fileid);
+ if (fsp1 && fsp1->initial_allocation_size) {
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
}
+ }
- srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6],
- total_params - 6,
- STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
+ if (!(mode & aDIR)) {
+ file_size = get_file_size_stat(&sbuf);
+ }
- status = filename_convert(ctx,
- conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req,
- NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
+ if (fsp) {
+ pos = fsp->fh->position_information;
+ }
- /* If this is a stream, check if there is a delete_pending. */
- if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && is_ntfs_stream_smb_fname(smb_fname)) {
- struct smb_filename *smb_fname_base = NULL;
+ if (fsp) {
+ access_mask = fsp->access_mask;
+ } else {
+ /* GENERIC_EXECUTE mapping from Windows */
+ access_mask = 0x12019F;
+ }
- /* Create an smb_filename with stream_name == NULL. */
- status =
- create_synthetic_smb_fname(talloc_tos(),
- smb_fname->base_name,
- NULL, NULL,
- &smb_fname_base);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
+ /* This should be an index number - looks like
+ dev/ino to me :-)
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname_base),
- strerror(errno)));
- TALLOC_FREE(smb_fname_base);
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else {
- if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "fileinfo of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname_base),
- strerror(errno)));
- TALLOC_FREE(smb_fname_base);
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- }
+ I think this causes us to fail the IFSKIT
+ BasicFileInformationTest. -tpot */
+ file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */
+ file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
- fileid = vfs_file_id_from_sbuf(conn,
- &smb_fname_base->st);
- TALLOC_FREE(smb_fname_base);
- get_file_infos(fileid, &delete_pending, NULL);
- if (delete_pending) {
- reply_nterror(req, NT_STATUS_DELETE_PENDING);
- return;
- }
+ switch (info_level) {
+ case SMB_INFO_STANDARD:
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
+ data_size = 22;
+ srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
+ srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
+ srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
+ SIVAL(pdata,l1_cbFile,(uint32)file_size);
+ SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
+ SSVAL(pdata,l1_attrFile,mode);
+ break;
+
+ case SMB_INFO_QUERY_EA_SIZE:
+ {
+ unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
+ data_size = 26;
+ srv_put_dos_date2(pdata,0,create_time);
+ srv_put_dos_date2(pdata,4,atime);
+ srv_put_dos_date2(pdata,8,mtime); /* write time */
+ SIVAL(pdata,12,(uint32)file_size);
+ SIVAL(pdata,16,(uint32)allocation_size);
+ SSVAL(pdata,20,mode);
+ SIVAL(pdata,22,ea_size);
+ break;
}
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
+ case SMB_INFO_IS_NAME_VALID:
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
+ if (fsp) {
+ /* os/2 needs this ? really ?*/
+ return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
}
+ /* This is only reached for qpathinfo */
+ data_size = 0;
+ break;
- } else if (!VALID_STAT(smb_fname->st) &&
- SMB_VFS_STAT(conn, smb_fname) &&
- (info_level != SMB_INFO_IS_NAME_VALID)) {
- ms_dfs_link = check_msdfs_link(conn, fname,
- &smb_fname->st);
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ {
+ size_t total_ea_len = 0;
+ struct ea_list *ea_file_list = NULL;
- if (!ms_dfs_link) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_STAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
+
+ ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
+ ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+
+ if (!ea_list || (total_ea_len > data_size)) {
+ data_size = 4;
+ SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
+ break;
}
- }
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
- if (delete_pending) {
- reply_nterror(req, NT_STATUS_DELETE_PENDING);
- return;
+ data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
+ break;
}
- }
- /* Set sbuf for use below. */
- sbuf = smb_fname->st;
-
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
- }
-
- DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
- fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
-
- p = strrchr_m(smb_fname->base_name,'/');
- if (!p)
- base_name = smb_fname->base_name;
- else
- base_name = p+1;
-
- if (ms_dfs_link) {
- mode = dos_mode_msdfs(conn, smb_fname);
- } else {
- mode = dos_mode(conn, smb_fname);
- }
- if (!mode)
- mode = FILE_ATTRIBUTE_NORMAL;
-
- nlink = sbuf.st_ex_nlink;
-
- if (nlink && (mode&aDIR)) {
- nlink = 1;
- }
-
- if ((nlink > 0) && delete_pending) {
- nlink -= 1;
- }
-
- fullpathname = fname;
- if (!(mode & aDIR))
- file_size = get_file_size_stat(&sbuf);
-
- /* Pull out any data sent here before we realloc. */
- switch (info_level) {
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- {
- /* Pull any EA list from the data portion. */
- uint32 ea_size;
-
- if (total_data < 4) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
- ea_size = IVAL(pdata,0);
-
- if (total_data > 0 && ea_size != total_data) {
- DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
-total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- if (!lp_ea_support(SNUM(conn))) {
- reply_doserror(req, ERRDOS,
- ERReasnotsupported);
- return;
- }
-
- /* Pull out the list of names. */
- ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
- if (!ea_list) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
- break;
- }
-
- case SMB_QUERY_POSIX_LOCK:
- {
- if (fsp == NULL || fsp->fh->fd == -1) {
- reply_nterror(req, NT_STATUS_INVALID_HANDLE);
- return;
- }
-
- if (total_data != POSIX_LOCK_DATA_SIZE) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- /* Copy the lock range data. */
- lock_data = (char *)TALLOC_MEMDUP(
- ctx, pdata, total_data);
- if (!lock_data) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- }
- default:
- break;
- }
-
- *pparams = (char *)SMB_REALLOC(*pparams,2);
- if (*pparams == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- params = *pparams;
- SSVAL(params,0,0);
- data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
- *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
- if (*ppdata == NULL ) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- pdata = *ppdata;
- dstart = pdata;
- dend = dstart + data_size - 1;
-
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
-
- if (!fsp) {
- /* Do we have this path open ? */
- files_struct *fsp1;
- fileid = vfs_file_id_from_sbuf(conn, &sbuf);
- fsp1 = file_find_di_first(fileid);
- if (fsp1 && fsp1->initial_allocation_size) {
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
- }
- }
-
- if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
- update_stat_ex_mtime(&sbuf, write_time_ts);
- }
-
- create_time_ts = sbuf.st_ex_btime;
- mtime_ts = sbuf.st_ex_mtime;
- atime_ts = sbuf.st_ex_atime;
-
- if (lp_dos_filetime_resolution(SNUM(conn))) {
- dos_filetime_timespec(&create_time_ts);
- dos_filetime_timespec(&mtime_ts);
- dos_filetime_timespec(&atime_ts);
- }
-
- create_time = convert_timespec_to_time_t(create_time_ts);
- mtime = convert_timespec_to_time_t(mtime_ts);
- atime = convert_timespec_to_time_t(atime_ts);
-
- /* NT expects the name to be in an exact form of the *full*
- filename. See the trans2 torture test */
- if (ISDOT(base_name)) {
- dos_fname = talloc_strdup(ctx, "\\");
- if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- } else {
- dos_fname = talloc_asprintf(ctx,
- "\\%s",
- fname);
- if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- string_replace(dos_fname, '/', '\\');
- }
-
- switch (info_level) {
- case SMB_INFO_STANDARD:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
- data_size = 22;
- srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
- srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
- srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
- SIVAL(pdata,l1_cbFile,(uint32)file_size);
- SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
- SSVAL(pdata,l1_attrFile,mode);
- break;
-
- case SMB_INFO_QUERY_EA_SIZE:
- {
- unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
- data_size = 26;
- srv_put_dos_date2(pdata,0,create_time);
- srv_put_dos_date2(pdata,4,atime);
- srv_put_dos_date2(pdata,8,mtime); /* write time */
- SIVAL(pdata,12,(uint32)file_size);
- SIVAL(pdata,16,(uint32)allocation_size);
- SSVAL(pdata,20,mode);
- SIVAL(pdata,22,ea_size);
- break;
- }
-
- case SMB_INFO_IS_NAME_VALID:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
- if (tran_call == TRANSACT2_QFILEINFO) {
- /* os/2 needs this ? really ?*/
- reply_doserror(req, ERRDOS, ERRbadfunc);
- return;
- }
- data_size = 0;
- param_size = 0;
- break;
-
- case SMB_INFO_QUERY_EAS_FROM_LIST:
+ case SMB_INFO_QUERY_ALL_EAS:
{
+ /* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
- struct ea_list *ea_file_list = NULL;
-
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
- ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+ ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
data_size = 4;
SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
break;
}
- data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+ data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
break;
}
- case SMB_INFO_QUERY_ALL_EAS:
+ case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
{
/* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
+ struct ea_list *ea_file_list = NULL;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
- ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
- if (!ea_list || (total_ea_len > data_size)) {
- data_size = 4;
- SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
- break;
+ /*TODO: add filtering and index handling */
+
+ ea_file_list = get_ea_list_from_file(mem_ctx,
+ conn, fsp,
+ fname,
+ &total_ea_len);
+ if (!ea_file_list) {
+ return NT_STATUS_NO_EAS_ON_FILE;
}
- data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+ status = fill_ea_chained_buffer(mem_ctx,
+ pdata,
+ data_size,
+ &data_size,
+ conn, ea_file_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
break;
}
case SMB_QUERY_FILE_BASIC_INFO:
if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
} else {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
data_size = 40;
SIVAL(pdata,36,0);
}
case SMB_FILE_STANDARD_INFORMATION:
case SMB_QUERY_FILE_STANDARD_INFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
data_size = 24;
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,file_size);
case SMB_QUERY_FILE_EA_INFO:
{
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
data_size = 4;
SIVAL(pdata,0,ea_size);
break;
case SMB_QUERY_FILE_ALT_NAME_INFO:
case SMB_FILE_ALTERNATE_NAME_INFORMATION:
{
+ int len;
char mangled_name[13];
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
if (!name_to_8_3(base_name,mangled_name,
True,conn->params)) {
- reply_nterror(
- req,
- NT_STATUS_NO_MEMORY);
+ return NT_STATUS_NO_MEMORY;
}
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, mangled_name,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
}
case SMB_QUERY_FILE_NAME_INFO:
+ {
+ int len;
/*
this must be *exactly* right for ACLs on mapped drives to work
*/
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, dos_fname,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
data_size = 4 + len;
SIVAL(pdata,0,len);
break;
+ }
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,allocation_size);
break;
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_END_OF_FILEINFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,file_size);
break;
case SMB_QUERY_FILE_ALL_INFO:
case SMB_FILE_ALL_INFORMATION:
{
+ int len;
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
put_long_date_timespec(pdata,create_time_ts);
put_long_date_timespec(pdata+8,atime_ts);
put_long_date_timespec(pdata+16,mtime_ts); /* write time */
pdata += 24;
SIVAL(pdata,0,ea_size);
pdata += 4; /* EA info */
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, dos_fname,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
data_size = PTR_DIFF(pdata,(*ppdata));
break;
}
- case SMB_FILE_INTERNAL_INFORMATION:
- /* This should be an index number - looks like
- dev/ino to me :-)
- I think this causes us to fail the IFSKIT
- BasicFileInformationTest. -tpot */
+ case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
+ {
+ int len;
+ unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
+ put_long_date_timespec(pdata+0x00,create_time_ts);
+ put_long_date_timespec(pdata+0x08,atime_ts);
+ put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */
+ put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */
+ SIVAL(pdata, 0x20, mode);
+ SIVAL(pdata, 0x24, 0); /* padding. */
+ SBVAL(pdata, 0x28, allocation_size);
+ SBVAL(pdata, 0x30, file_size);
+ SIVAL(pdata, 0x38, nlink);
+ SCVAL(pdata, 0x3C, delete_pending);
+ SCVAL(pdata, 0x3D, (mode&aDIR)?1:0);
+ SSVAL(pdata, 0x3E, 0); /* padding */
+ SBVAL(pdata, 0x40, file_index);
+ SIVAL(pdata, 0x48, ea_size);
+ SIVAL(pdata, 0x4C, access_mask);
+ SBVAL(pdata, 0x50, pos);
+ SIVAL(pdata, 0x58, mode); /*TODO: mode != mode fix this!!! */
+ SIVAL(pdata, 0x5C, 0); /* No alignment needed. */
+
+ pdata += 0x60;
+
+ len = srvstr_push(dstart, flags2,
+ pdata+4, dos_fname,
+ PTR_DIFF(dend, pdata+4),
+ STR_UNICODE);
+ SIVAL(pdata,0,len);
+ pdata += 4 + len;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+ break;
+ }
+ case SMB_FILE_INTERNAL_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
+ SBVAL(pdata, 0, file_index);
data_size = 8;
break;
case SMB_FILE_ACCESS_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
- if (fsp) {
- SIVAL(pdata,0,fsp->access_mask);
- } else {
- /* GENERIC_EXECUTE mapping from Windows */
- SIVAL(pdata,0,0x12019F);
- }
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
+ SIVAL(pdata, 0, access_mask);
data_size = 4;
break;
{
size_t byte_len;
byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
SIVAL(pdata,0,byte_len);
data_size = 4 + byte_len;
break;
}
case SMB_FILE_DISPOSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
data_size = 1;
SCVAL(pdata,0,delete_pending);
break;
case SMB_FILE_POSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,pos);
break;
case SMB_FILE_MODE_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
SIVAL(pdata,0,mode);
data_size = 4;
break;
case SMB_FILE_ALIGNMENT_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
SIVAL(pdata,0,0); /* No alignment needed. */
data_size = 4;
break;
unsigned int num_streams;
struct stream_struct *streams;
- DEBUG(10,("call_trans2qfilepathinfo: "
+ DEBUG(10,("smbd_do_qfilepathinfo: "
"SMB_FILE_STREAM_INFORMATION\n"));
status = SMB_VFS_STREAMINFO(
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not get stream info: %s\n",
nt_errstr(status)));
- reply_nterror(req, status);
- return;
+ return status;
}
status = marshall_stream_info(num_streams, streams,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("marshall_stream_info failed: %s\n",
nt_errstr(status)));
- reply_nterror(req, status);
- return;
+ return status;
}
TALLOC_FREE(streams);
}
case SMB_QUERY_COMPRESSION_INFO:
case SMB_FILE_COMPRESSION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
SOFF_T(pdata,0,file_size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
break;
case SMB_FILE_NETWORK_OPEN_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
put_long_date_timespec(pdata,create_time_ts);
put_long_date_timespec(pdata+8,atime_ts);
put_long_date_timespec(pdata+16,mtime_ts); /* write time */
break;
case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
SIVAL(pdata,0,mode);
SIVAL(pdata,4,0);
data_size = 8;
{
int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
+ DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
for (i=0; i<100; i++)
DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
{
int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
+ DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
for (i=0; i<100; i++)
DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
case SMB_QUERY_FILE_UNIX_LINK:
{
- char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1);
+ int len;
+ char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
if (!buffer) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
if(!S_ISLNK(sbuf.st_ex_mode)) {
- reply_unixerror(req, ERRSRV,
- ERRbadlink);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRbadlink);
}
#else
- reply_unixerror(req, ERRDOS, ERRbadlink);
- return;
+ return NT_STATUS_DOS(ERRDOS, ERRbadlink);
#endif
- len = SMB_VFS_READLINK(conn,fullpathname,
+ len = SMB_VFS_READLINK(conn,fname,
buffer, PATH_MAX);
if (len == -1) {
- reply_unixerror(req, ERRDOS,
- ERRnoaccess);
- return;
+ return map_nt_error_from_unix(errno);
}
buffer[len] = 0;
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata, buffer,
PTR_DIFF(dend, pdata),
STR_TERMINATE);
}
if (file_acl == NULL && no_acl_syscall_error(errno)) {
- DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
+ DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
fname ));
- reply_nterror(
- req,
- NT_STATUS_NOT_IMPLEMENTED);
- return;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
if (S_ISDIR(sbuf.st_ex_mode)) {
if (fsp && fsp->is_directory) {
- def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl =
+ SMB_VFS_SYS_ACL_GET_FILE(
+ conn,
+ fsp->fsp_name->base_name,
+ SMB_ACL_TYPE_DEFAULT);
} else {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
}
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",
+ DEBUG(5,("smbd_do_qfilepathinfo: 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 (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req,
- NT_STATUS_BUFFER_TOO_SMALL);
- return;
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req, NT_STATUS_INTERNAL_ERROR);
- return;
+ return 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) {
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req,
- NT_STATUS_INTERNAL_ERROR);
- return;
+ return NT_STATUS_INTERNAL_ERROR;
}
if (file_acl) {
uint32 lock_pid;
enum brl_type lock_type;
- if (total_data != POSIX_LOCK_DATA_SIZE) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
+ /* We need an open file with a real fd for this. */
+ if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
+ return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
case POSIX_LOCK_TYPE_UNLOCK:
default:
/* There's no point in asking for an unlock... */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
+ return NT_STATUS_INVALID_PARAMETER;
}
lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
} else {
+ return status;
+ }
+ break;
+ }
+
+ default:
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ *pdata_size = data_size;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
+ file name or file id).
+****************************************************************************/
+
+static void call_trans2qfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 info_level;
+ unsigned int data_size = 0;
+ unsigned int param_size = 2;
+ struct smb_filename *smb_fname = NULL;
+ bool delete_pending = False;
+ struct timespec write_time_ts;
+ files_struct *fsp = NULL;
+ struct file_id fileid;
+ struct ea_list *ea_list = NULL;
+ int lock_data_count = 0;
+ char *lock_data = NULL;
+ bool ms_dfs_link = false;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (!params) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ ZERO_STRUCT(write_time_ts);
+
+ if (tran_call == TRANSACT2_QFILEINFO) {
+ if (total_params < 4) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (IS_IPC(conn)) {
+ call_trans2qpipeinfo(conn, req, tran_call,
+ pparams, total_params,
+ ppdata, total_data,
+ max_data_bytes);
+ return;
+ }
+
+ fsp = file_fsp(req, SVAL(params,0));
+ info_level = SVAL(params,2);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+
+ /* Initial check for valid fsp ptr. */
+ if (!check_fsp_open(conn, req, fsp)) {
+ return;
+ }
+
+ status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ if(fsp->fake_file_handle) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ /* We know this name is ok, it's already passed the checks. */
+
+ } else if(fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a QFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ } else if (SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ if (!check_fsp(conn, req, fsp)) {
+ return;
+ }
+
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3, ("fstat of fnum %d failed (%s)\n",
+ fsp->fnum, strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ }
+
+ } else {
+ char *fname = NULL;
+
+ /* qpathinfo */
+ if (total_params < 7) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ info_level = SVAL(params,0);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+
+ srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = filename_convert(req,
+ conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ fname,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ return;
+ }
+ reply_nterror(req, status);
+ return;
+ }
+
+ /* If this is a stream, check if there is a delete_pending. */
+ if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
+ && is_ntfs_stream_smb_fname(smb_fname)) {
+ struct smb_filename *smb_fname_base = NULL;
+
+ /* Create an smb_filename with stream_name == NULL. */
+ status =
+ create_synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ NULL, NULL,
+ &smb_fname_base);
+ if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "fileinfo of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn,
+ &smb_fname_base->st);
+ TALLOC_FREE(smb_fname_base);
+ get_file_infos(fileid, &delete_pending, NULL);
+ if (delete_pending) {
+ reply_nterror(req, NT_STATUS_DELETE_PENDING);
+ return;
+ }
+ }
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname) &&
+ (info_level != SMB_INFO_IS_NAME_VALID)) {
+ ms_dfs_link = check_msdfs_link(conn,
+ smb_fname->base_name,
+ &smb_fname->st);
+
+ if (!ms_dfs_link) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ if (delete_pending) {
+ reply_nterror(req, NT_STATUS_DELETE_PENDING);
+ return;
+ }
+ }
+
+ DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
+ "total_data=%d\n", smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+
+ /* Pull out any data sent here before we realloc. */
+ switch (info_level) {
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ {
+ /* Pull any EA list from the data portion. */
+ uint32 ea_size;
+
+ if (total_data < 4) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+ ea_size = IVAL(pdata,0);
+
+ if (total_data > 0 && ea_size != total_data) {
+ DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ reply_doserror(req, ERRDOS,
+ ERReasnotsupported);
+ return;
+ }
+
+ /* Pull out the list of names. */
+ ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
+ if (!ea_list) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
break;
}
+ case SMB_QUERY_POSIX_LOCK:
+ {
+ if (fsp == NULL || fsp->fh->fd == -1) {
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return;
+ }
+
+ if (total_data != POSIX_LOCK_DATA_SIZE) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ /* Copy the lock range data. */
+ lock_data = (char *)TALLOC_MEMDUP(
+ req, pdata, total_data);
+ if (!lock_data) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ lock_data_count = total_data;
+ }
default:
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ break;
+ }
+
+ *pparams = (char *)SMB_REALLOC(*pparams,2);
+ if (*pparams == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ params = *pparams;
+ SSVAL(params,0,0);
+
+ /*
+ * draft-leach-cifs-v1-spec-02.txt
+ * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
+ * says:
+ *
+ * The requested information is placed in the Data portion of the
+ * transaction response. For the information levels greater than 0x100,
+ * the transaction response has 1 parameter word which should be
+ * ignored by the client.
+ *
+ * However Windows only follows this rule for the IS_NAME_VALID call.
+ */
+ switch (info_level) {
+ case SMB_INFO_IS_NAME_VALID:
+ param_size = 0;
+ break;
+ }
+
+ if ((info_level & 0xFF00) == 0xFF00) {
+ /*
+ * We use levels that start with 0xFF00
+ * internally to represent SMB2 specific levels
+ */
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+
+ status = smbd_do_qfilepathinfo(conn, req, info_level,
+ fsp, smb_fname,
+ delete_pending, write_time_ts,
+ ms_dfs_link, ea_list,
+ lock_data_count, lock_data,
+ req->flags2, max_data_bytes,
+ ppdata, &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
}
send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
const struct smb_filename *smb_fname_old,
const struct smb_filename *smb_fname_new)
{
- char *oldname = NULL;
- char *newname = NULL;
NTSTATUS status = NT_STATUS_OK;
/* source must already exist. */
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- status = get_full_smb_filename(ctx, smb_fname_new, &newname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
- status = get_full_smb_filename(ctx, smb_fname_old, &oldname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ /* Setting a hardlink to/from a stream isn't currently supported. */
+ if (is_ntfs_stream_smb_fname(smb_fname_old) ||
+ is_ntfs_stream_smb_fname(smb_fname_new)) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
+ DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
+ smb_fname_old->base_name, smb_fname_new->base_name));
- if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
+ if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
+ smb_fname_new->base_name) != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
- nt_errstr(status), newname, oldname));
+ nt_errstr(status), smb_fname_old->base_name,
+ smb_fname_new->base_name));
}
- out:
- TALLOC_FREE(newname);
- TALLOC_FREE(oldname);
return status;
}
}
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
- fsp->fsp_name, (double)position_information ));
+ DEBUG(10,("smb_file_position_information: Set file position "
+ "information for file %s to %.0f\n", fsp_str_dbg(fsp),
+ (double)position_information));
fsp->fh->position_information = position_information;
return NT_STATUS_OK;
}
struct smb_request *req,
const char *pdata,
int total_data,
- const char *fname)
+ const struct smb_filename *smb_fname)
{
char *link_target = NULL;
- const char *newname = fname;
+ const char *newname = smb_fname->base_name;
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname,
- &smb_fname_old,
- NULL);
+ &smb_fname_old);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* Create an smb_fname to call rename_internals_fsp() with. */
status = create_synthetic_smb_fname(talloc_tos(),
- fsp->base_fsp->fsp_name,
- newname, NULL, &smb_fname);
+ fsp->base_fsp->fsp_name->base_name, newname, NULL,
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
/* Create a char * to call rename_internals() with. */
base_name = talloc_asprintf(ctx, "%s%s",
- fsp->base_fsp->fsp_name,
+ fsp->base_fsp->fsp_name->base_name,
newname);
if (!base_name) {
status = NT_STATUS_NO_MEMORY;
}
if (fsp) {
- DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp->fsp_name, base_name ));
+ DEBUG(10,("smb_file_rename_information: "
+ "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
+ fsp->fnum, fsp_str_dbg(fsp), base_name));
status = rename_internals_fsp(conn, fsp, smb_fname, 0,
overwrite);
} else {
- DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
- fname, base_name ));
+ DEBUG(10,("smb_file_rename_information: "
+ "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
+ fname, base_name));
status = rename_internals(ctx, conn, req, fname, base_name, 0,
overwrite, False, dest_has_wcard,
FILE_WRITE_ATTRIBUTES);
const char *pdata,
int total_data,
files_struct *fsp,
- const char *fname,
- SMB_STRUCT_STAT *psbuf)
+ const struct smb_filename *smb_fname)
{
uint16 posix_acl_version;
uint16 num_file_acls;
}
DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
- fname ? fname : fsp->fsp_name,
+ smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
(unsigned int)num_file_acls,
(unsigned int)num_def_acls));
- if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+ if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
+ smb_fname->base_name, num_file_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
return map_nt_error_from_unix(errno);
}
- if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE +
- (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+ if (valid_def_acls && !set_unix_posix_default_acl(conn,
+ smb_fname->base_name, &smb_fname->st, num_def_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
return map_nt_error_from_unix(errno);
}
return NT_STATUS_OK;
DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
"lock_pid = %u, count = %.0f, offset = %.0f\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)lock_type,
(unsigned int)lock_pid,
(double)count,
struct smb_request *req,
char **ppdata,
int total_data,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
+ struct smb_filename *smb_fname,
int *pdata_return_size)
{
- struct smb_filename *smb_fname;
NTSTATUS status = NT_STATUS_OK;
uint32 raw_unixmode = 0;
uint32 mod_unixmode = 0;
raw_unixmode = IVAL(pdata,8);
/* Next 4 bytes are not yet defined. */
- status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode);
+ status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+ PERM_NEW_DIR, &unixmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
- fname, (unsigned int)unixmode ));
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
&fsp, /* result */
&info); /* pinfo */
- *psbuf = smb_fname->st;
- TALLOC_FREE(smb_fname);
-
if (NT_STATUS_IS_OK(status)) {
close_file(req, fsp, NORMAL_CLOSE);
}
case SMB_QUERY_FILE_UNIX_BASIC:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
SSVAL(pdata,10,0); /* Padding. */
- store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
case SMB_QUERY_FILE_UNIX_INFO2:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
SSVAL(pdata,10,0); /* Padding. */
- store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic_info2(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
default:
SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
struct smb_request *req,
char **ppdata,
int total_data,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
+ struct smb_filename *smb_fname,
int *pdata_return_size)
{
- struct smb_filename *smb_fname = NULL;
bool extended_oplock_granted = False;
char *pdata = *ppdata;
uint32 flags = 0;
return smb_posix_mkdir(conn, req,
ppdata,
total_data,
- fname,
- psbuf,
+ smb_fname,
pdata_return_size);
}
raw_unixmode = IVAL(pdata,8);
/* Next 4 bytes are not yet defined. */
- status = unix_perms_from_wire(conn,
- psbuf,
- raw_unixmode,
- VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE,
- &unixmode);
+ status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+ (VALID_STAT(smb_fname->st) ?
+ PERM_EXISTING_FILE : PERM_NEW_FILE),
+ &unixmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
(unsigned int)wire_open_mode,
(unsigned int)unixmode ));
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
&fsp, /* result */
&info); /* pinfo */
- *psbuf = smb_fname->st;
- TALLOC_FREE(smb_fname);
-
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QUERY_FILE_UNIX_BASIC:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
SSVAL(pdata,10,0); /* padding. */
- store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
case SMB_QUERY_FILE_UNIX_INFO2:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
SSVAL(pdata,10,0); /* padding. */
- store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic_info2(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
default:
SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
NULL);
if (lck == NULL) {
- DEBUG(0, ("smb_posix_unlink: Could not get share mode "
- "lock for file %s\n", fsp->fsp_name));
- close_file(req, fsp, NORMAL_CLOSE);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * See if others still have the file open. If this is the case, then
- * don't delete. If all opens are POSIX delete we can set the delete
- * on close disposition.
- */
- for (i=0; i<lck->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->share_modes[i];
- if (is_valid_share_mode_entry(e)) {
- if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
- continue;
- }
- /* Fail with sharing violation. */
- close_file(req, fsp, NORMAL_CLOSE);
- TALLOC_FREE(lck);
- return NT_STATUS_SHARING_VIOLATION;
- }
- }
-
- /*
- * Set the delete on close.
- */
- status = smb_set_file_disposition_info(conn,
- &del,
- 1,
- fsp,
- smb_fname);
-
- if (!NT_STATUS_IS_OK(status)) {
- close_file(req, fsp, NORMAL_CLOSE);
- TALLOC_FREE(lck);
- return status;
- }
- TALLOC_FREE(lck);
- return close_file(req, fsp, NORMAL_CLOSE);
-}
-
-/****************************************************************************
- Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
-****************************************************************************/
-
-static void call_trans2setfilepathinfo(connection_struct *conn,
- struct smb_request *req,
- unsigned int tran_call,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
-{
- char *params = *pparams;
- char *pdata = *ppdata;
- uint16 info_level;
- SMB_STRUCT_STAT sbuf;
- char *fname = NULL;
- struct smb_filename *smb_fname = NULL;
- files_struct *fsp = NULL;
- NTSTATUS status = NT_STATUS_OK;
- int data_return_size = 0;
- TALLOC_CTX *ctx = talloc_tos();
-
- if (!params) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- if (tran_call == TRANSACT2_SETFILEINFO) {
- if (total_params < 4) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- fsp = file_fsp(req, SVAL(params,0));
- /* Basic check for non-null fsp. */
- if (!check_fsp_open(conn, req, fsp)) {
- return;
- }
- info_level = SVAL(params,2);
-
- fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
- if (!fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- if(fsp->is_directory || fsp->fh->fd == -1) {
- /*
- * This is actually a SETFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2setfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else {
- if (SMB_VFS_STAT(conn, smb_fname) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: "
- "fileinfo of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- }
- } else if (fsp->print_file) {
- /*
- * Doing a DELETE_ON_CLOSE should cancel a print job.
- */
- if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
- fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
-
- DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
-
- SSVAL(params,0,0);
- send_trans2_replies(conn, req, params, 2,
- *ppdata, 0,
- max_data_bytes);
- return;
- } else {
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
- } else {
- /*
- * Original code - this is an open file.
- */
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
-
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat "
- "of fnum %d failed (%s)\n", fsp->fnum,
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadfid);
- return;
- }
- }
- } else {
- /* set path info */
- if (total_params < 7) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- info_level = SVAL(params,0);
- srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6],
- total_params - 6, STR_TERMINATE,
- &status);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req,
- NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
+ DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+ "lock for file %s\n", fsp_str_dbg(fsp)));
+ close_file(req, fsp, NORMAL_CLOSE);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /*
+ * See if others still have the file open. If this is the case, then
+ * don't delete. If all opens are POSIX delete we can set the delete
+ * on close disposition.
+ */
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if (is_valid_share_mode_entry(e)) {
+ if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+ continue;
}
- reply_nterror(req, status);
- return;
+ /* Fail with sharing violation. */
+ close_file(req, fsp, NORMAL_CLOSE);
+ TALLOC_FREE(lck);
+ return NT_STATUS_SHARING_VIOLATION;
}
+ }
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /*
- * For CIFS UNIX extensions the target name may not exist.
- */
-
- /* Always do lstat for UNIX calls. */
- SMB_VFS_LSTAT(conn, smb_fname);
+ /*
+ * Set the delete on close.
+ */
+ status = smb_set_file_disposition_info(conn,
+ &del,
+ 1,
+ fsp,
+ smb_fname);
- } else if (!VALID_STAT(smb_fname->st) &&
- SMB_VFS_STAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
- "%s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ close_file(req, fsp, NORMAL_CLOSE);
+ TALLOC_FREE(lck);
+ return status;
}
+ TALLOC_FREE(lck);
+ return close_file(req, fsp, NORMAL_CLOSE);
+}
- /* Set sbuf for use below. */
- sbuf = smb_fname->st;
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ struct smb_filename *smb_fname,
+ char **ppdata, int total_data,
+ int *ret_data_size)
+{
+ char *pdata = *ppdata;
+ char *fname = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+ int data_return_size = 0;
+
+ *ret_data_size = 0;
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
if (!CAN_WRITE(conn)) {
/* Allow POSIX opens. The open path will deny
* any non-readonly opens. */
if (info_level != SMB_POSIX_PATH_OPEN) {
- reply_doserror(req, ERRSRV, ERRaccess);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRaccess);
}
}
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
- tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
-
- /* Realloc the parameter size */
- *pparams = (char *)SMB_REALLOC(*pparams,2);
- if (*pparams == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- params = *pparams;
- SSVAL(params,0,0);
+ DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
+ "totdata=%d\n", smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level, total_data));
switch (info_level) {
case SMB_SET_FILE_UNIX_LINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_file_unix_link(conn, req, pdata,
- total_data, fname);
+ total_data, smb_fname);
break;
}
case SMB_SET_FILE_UNIX_HLINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_file_unix_hlink(conn, req,
pdata, total_data,
pdata,
total_data,
fsp,
- fname,
- &sbuf);
+ smb_fname);
break;
}
#endif
case SMB_SET_POSIX_LOCK:
{
- if (tran_call != TRANSACT2_SETFILEINFO) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ if (!fsp) {
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_posix_lock(conn, req,
pdata, total_data, fsp);
case SMB_POSIX_PATH_OPEN:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_posix_open(conn, req,
ppdata,
total_data,
- fname,
- &sbuf,
+ smb_fname,
&data_return_size);
break;
}
case SMB_POSIX_PATH_UNLINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_posix_unlink(conn, req,
}
default:
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ *ret_data_size = data_return_size;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
+****************************************************************************/
+
+static void call_trans2setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 info_level;
+ struct smb_filename *smb_fname = NULL;
+ files_struct *fsp = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+ int data_return_size = 0;
+
+ if (!params) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (tran_call == TRANSACT2_SETFILEINFO) {
+ if (total_params < 4) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ fsp = file_fsp(req, SVAL(params,0));
+ /* Basic check for non-null fsp. */
+ if (!check_fsp_open(conn, req, fsp)) {
+ return;
+ }
+ info_level = SVAL(params,2);
+
+ status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ if(fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a SETFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "fileinfo of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+ } else if (fsp->print_file) {
+ /*
+ * Doing a DELETE_ON_CLOSE should cancel a print job.
+ */
+ if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
+ fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "Cancelling print job (%s)\n",
+ fsp_str_dbg(fsp)));
+
+ SSVAL(params,0,0);
+ send_trans2_replies(conn, req, params, 2,
+ *ppdata, 0,
+ max_data_bytes);
+ return;
+ } else {
+ reply_doserror(req, ERRDOS, ERRbadpath);
+ return;
+ }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ if (!check_fsp(conn, req, fsp)) {
+ return;
+ }
+
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: fstat "
+ "of fnum %d failed (%s)\n", fsp->fnum,
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+ } else {
+ char *fname = NULL;
+
+ /* set path info */
+ if (total_params < 7) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ info_level = SVAL(params,0);
+ srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
+ total_params - 6, STR_TERMINATE,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = filename_convert(req, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ fname,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ return;
+ }
+ reply_nterror(req, status);
+ return;
+ }
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /*
+ * For CIFS UNIX extensions the target name may not exist.
+ */
+
+ /* Always do lstat for UNIX calls. */
+ SMB_VFS_LSTAT(conn, smb_fname);
+
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
+ "%s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
return;
+ }
+ }
+
+ DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
+ "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level,total_data));
+
+ /* Realloc the parameter size */
+ *pparams = (char *)SMB_REALLOC(*pparams,2);
+ if (*pparams == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
+ params = *pparams;
+
+ SSVAL(params,0,0);
+ status = smbd_do_setfilepathinfo(conn, req, req,
+ info_level,
+ fsp,
+ smb_fname,
+ ppdata, total_data,
+ &data_return_size);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
return;
}
- SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
* Actually try and commit the space on disk....
*/
- DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
+ fsp_str_dbg(fsp), (double)len));
if (((SMB_OFF_T)len) < 0) {
- DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
+ DEBUG(0,("vfs_allocate_file_space: %s negative len "
+ "requested.\n", fsp_str_dbg(fsp)));
errno = EINVAL;
return -1;
}
if (len < (uint64_t)st.st_ex_size) {
/* Shrink - use ftruncate. */
- DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
- fsp->fsp_name, (double)st.st_ex_size ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
+ "size %.0f\n", fsp_str_dbg(fsp),
+ (double)st.st_ex_size));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
len -= st.st_ex_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
- space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
+ space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
+ &bsize, &dfree, &dsize);
if (space_avail == (uint64_t)-1) {
return -1;
}
- DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
- fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
+ "needed blocks = %.0f, space avail = %.0f\n",
+ fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len,
+ (double)space_avail));
if (len > space_avail) {
errno = ENOSPC;
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
- DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
+ DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
+ fsp_str_dbg(fsp), (double)len));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
set_filelen_write_cache(fsp, len);
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
return 0;
}
- DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
- fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size)));
+ DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
+ "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
+ (double)st.st_ex_size, (double)len,
+ (double)(len - st.st_ex_size)));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
if (pwrite_ret == -1) {
- DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file "
+ "%s failed with error %s\n",
+ fsp_str_dbg(fsp), strerror(errno)));
ret = -1;
goto out;
}
#ifdef S_ISLNK
if (!lp_symlinks(SNUM(conn))) {
- SMB_STRUCT_STAT statbuf;
- if ( (vfs_lstat_smb_fname(conn,fname,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_ex_mode)) ) {
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (free_resolved_name) {
+ SAFE_FREE(resolved_name);
+ }
+ return status;
+ }
+
+ if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
+ (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
if (free_resolved_name) {
SAFE_FREE(resolved_name);
}
DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name));
+ TALLOC_FREE(smb_fname);
return NT_STATUS_ACCESS_DENIED;
}
+ TALLOC_FREE(smb_fname);
}
#endif
}
return NT_STATUS_OK;
}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_STAT(conn, smb_fname);
+ if (ret != -1) {
+ *psbuf = smb_fname->st;
+ }
+
+ TALLOC_FREE(smb_fname);
+ return ret;
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
+ if (ret != -1) {
+ *psbuf = smb_fname->st;
+ }
+
+ TALLOC_FREE(smb_fname);
+ return ret;
+}
+
if (fsp == NULL) {
return NT_STATUS_NO_MEMORY;
}
- fsp->fsp_name = SMB_STRDUP(argv[1]);
- if (fsp->fsp_name == NULL) {
- SAFE_FREE(fsp);
- return NT_STATUS_NO_MEMORY;
- }
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (fsp->fh == NULL) {
SAFE_FREE(fsp->fsp_name);
status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
- SAFE_FREE(fsp->fsp_name);
SAFE_FREE(fsp);
return status;
}
+ fsp->fsp_name = smb_fname;
+
fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode);
- TALLOC_FREE(smb_fname);
if (fsp->fh->fd == -1) {
printf("open: error=%d (%s)\n", errno, strerror(errno));
SAFE_FREE(fsp->fh);
- SAFE_FREE(fsp->fsp_name);
SAFE_FREE(fsp);
+ TALLOC_FREE(smb_fname);
return NT_STATUS_UNSUCCESSFUL;
}
else
printf("close: ok\n");
- SAFE_FREE(vfs->files[fd]->fsp_name);
+ TALLOC_FREE(vfs->files[fd]->fsp_name);
SAFE_FREE(vfs->files[fd]->fh);
SAFE_FREE(vfs->files[fd]);
vfs->files[fd] = NULL;
case OP_UNLOCK:
/* unset a lock */
for (server=0;server<NSERVERS;server++) {
- ret[server] = cli_unlock64(cli[server][conn],
+ ret[server] = NT_STATUS_IS_OK(cli_unlock64(cli[server][conn],
fnum[server][conn][f],
- start, len);
+ start, len));
status[server] = cli_nt_error(cli[server][conn]);
}
if (showall ||
switch (fstype) {
case FSTYPE_SMB:
- return cli_unlock(c, fd, start, len);
+ return NT_STATUS_IS_OK(cli_unlock(c, fd, start, len));
case FSTYPE_NFS:
lock.l_type = F_UNLCK;
pdb_set_homedir(out, "\\\\torture\\home", PDB_SET);
pdb_set_logon_script(out, "torture_script.cmd", PDB_SET);
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &history);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &history);
if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) {
buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN);
} else {
}
pdb_set_pw_history(out, buf, history, PDB_SET);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire);
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &min_age);
pdb_set_pass_last_set_time(out, time(NULL), PDB_SET);
if (expire == 0 || expire == (uint32)-1) {
correct = False;
}
- if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
+ if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
printf("unlock failed (%s)\n", cli_errstr(c));
correct = False;
}
printf("lock at 100 failed (%s)\n", cli_errstr(cli));
}
cli_setpid(cli, 2);
- if (cli_unlock(cli, fnum1, 100, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
printf("unlock at 100 succeeded! This is a locking bug\n");
correct = False;
}
- if (cli_unlock(cli, fnum1, 0, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
printf("unlock1 succeeded! This is a locking bug\n");
correct = False;
} else {
NT_STATUS_RANGE_NOT_LOCKED)) return False;
}
- if (cli_unlock(cli, fnum1, 0, 8)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
printf("unlock2 succeeded! This is a locking bug\n");
correct = False;
} else {
for (offset=i=0;i<torture_numops;i++) {
NEXT_OFFSET;
- if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
printf("unlock1 %d failed (%s)\n",
i,
cli_errstr(cli1));
return False;
}
- if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
printf("unlock2 %d failed (%s)\n",
i,
cli_errstr(cli1));
ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 110, 6);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
EXPECTED(ret, False);
printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 140, 4) &&
- cli_unlock(cli1, fnum1, 140, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
EXPECTED(ret, True);
printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 150, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
(cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
!(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
- cli_unlock(cli1, fnum1, 150, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
EXPECTED(ret, True);
printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 160, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 160, 4) == 4);
EXPECTED(ret, True);
printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
- cli_unlock(cli1, fnum1, 170, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 170, 4) == 4);
EXPECTED(ret, True);
ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 190, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
!(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 190, 4) == 4);
EXPECTED(ret, True);
/* Unlock the first process lock, then check this was the WRITE lock that was
removed. */
- ret = cli_unlock(cli1, fnum1, 0, 4) &&
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
EXPECTED(ret, True);
/* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
- ret = cli_unlock(cli1, fnum1, 1, 1) &&
- cli_unlock(cli1, fnum1, 0, 4) &&
- cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, True);
printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
/* Ensure the next unlock fails. */
- ret = cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, False);
printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
goto out;
}
+ /* Do a POSIX lock/unlock. */
+ if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
+ printf("POSIX lock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Punch a hole in the locked area. */
+ if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
+ printf("POSIX unlock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
cli_close(cli1, fnum1);
/* Open the symlink for read - this should fail. A POSIX
return ok;
}
+static bool run_local_base64(int dummy)
+{
+ int i;
+ bool ret = true;
+
+ for (i=1; i<2000; i++) {
+ DATA_BLOB blob1, blob2;
+ char *b64;
+
+ blob1.data = talloc_array(talloc_tos(), uint8_t, i);
+ blob1.length = i;
+ generate_random_buffer(blob1.data, blob1.length);
+
+ b64 = base64_encode_data_blob(talloc_tos(), blob1);
+ if (b64 == NULL) {
+ d_fprintf(stderr, "base64_encode_data_blob failed "
+ "for %d bytes\n", i);
+ ret = false;
+ }
+ blob2 = base64_decode_data_blob(b64);
+ TALLOC_FREE(b64);
+
+ if (data_blob_cmp(&blob1, &blob2)) {
+ d_fprintf(stderr, "data_blob_cmp failed for %d "
+ "bytes\n", i);
+ ret = false;
+ }
+ TALLOC_FREE(blob1.data);
+ data_blob_free(&blob2);
+ }
+ return ret;
+}
+
static bool run_local_gencache(int dummy)
{
char *val;
time_t tm;
DATA_BLOB blob;
- if (!gencache_init()) {
- d_printf("%s: gencache_init() failed\n", __location__);
- return False;
- }
-
if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
d_printf("%s: gencache_set() failed\n", __location__);
return False;
}
blob = data_blob_string_const_null("bar");
- tm = time(NULL);
+ tm = time(NULL) + 60;
if (!gencache_set_data_blob("foo", &blob, tm)) {
d_printf("%s: gencache_set_data_blob() failed\n", __location__);
return False;
}
- data_blob_free(&blob);
-
if (!gencache_get_data_blob("foo", &blob, NULL)) {
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
return False;
return False;
}
- if (!gencache_shutdown()) {
- d_printf("%s: gencache_shutdown() failed\n", __location__);
- return False;
- }
-
- if (gencache_shutdown()) {
- d_printf("%s: second gencache_shutdown() succeeded\n",
- __location__);
- return False;
- }
-
return True;
}
{ "STREAMERROR", run_streamerror },
{ "LOCAL-SUBSTITUTE", run_local_substitute, 0},
{ "LOCAL-GENCACHE", run_local_gencache, 0},
+ { "LOCAL-BASE64", run_local_base64, 0},
{ "LOCAL-RBTREE", run_local_rbtree, 0},
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},
int main(int argc, const char **argv)
{
int opt,i;
+ char *p;
int rc = 0;
int argc_new = 0;
const char ** argv_new;
struct poptOption long_options[] = {
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
{"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup},
+ {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
{"ipaddress", 'I', POPT_ARG_STRING, 0,'I'},
{"port", 'p', POPT_ARG_INT, &c->opt_port},
{"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name},
{"server", 'S', POPT_ARG_STRING, &c->opt_host},
+ {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
{"container", 'c', POPT_ARG_STRING, &c->opt_container},
{"comment", 'C', POPT_ARG_STRING, &c->opt_comment},
{"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers},
{"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin},
{"timeout", 't', POPT_ARG_INT, &c->opt_timeout},
{"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout},
+ {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass},
+ {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos},
{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
{"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose},
{"test", 'T', POPT_ARG_NONE, &c->opt_testmode},
/* Options for 'net groupmap set' */
{"local", 'L', POPT_ARG_NONE, &c->opt_localgroup},
{"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup},
- {"ntname", 0, POPT_ARG_STRING, &c->opt_newntname},
+ {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname},
{"rid", 'R', POPT_ARG_INT, &c->opt_rid},
/* Options for 'net rpc share migrate' */
{"acls", 0, POPT_ARG_NONE, &c->opt_acls},
{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
{ 0, 0, 0, 0}
};
dbf = x_stderr;
c->private_data = net_func;
- c->auth_info = user_auth_info_init(frame);
- if (c->auth_info == NULL) {
- d_fprintf(stderr, "\nOut of memory!\n");
- exit(1);
- }
- popt_common_set_auth_info(c->auth_info);
-
pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
switch (opt) {
case 'h':
c->display_usage = true;
- set_cmdline_auth_info_password(c->auth_info, "");
+ break;
+ case 'e':
+ c->smb_encrypt = true;
break;
case 'I':
if (!interpret_string_addr(&c->opt_dest_ip,
c->opt_have_ip = true;
}
break;
+ case 'U':
+ c->opt_user_specified = true;
+ c->opt_user_name = SMB_STRDUP(c->opt_user_name);
+ p = strchr(c->opt_user_name,'%');
+ if (p) {
+ *p = 0;
+ c->opt_password = p+1;
+ }
+ break;
default:
d_fprintf(stderr, "\nInvalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
set_global_myname(c->opt_requester_name);
}
+ if (!c->opt_user_name && getenv("LOGNAME")) {
+ c->opt_user_name = getenv("LOGNAME");
+ }
+
if (!c->opt_workgroup) {
c->opt_workgroup = smb_xstrdup(lp_workgroup());
}
that it won't assert becouse we are not root */
sec_init();
+ if (c->opt_machine_pass) {
+ /* it is very useful to be able to make ads queries as the
+ machine account for testing purposes and for domain leave */
+
+ net_use_krb_machine_account(c);
+ }
+
+ if (!c->opt_password) {
+ c->opt_password = getenv("PASSWD");
+ }
+
rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
DEBUG(2,("return code = %d\n", rc));
+ gencache_stabilize();
+
libnetapi_free(c->netapi_ctx);
poptFreeContext(pc);
struct net_context {
const char *opt_requester_name;
const char *opt_host;
- int opt_long_list_entries;
+ const char *opt_password;
+ const char *opt_user_name;
+ bool opt_user_specified;
const char *opt_workgroup;
+ int opt_long_list_entries;
int opt_reboot;
int opt_force;
int opt_stdin;
int opt_timeout;
int opt_request_timeout;
const char *opt_target_workgroup;
+ int opt_machine_pass;
int opt_localgroup;
int opt_domaingroup;
int do_talloc_report;
const char *opt_exclude;
const char *opt_destination;
int opt_testmode;
+ bool opt_kerberos;
int opt_force_full_repl;
int opt_single_obj_repl;
int opt_clean_old_entries;
int opt_have_ip;
struct sockaddr_storage opt_dest_ip;
+ bool smb_encrypt;
struct libnetapi_ctx *netapi_ctx;
- struct user_auth_info *auth_info;
bool display_usage;
void *private_data;
ads = ads_init(realm, c->opt_target_workgroup, c->opt_host);
+ if (!c->opt_user_name) {
+ c->opt_user_name = "administrator";
+ }
+
+ if (c->opt_user_specified) {
+ need_password = true;
+ }
+
retry:
- if (need_password) {
- set_cmdline_auth_info_getpass(c->auth_info);
+ if (!c->opt_password && need_password && !c->opt_machine_pass) {
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
+ if (!c->opt_password) {
+ ads_destroy(&ads);
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
}
- if (get_cmdline_auth_info_got_pass(c->auth_info) ||
- !get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ if (c->opt_password) {
use_in_memory_ccache();
SAFE_FREE(ads->auth.password);
- ads->auth.password = smb_xstrdup(
- get_cmdline_auth_info_password(c->auth_info));
+ ads->auth.password = smb_xstrdup(c->opt_password);
}
ads->auth.flags |= auth_flags;
SAFE_FREE(ads->auth.user_name);
- ads->auth.user_name = smb_xstrdup(
- get_cmdline_auth_info_username(c->auth_info));
+ ads->auth.user_name = smb_xstrdup(c->opt_user_name);
/*
* If the username is of the form "name@realm",
return net_ads_user_usage(c, argc, argv);
}
- escaped_user = escape_ldap_string_alloc(argv[0]);
+ escaped_user = escape_ldap_string(talloc_tos(), argv[0]);
if (!escaped_user) {
d_fprintf(stderr, "ads_user_info: failed to escape user %s\n", argv[0]);
}
if (!ADS_ERR_OK(ads_startup(c, false, &ads))) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
if (asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user) == -1) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
rc = ads_search(ads, &res, searchstring, attrs);
if (!ADS_ERR_OK(rc)) {
d_fprintf(stderr, "ads_search: %s\n", ads_errstr(rc));
ads_destroy(&ads);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
ads_msgfree(ads, res);
ads_destroy(&ads);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return 0;
}
TALLOC_CTX *ctx;
struct libnet_UnjoinCtx *r = NULL;
WERROR werr;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
return -1;
}
- if (!get_cmdline_auth_info_use_kerberos(ai)) {
+ if (!c->opt_kerberos) {
use_in_memory_ccache();
}
return -1;
}
- set_cmdline_auth_info_getpass(ai);
-
r->in.debug = true;
- r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai);
+ r->in.use_kerberos = c->opt_kerberos;
r->in.dc_name = c->opt_host;
r->in.domain_name = lp_realm();
- r->in.admin_account = get_cmdline_auth_info_username(ai);
- r->in.admin_password = get_cmdline_auth_info_password(ai);
+ r->in.admin_account = c->opt_user_name;
+ r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
r->in.modify_config = lp_config_backend_is_registry();
/* Try to delete it, but if that fails, disable it. The
return NT_STATUS_ACCESS_DENIED;
}
- set_cmdline_auth_info_use_machine_account(c->auth_info);
- set_cmdline_auth_info_machine_account_creds(c->auth_info);
+ net_use_krb_machine_account(c);
status = ads_startup(c, true, &ads);
if (!ADS_ERR_OK(status)) {
const char *os_name = NULL;
const char *os_version = NULL;
bool modify_config = lp_config_backend_is_registry();
- struct user_auth_info *ai = c->auth_info;;
if (c->display_usage)
return net_ads_join_usage(c, argc, argv);
goto fail;
}
- if (!get_cmdline_auth_info_use_kerberos(ai)) {
+ if (!c->opt_kerberos) {
use_in_memory_ccache();
}
/* Do the domain join here */
- set_cmdline_auth_info_getpass(ai);
-
r->in.domain_name = domain;
r->in.create_upn = createupn;
r->in.upn = machineupn;
r->in.os_name = os_name;
r->in.os_version = os_version;
r->in.dc_name = c->opt_host;
- r->in.admin_account = get_cmdline_auth_info_username(ai);
- r->in.admin_password = get_cmdline_auth_info_password(ai);
+ r->in.admin_account = c->opt_user_name;
+ r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
r->in.debug = true;
- r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai);
+ r->in.use_kerberos = c->opt_kerberos;
r->in.modify_config = modify_config;
r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
char *prt_dn, *srv_dn, **srv_cn;
char *srv_cn_escaped = NULL, *printername_escaped = NULL;
LDAPMessage *res = NULL;
- struct user_auth_info *ai = c->auth_info;
if (argc < 1 || c->display_usage) {
d_printf("Usage:\n"
nt_status = cli_full_connection(&cli, global_myname(), servername,
&server_ss, 0,
"IPC$", "IPC",
- get_cmdline_auth_info_username(ai),
- c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name, c->opt_workgroup,
+ c->opt_password ? c->opt_password : "",
CLI_FULL_CONNECTION_USE_KERBEROS,
Undefined, NULL);
static int net_ads_password(struct net_context *c, int argc, const char **argv)
{
ADS_STRUCT *ads;
- const char *auth_principal;
- const char *auth_password;
+ const char *auth_principal = c->opt_user_name;
+ const char *auth_password = c->opt_password;
char *realm = NULL;
char *new_password = NULL;
char *chr, *prompt;
return 0;
}
- auth_principal = get_cmdline_auth_info_username(c->auth_info);
- set_cmdline_auth_info_getpass(c->auth_info);
- auth_password = get_cmdline_auth_info_password(c->auth_info);
+ if (c->opt_user_name == NULL || c->opt_password == NULL) {
+ d_fprintf(stderr, "You must supply an administrator username/password\n");
+ return -1;
+ }
if (argc < 1) {
d_fprintf(stderr, "ERROR: You must say which username to change password for\n");
return -1;
}
- set_cmdline_auth_info_use_machine_account(c->auth_info);
+ net_use_krb_machine_account(c);
use_in_memory_ccache();
TALLOC_CTX *mem_ctx = NULL;
NTSTATUS status;
int ret = -1;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
goto out;
}
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
status = kerberos_return_pac(mem_ctx,
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name,
+ c->opt_password,
0,
NULL,
NULL,
TALLOC_CTX *mem_ctx = NULL;
int ret = -1;
NTSTATUS status;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
goto out;
}
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
- ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ ret = kerberos_kinit_password_ext(c->opt_user_name,
+ c->opt_password,
0,
NULL,
NULL,
if (gencache_set(keystr, datastr, timeout)) {
d_printf("New cache entry stored successfully.\n");
- gencache_shutdown();
return 0;
}
d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n");
- gencache_shutdown();
return -1;
}
return 0;
}
gencache_iterate(print_cache_entry, NULL, pattern);
- gencache_shutdown();
return 0;
}
return 0;
}
gencache_iterate(delete_cache_entry, NULL, pattern);
- gencache_shutdown();
return 0;
}
+static int net_cache_stabilize(struct net_context *c, int argc,
+ const char **argv)
+{
+ if (c->display_usage) {
+ d_printf("Usage:\n"
+ "net cache flush\n"
+ " Delete all cache entries.\n");
+ return 0;
+ }
+
+ if (!gencache_stabilize()) {
+ return -1;
+ }
+ return 0;
+}
/**
* Entry point to 'net cache' subfunctionality
*
"net cache flush\n"
" Delete all cache entries"
},
+ {
+ "stabilize",
+ net_cache_stabilize,
+ NET_TRANSPORT_LOCAL,
+ "Move transient cache content to stable storage",
+ "net cache stabilize\n"
+ " Move transient cache content to stable storage"
+ },
{NULL, NULL, 0, NULL, NULL}
};
return -1;
}
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
}
c->display_usage = true;
- set_cmdline_auth_info_password(c->auth_info, "");
return net_run_function(c, argc, argv, "net help", func);
}
NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
struct rpc_pipe_client **pp_pipe_hnd,
const struct ndr_syntax_id *interface);
+int net_use_krb_machine_account(struct net_context *c);
+int net_use_machine_account(struct net_context *c);
bool net_find_server(struct net_context *c,
const char *domain,
unsigned flags,
const char *server,
struct sockaddr_storage *pss,
unsigned flags, struct cli_state **pcli);
+const char *net_prompt_pass(struct net_context *c, const char *user);
int net_run_function(struct net_context *c, int argc, const char **argv,
const char *whoami, struct functable *table);
void net_display_usage_from_functable(struct functable *table);
#include "../libcli/auth/libcli_auth.h"
static int net_mode_share;
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
- const struct user_auth_info *auth_info);
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
/**
* @file net_rpc.c
DOM_SID *domain_sid;
const char *domain_name;
int ret = -1;
- struct user_auth_info *ai = c->auth_info;
/* make use of cli_state handed over as an argument, if possible */
if (!cli_arg) {
nt_status = cli_rpc_pipe_open_ntlmssp(
cli, interface,
PIPE_AUTH_LEVEL_PRIVACY,
- lp_workgroup(),
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
- &pipe_hnd);
+ lp_workgroup(), c->opt_user_name,
+ c->opt_password, &pipe_hnd);
} else {
nt_status = cli_rpc_pipe_open_noauth(
cli, interface,
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
old_dir = local_state->cwd;
local_state->cwd = dir;
- if (!sync_files(local_state, new_mask, c->auth_info))
+ if (!sync_files(local_state, new_mask))
printf("could not handle files\n");
local_state->cwd = old_dir;
*
* @return Boolean result
**/
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
- const struct user_auth_info *auth_info)
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
{
struct cli_state *targetcli;
char *targetpath = NULL;
DEBUG(3,("calling cli_list with mask: %s\n", mask));
-
- if ( !cli_resolve_path(talloc_tos(), "", auth_info,
- cp_clistate->cli_share_src, mask, &targetcli,
- &targetpath ) ) {
+ if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
+ mask, &targetcli, &targetpath ) ) {
d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
mask, cli_errstr(cp_clistate->cli_share_src));
return false;
goto done;
}
- if (!sync_files(&cp_clistate, mask, c->auth_info)) {
+ if (!sync_files(&cp_clistate, mask)) {
d_fprintf(stderr, "could not handle files for share: %s\n", info502.name);
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
c->opt_workgroup = smb_xstrdup(domain_name);
};
- set_cmdline_auth_info_username(c->auth_info, acct_name);
+ c->opt_user_name = acct_name;
/* find the domain controller */
if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
* Store the password in secrets db
*/
- if (!pdb_set_trusteddom_pw(domain_name,
- get_cmdline_auth_info_password(c->auth_info),
- domain_sid)) {
+ if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
DEBUG(0, ("Storing password for trusted domain failed.\n"));
cli_shutdown(cli);
talloc_destroy(mem_ctx);
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
if (sec == SEC_ADS) {
/* Connect to IPC$ using machine account's credentials. We don't use anonymous
connection here, as it may be denied by server's local policy. */
- set_cmdline_auth_info_use_machine_account(c->auth_info);
- set_cmdline_auth_info_machine_account_creds(c->auth_info);
+ net_use_machine_account(c);
} else {
/* some servers (e.g. WinNT) don't accept machine-authenticated
ctx->cli = pipe_hnd;
ctx->ops = &libnet_samsync_keytab_ops;
ctx->domain_name = domain_name;
- ctx->username = get_cmdline_auth_info_username(c->auth_info);
- ctx->password = get_cmdline_auth_info_password(c->auth_info);
+ ctx->username = c->opt_user_name;
+ ctx->password = c->opt_password;
ctx->force_full_replication = c->opt_force_full_repl ? true : false;
ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
if (!dc_info.is_ad) {
printf("DC is not running Active Directory\n");
- return -1;
- }
-
- if (dc_info.is_mixed_mode) {
ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
0,
rpc_vampire_keytab_internals, argc, argv);
+ return -1;
} else {
ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id,
NET_FLAGS_SEAL,
rpc_vampire_keytab_ds_internals, argc, argv);
+ if (ret != 0 && dc_info.is_mixed_mode) {
+ printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n");
+ ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
+ 0,
+ rpc_vampire_keytab_internals, argc, argv);
+ }
}
return ret;
if (libnetapi_init(&c->netapi_ctx) != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
const char *account_policy = NULL;
uint32 value = 0;
uint32 old_value = 0;
- int field;
+ enum pdb_policy_type field;
char *endptr;
if (argc != 2 || c->display_usage) {
}
account_policy = argv[0];
- field = account_policy_name_to_fieldnum(account_policy);
+ field = account_policy_name_to_typenum(account_policy);
if (strequal(argv[1], "forever") || strequal(argv[1], "never")
|| strequal(argv[1], "off")) {
{
const char *account_policy = NULL;
uint32 old_value;
- int field;
+ enum pdb_policy_type field;
if (argc != 1 || c->display_usage) {
d_fprintf(stderr, "usage: net sam policy show"
}
account_policy = argv[0];
- field = account_policy_name_to_fieldnum(account_policy);
+ field = account_policy_name_to_typenum(account_policy);
if (field == 0) {
const char **names;
d_fprintf(stderr, "net usershare delete: share name %s contains "
"invalid characters (any of %s)\n",
sharename, INVALID_SHARENAME_CHARS);
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
lp_usershare_path(),
sharename);
if (!us_path) {
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare delete: unable to remove usershare %s. "
"Error was %s\n",
us_path, strerror(errno));
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return 0;
}
d_fprintf(stderr, "net usershare add: maximum number of allowed usershares (%d) reached\n",
lp_usershare_max_shares() );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
"invalid characters (any of %s)\n",
sharename, INVALID_SHARENAME_CHARS);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: share name %s is already a valid system user name\n",
sharename );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
full_path = get_basepath(ctx);
if (!full_path) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
full_path_tmp = talloc_asprintf(ctx,
full_path);
if (!full_path_tmp) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
sharename);
if (!full_path) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr,"net usershare add: path %s is not an absolute path.\n",
us_path);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
"this is a directory. Error was %s\n",
us_path, strerror(errno) );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: path %s is not a directory.\n",
us_path );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
"\tto the [global] section of the smb.conf to allow this.\n",
us_path );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: malformed acl %s (missing ':').\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
"(access control must be 'r', 'f', or 'd')\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: malformed terminating character for acl %s\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
if ((name = talloc_strndup(ctx, pacl, pcolon - pacl)) == NULL) {
d_fprintf(stderr, "talloc_strndup failed\n");
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
if (!string_to_sid(&sid, name)) {
d_fprintf(stderr, "\n");
}
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
}
"but the \"usershare allow guests\" parameter is not enabled "
"by this server.\n");
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: cannot create tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: cannot lstat tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: cannot fstat tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
d_fprintf(stderr, "net usershare add: failed to fchmod tmp file %s to 0644n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
(unsigned int)to_write, full_path_tmp, strerror(errno));
unlink(full_path_tmp);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
sharename, strerror(errno));
TALLOC_FREE(ctx);
close(tmpfd);
- SAFE_FREE(sharename);
return -1;
}
net_usershare_info(c, 1, my_argv);
}
- SAFE_FREE(sharename);
TALLOC_FREE(ctx);
return 0;
}
pi.ctx = ctx;
pi.op = US_LIST_OP;
+ pi.c = c;
ret = process_share_list(info_fn, &pi);
talloc_destroy(ctx);
{
NTSTATUS nt_status;
int flags = 0;
- struct user_auth_info *ai = c->auth_info;
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
- if (get_cmdline_auth_info_use_kerberos(ai)) {
- flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
- CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+ if (c->opt_kerberos) {
+ flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+ }
+
+ if (c->opt_kerberos && c->opt_password) {
+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
}
nt_status = cli_full_connection(cli_ctx, NULL, server_name,
server_ss, c->opt_port,
service_name, service_type,
- get_cmdline_auth_info_username(ai),
- c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
- flags, Undefined, NULL);
+ c->opt_user_name, c->opt_workgroup,
+ c->opt_password, flags, Undefined, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
d_fprintf(stderr, "Could not connect to server %s\n", server_name);
return nt_status;
}
- if (get_cmdline_auth_info_smb_encrypt(ai)) {
+ if (c->smb_encrypt) {
nt_status = cli_force_encryption(*cli_ctx,
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name,
+ c->opt_password,
c->opt_workgroup);
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
{
NTSTATUS nt_status;
char *user_and_realm = NULL;
- struct user_auth_info *ai = c->auth_info;
/* FIXME: Should get existing kerberos ticket if possible. */
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
+ if (!c->opt_password) {
+ return NT_STATUS_NO_MEMORY;
+ }
- user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai));
+ user_and_realm = get_user_and_realm(c->opt_user_name);
if (!user_and_realm) {
return NT_STATUS_NO_MEMORY;
}
server_ss, c->opt_port,
"IPC$", "IPC",
user_and_realm, c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
+ c->opt_password,
CLI_FULL_CONNECTION_USE_KERBEROS,
Undefined, NULL);
return nt_status;
}
- if (get_cmdline_auth_info_smb_encrypt(ai)) {
+ if (c->smb_encrypt) {
nt_status = cli_cm_force_encryption(*cli_ctx,
user_and_realm,
- get_cmdline_auth_info_password(ai),
+ c->opt_password,
c->opt_workgroup,
"IPC$");
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
+/****************************************************************************
+ Use the local machine account (krb) and password for this session.
+****************************************************************************/
+
+int net_use_krb_machine_account(struct net_context *c)
+{
+ char *user_name = NULL;
+
+ if (!secrets_init()) {
+ d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ c->opt_password = secrets_fetch_machine_password(
+ c->opt_target_workgroup, NULL, NULL);
+ if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
+ return -1;
+ }
+ c->opt_user_name = user_name;
+ return 0;
+}
+
+/****************************************************************************
+ Use the machine account name and password for this session.
+****************************************************************************/
+
+int net_use_machine_account(struct net_context *c)
+{
+ char *user_name = NULL;
+
+ if (!secrets_init()) {
+ d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ c->opt_password = secrets_fetch_machine_password(
+ c->opt_target_workgroup, NULL, NULL);
+ if (asprintf(&user_name, "%s$", global_myname()) == -1) {
+ return -1;
+ }
+ c->opt_user_name = user_name;
+ return 0;
+}
+
bool net_find_server(struct net_context *c,
const char *domain,
unsigned flags,
/****************************************************************************
****************************************************************************/
+const char *net_prompt_pass(struct net_context *c, const char *user)
+{
+ char *prompt = NULL;
+ const char *pass = NULL;
+
+ if (c->opt_password) {
+ return c->opt_password;
+ }
+
+ if (c->opt_machine_pass) {
+ return NULL;
+ }
+
+ if (c->opt_kerberos && !c->opt_user_specified) {
+ return NULL;
+ }
+
+ if (asprintf(&prompt, "Enter %s's password:", user) == -1) {
+ return NULL;
+ }
+
+ pass = getpass(prompt);
+ SAFE_FREE(prompt);
+
+ return pass;
+}
+
int net_run_function(struct net_context *c, int argc, const char **argv,
const char *whoami, struct functable *table)
{
/* account policy operations */
if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
uint32 value;
- int field = account_policy_name_to_fieldnum(account_policy);
+ enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
if (field == 0) {
const char **names;
int count;
trustdom_cache_shutdown();
+ gencache_stabilize();
+
#if 0
if (interactive) {
TALLOC_CTX *mem_ctx = talloc_init("end_description");
gid_t primary_gid = (gid_t)-1;
if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
- ads_atype_map(atype) != SID_NAME_USER) {
+ ds_atype_map(atype) != SID_NAME_USER) {
DEBUG(1,("Not a user account? atype=0x%x\n", atype));
continue;
}
goto done;
}
- if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) {
+ if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
GROUP_TYPE_SECURITY_ENABLED);
if (!ldap_exp) {
DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
- SAFE_FREE(escaped_dn);
+ TALLOC_FREE(escaped_dn);
status = NT_STATUS_NO_MEMORY;
goto done;
}
- SAFE_FREE(escaped_dn);
+ TALLOC_FREE(escaped_dn);
rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
if (tevent_req_is_unix_error(req, err)) {
return -1;
}
- if (state->response->result != WINBINDD_OK) {
- *err = EIO; /* EIO doesn't fit, but what would be better? */
- return -1;
- }
*presponse = talloc_move(mem_ctx, &state->response);
return 0;
}
return NT_STATUS_NO_MEMORY;
}
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
p->min_password_length = account_policy_temp;
- if (!pdb_get_account_policy(AP_PASSWORD_HISTORY,
+ if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
&account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
p->password_history_length = account_policy_temp;
- if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&p->password_properties)) {
return NT_STATUS_ACCESS_DENIED;
}
- if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
+ if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
u_expire = account_policy_temp;
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
u_min_age = account_policy_temp;
*p = 0;
name_domain = state->request->data.name.name;
name_user = p+1;
+ } else if ((p = strchr(state->request->data.name.name, '@')) != NULL) {
+ /* upn */
+ name_domain = p + 1;
+ *p = 0;
+ name_user = state->request->data.name.name;
} else {
name_domain = state->request->data.name.dom_name;
name_user = state->request->data.name.name;
if ( assume_domain(lp_workgroup())) {
fstrcpy(domain, lp_workgroup());
} else if ((p = strchr(domuser, '@')) != NULL) {
- fstrcpy(domain, "");
+ fstrcpy(domain, p + 1);
+ user[PTR_DIFF(p, domuser)] = 0;
} else {
return False;
}
#include "librpc/gen_ndr/ndr_krb5pac.h"
+extern const char *krbtgt_attrs[];
+extern const char *server_attrs[];
extern const char *user_attrs[];
union netr_Validation;
krb5_keyblock *keyblock;
krb5_ticket *ticket;
bool gssapi;
+ krb5_flags ap_req_options;
};
static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state)
return 0;
}
-static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security, bool gssapi)
{
krb5_error_code ret;
struct gensec_krb5_state *gensec_krb5_state;
gensec_krb5_state->keyblock = NULL;
gensec_krb5_state->session_key = data_blob(NULL, 0);
gensec_krb5_state->pac = data_blob(NULL, 0);
- gensec_krb5_state->gssapi = false;
+ gensec_krb5_state->gssapi = gssapi;
talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy);
return NT_STATUS_OK;
}
-static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_server_start(struct gensec_security *gensec_security, bool gssapi)
{
NTSTATUS nt_status;
struct gensec_krb5_state *gensec_krb5_state;
- nt_status = gensec_krb5_start(gensec_security);
+ nt_status = gensec_krb5_start(gensec_security, gssapi);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
return NT_STATUS_OK;
}
-static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
{
- NTSTATUS nt_status = gensec_krb5_server_start(gensec_security);
+ return gensec_krb5_common_server_start(gensec_security, false);
+}
- if (NT_STATUS_IS_OK(nt_status)) {
- struct gensec_krb5_state *gensec_krb5_state;
- gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
- gensec_krb5_state->gssapi = true;
- }
- return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+{
+ return gensec_krb5_common_server_start(gensec_security, true);
}
-static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi)
{
struct gensec_krb5_state *gensec_krb5_state;
krb5_error_code ret;
NTSTATUS nt_status;
struct ccache_container *ccache_container;
const char *hostname;
- krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED;
const char *principal;
krb5_data in_data;
return NT_STATUS_INVALID_PARAMETER;
}
- nt_status = gensec_krb5_start(gensec_security);
+ nt_status = gensec_krb5_start(gensec_security, gssapi);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START;
+ gensec_krb5_state->ap_req_options = AP_OPTS_USE_SUBKEY;
+
+ if (gensec_krb5_state->gssapi) {
+ /* The Fake GSSAPI modal emulates Samba3, which does not do mutual authentication */
+ if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) {
+ gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ } else {
+ /* The wrapping for KPASSWD (a user of the raw KRB5 API) should be mutually authenticated */
+ if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) {
+ gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ }
principal = gensec_get_target_principal(gensec_security);
if (ret == 0) {
ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context,
&gensec_krb5_state->auth_context,
- ap_req_options,
+ gensec_krb5_state->ap_req_options,
target_principal,
&in_data, ccache_container->ccache,
&gensec_krb5_state->enc_ticket);
} else {
ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
&gensec_krb5_state->auth_context,
- ap_req_options,
+ gensec_krb5_state->ap_req_options,
gensec_get_target_service(gensec_security),
hostname,
&in_data, ccache_container->ccache,
}
}
-static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
{
- NTSTATUS nt_status = gensec_krb5_client_start(gensec_security);
+ return gensec_krb5_common_client_start(gensec_security, false);
+}
- if (NT_STATUS_IS_OK(nt_status)) {
- struct gensec_krb5_state *gensec_krb5_state;
- gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
- gensec_krb5_state->gssapi = true;
- }
- return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+{
+ return gensec_krb5_common_client_start(gensec_security, true);
}
/**
} else {
*out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length);
}
- gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
- nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ if (gensec_krb5_state->ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
+ gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
+ nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ } else {
+ gensec_krb5_state->state_position = GENSEC_KRB5_DONE;
+ nt_status = NT_STATUS_OK;
+ }
return nt_status;
}
#include "param/param.h"
#include "auth/auth_sam.h"
-const char *user_attrs[] = {
- /* required for the krb5 kdc */
- "objectClass",
- "sAMAccountName",
- "userPrincipalName",
- "servicePrincipalName",
- "msDS-KeyVersionNumber",
- "supplementalCredentials",
+#define KRBTGT_ATTRS \
+ /* required for the krb5 kdc */ \
+ "objectClass", \
+ "sAMAccountName", \
+ "userPrincipalName", \
+ "servicePrincipalName", \
+ "msDS-KeyVersionNumber", \
+ "supplementalCredentials", \
+ \
+ /* passwords */ \
+ "dBCSPwd", \
+ "unicodePwd", \
+ \
+ "userAccountControl", \
+ "objectSid", \
+ \
+ "pwdLastSet", \
+ "accountExpires"
+
+const char *krbtgt_attrs[] = {
+ KRBTGT_ATTRS
+};
- /* passwords */
- "dBCSPwd",
- "unicodePwd",
+const char *server_attrs[] = {
+ KRBTGT_ATTRS
+};
- "userAccountControl",
+const char *user_attrs[] = {
+ KRBTGT_ATTRS,
- "pwdLastSet",
- "accountExpires",
"logonHours",
- "objectSid",
/* check 'allowed workstations' */
"userWorkstations",
"(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
"(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))",
ldb_binary_encode_string(mem_ctx, user),
- UF_ACCOUNTDISABLE, samdb_acb2uf(acct_control));
+ UF_ACCOUNTDISABLE, ds_acb2uf(acct_control));
if (ret != LDB_SUCCESS) {
DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n",
user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
AC_CONFIG_FILES(lib/registry/registry.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
+AC_CONFIG_FILES(../librpc/ndr_standard.pc)
AC_CONFIG_FILES(../lib/torture/torture.pc)
AC_CONFIG_FILES(auth/gensec/gensec.pc)
AC_CONFIG_FILES(param/samba-hostconfig.pc)
#include "includes.h"
#include "system/passwd.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
#include "libcli/ldap/ldap_ndr.h"
struct passwd *pwd;
uid_t uid = rid - SIDMAP_LOCAL_USER_BASE;
atype = ATYPE_NORMAL_ACCOUNT;
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
pwd = getpwuid(uid);
if (pwd == NULL) {
struct group *grp;
gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE;
atype = ATYPE_LOCAL_GROUP;
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
grp = getgrgid(gid);
if (grp == NULL) {
*name = talloc_asprintf(mem_ctx, "gid%u", gid);
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/common/proto.h"
#include "libcli/ldap/ldap_ndr.h"
#include "param/param.h"
struct ldb_message *msg, struct ldb_dn *domain_dn)
{
uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
- uint32_t acct_flags = samdb_uf2acb(userAccountControl);
+ uint32_t acct_flags = ds_uf2acb(userAccountControl);
NTTIME must_change_time;
NTTIME now;
int samdb_msg_add_acct_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
const char *attr_name, uint32_t v)
{
- return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, samdb_acb2uf(v));
+ return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, ds_acb2uf(v));
}
/*
SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \
sidmap.o \
- flag_mapping.o \
- util.o)
+ util.o) \
+ ../libds/common/flag_mapping.o
$(eval $(call proto_header_template,$(dsdbsrcdir)/common/proto.h,$(SAMDB_COMMON_OBJ_FILES:.o=.c)))
[SUBSYSTEM::SAMDB_SCHEMA]
#include "ldb_module.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
struct it_context {
struct ldb_module *module;
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
- break;
- case LDB_RENAME:
-
+ return ret;
+
+ case LDB_RENAME:
+ /* start the mod requests chain */
ret = la_do_mod_request(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL,
ret);
- }
-
+ }
return ret;
default:
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- return LDB_SUCCESS;
}
talloc_free(ares);
#include "auth/kerberos/kerberos.h"
#include "system/time.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/ldb_modules/password_modules.h"
#include "librpc/ndr/libndr.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
uint8_t zero16[16];
bool do_newer_keys = false;
bool do_cleartext = false;
+ int *domainFunctionality;
ZERO_STRUCT(zero16);
ZERO_STRUCT(names);
_old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
}
}
+ /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
+ domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
- /* TODO: do the correct check for this, it maybe depends on the functional level? */
- do_newer_keys = lp_parm_bool(ldb_get_opaque(ldb, "loadparm"),
- NULL, "password_hash", "create_aes_key", false);
+ do_newer_keys = *domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008);
if (io->domain->store_cleartext &&
(io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
}
ret = setup_kerberos_keys(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
}
ret = setup_nt_fields(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_lm_fields(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_supplemental_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_last_set_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_kvno_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
+ break;
case LDB_REPLY_REFERRAL:
/* ignore */
#include "includes.h"
#include "ldb_module.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data);
char **server_sasl;
const struct dsdb_schema *schema;
+ int *val;
ldb = ldb_module_get_ctx(module);
schema = dsdb_get_schema(ldb);
}
}
- if (do_attribute(attrs, "supportedControl")) {
+ if (priv && do_attribute(attrs, "supportedControl")) {
int i;
for (i = 0; i < priv->num_controls; i++) {
char *control = talloc_strdup(msg, priv->controls[i]);
}
}
- if (do_attribute(attrs, "namingContexts")) {
+ if (priv && do_attribute(attrs, "namingContexts")) {
int i;
for (i = 0; i < priv->num_partitions; i++) {
struct ldb_dn *dn = priv->partitions[i];
}
}
- if (schema && do_attribute_explicit(attrs, "vendorVersion")) {
+ if (do_attribute_explicit(attrs, "vendorVersion")) {
if (ldb_msg_add_fmt(msg, "vendorVersion",
"%s", SAMBA_VERSION_STRING) != 0) {
goto failed;
}
}
+ if (priv && do_attribute(attrs, "domainFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "domainFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
+ if (priv && do_attribute(attrs, "forestFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "forestFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "forestFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
+ if (priv && do_attribute(attrs, "domainControllerFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "domainControllerFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "domainControllerFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
/* TODO: lots more dynamic attributes should be added here */
return LDB_SUCCESS;
static int rootdse_init(struct ldb_module *module)
{
+ int ret;
struct ldb_context *ldb;
+ struct ldb_result *res;
struct private_data *data;
+ const char *attrs[] = { "msDS-Behavior-Version", NULL };
+ const char *ds_attrs[] = { "dsServiceName", NULL };
+ TALLOC_CTX *mem_ctx;
ldb = ldb_module_get_ctx(module);
- data = talloc(module, struct private_data);
+ data = talloc_zero(module, struct private_data);
if (data == NULL) {
return -1;
}
ldb_set_default_dns(ldb);
- return ldb_next_init(module);
+ ret = ldb_next_init(module);
+
+ if (ret) {
+ return ret;
+ }
+
+ mem_ctx = talloc_new(data);
+ if (!mem_ctx) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* Now that the partitions are set up, do a search for:
+ - domainControllerFunctionality
+ - domainFunctionality
+ - forestFunctionality
+
+ Then stuff these values into an opaque
+ */
+ ret = ldb_search(ldb, mem_ctx, &res,
+ ldb_get_default_basedn(ldb),
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int domain_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (domain_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = domain_behaviour_version;
+ ret = ldb_set_opaque(ldb, "domainFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+
+ ret = ldb_search(ldb, mem_ctx, &res,
+ samdb_partitions_dn(ldb, mem_ctx),
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int forest_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (forest_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = forest_behaviour_version;
+ ret = ldb_set_opaque(ldb, "forestFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+
+ ret = ldb_search(ldb, mem_ctx, &res,
+ ldb_dn_new(mem_ctx, ldb, ""),
+ LDB_SCOPE_BASE, ds_attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ struct ldb_dn *ds_dn
+ = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0],
+ "dsServiceName");
+ if (ds_dn) {
+ ret = ldb_search(ldb, mem_ctx, &res, ds_dn,
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int domain_controller_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (domain_controller_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = domain_controller_behaviour_version;
+ ret = ldb_set_opaque(ldb,
+ "domainControllerFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+ }
+ }
+
+ talloc_free(mem_ctx);
+
+ return LDB_SUCCESS;
}
static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
"userAccountControl invalid");
return LDB_ERR_UNWILLING_TO_PERFORM;
} else {
- account_type = samdb_uf2atype(uac);
+ account_type = ds_uf2atype(uac);
ret = samdb_msg_add_uint(ldb,
ac->msg, ac->msg,
"sAMAccountType",
"groupType invalid");
return LDB_ERR_UNWILLING_TO_PERFORM;
} else {
- account_type = samdb_gtype2atype(group_type);
+ account_type = ds_gtype2atype(group_type);
ret = samdb_msg_add_uint(ldb,
ac->msg, ac->msg,
"sAMAccountType",
req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
group_type = strtoul((const char *)el->values[0].data, NULL, 0);
- account_type = samdb_gtype2atype(group_type);
+ account_type = ds_gtype2atype(group_type);
ret = samdb_msg_add_uint(ldb, msg, msg,
"sAMAccountType",
account_type);
req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
user_account_control = strtoul((const char *)el->values[0].data, NULL, 0);
- account_type = samdb_uf2atype(user_account_control);
+ account_type = ds_uf2atype(user_account_control);
ret = samdb_msg_add_uint(ldb, msg, msg,
"sAMAccountType",
account_type);
#include "ldb_wrap.h"
#include "../lib/util/util_ldb.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "param/param.h"
#include "lib/events/events.h"
#include "auth/credentials/credentials.h"
#include "dsdb/schema/schema.h"
#include "dsdb/samdb/samdb_proto.h"
#include "dsdb/common/proto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2"
struct dsdb_control_current_partition {
goto out;
}
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- TRUE);
+ ret = kdc_check_flags (context, config,
+ client_entry, client_name,
+ server_entry, server_name,
+ TRUE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
goto out;
goto out;
}
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- FALSE);
+ ret = kdc_check_flags (context, config,
+ client_entry, client_name,
+ server_entry, server_name,
+ FALSE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
goto out;
hdb_entry *client = &client_ex->entry;
/* check client */
+ if (client->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client (%s) is locked out", client_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
if (client->flags.invalid) {
kdc_log(context, config, 0,
"Client (%s) has invalid bit set", client_name);
if (server_ex != NULL) {
hdb_entry *server = &server_ex->entry;
+ if (server->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client server locked out -- %s", server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
if (server->flags.invalid) {
kdc_log(context, config, 0,
"Server has invalid flag set -- %s", server_name);
AS_REP rep;
KDCOptions f = b->kdc_options;
hdb_entry_ex *client = NULL, *server = NULL;
+ HDB *clientdb;
krb5_enctype cetype, setype, sessionetype;
krb5_data e_data;
EncTicketPart et;
*/
ret = _kdc_db_fetch(context, config, client_princ,
- HDB_F_GET_CLIENT | flags, NULL, &client);
+ HDB_F_GET_CLIENT | flags, &clientdb, &client);
if(ret){
kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
krb5_get_err_text(context, ret));
"No client key matching pa-data (%s) -- %s",
estr, client_name);
free(estr);
-
free_EncryptedData(&enc_data);
+
continue;
}
e_text = "Failed to decrypt PA-DATA";
free_EncryptedData(&enc_data);
+
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD);
+
ret = KRB5KDC_ERR_PREAUTH_FAILED;
continue;
}
goto out;
}
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client,
+ HDB_AUTH_SUCCESS);
+
/*
* Verify flags after the user been required to prove its identity
* with in a preauth mech.
static krb5_error_code
check_constrained_delegation(krb5_context context,
krb5_kdc_configuration *config,
+ HDB *clientdb,
hdb_entry_ex *client,
krb5_const_principal server)
{
krb5_error_code ret;
int i;
- ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
- if (ret) {
- krb5_clear_error_message(context);
- return ret;
- }
+ /* if client delegates to itself, that ok */
+ if (krb5_principal_compare(context, client->entry.principal, server) == TRUE)
+ return 0;
- if (acl) {
- for (i = 0; i < acl->len; i++) {
- if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
- return 0;
+ if (clientdb->hdb_check_constrained_delegation) {
+ ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, server);
+ if (ret == 0)
+ return 0;
+ } else {
+ ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
+ if (ret) {
+ krb5_clear_error_message(context);
+ return ret;
+ }
+
+ if (acl) {
+ for (i = 0; i < acl->len; i++) {
+ if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
+ return 0;
+ }
}
+ ret = KRB5KDC_ERR_BADOPTION;
}
kdc_log(context, config, 0,
"Bad request for constrained delegation");
- return KRB5KDC_ERR_BADOPTION;
+ return ret;
}
/*
et.flags.hw_authent = tgt->flags.hw_authent;
et.flags.anonymous = tgt->flags.anonymous;
et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
+
+ if(rspac->length) {
+ /*
+ * No not need to filter out the any PAC from the
+ * auth_data since it's signed by the KDC.
+ */
+ ret = _kdc_tkt_add_if_relevant_ad(context, &et,
+ KRB5_AUTHDATA_WIN2K_PAC, rspac);
+ if (ret)
+ goto out;
+ }
if (auth_data) {
- /* XXX Check enc-authorization-data */
- et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+ unsigned int i = 0;
+
+ /* XXX check authdata */
if (et.authorization_data == NULL) {
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
- ret = copy_AuthorizationData(auth_data, et.authorization_data);
- if (ret)
- goto out;
+ for(i = 0; i < auth_data->len ; i++) {
+ ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
+ if (ret) {
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ goto out;
+ }
+ }
/* Filter out type KRB5SignedPath */
ret = find_KRB5SignedPath(context, et.authorization_data, NULL);
}
}
- if(rspac->length) {
- /*
- * No not need to filter out the any PAC from the
- * auth_data since it's signed by the KDC.
- */
- ret = _kdc_tkt_add_if_relevant_ad(context, &et,
- KRB5_AUTHDATA_WIN2K_PAC,
- rspac);
- if (ret)
- goto out;
- }
-
ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key);
if (ret)
goto out;
krb5_principal client_principal = NULL;
char *spn = NULL, *cpn = NULL;
hdb_entry_ex *server = NULL, *client = NULL;
+ HDB *clientdb;
krb5_realm ref_realm = NULL;
EncTicketPart *tgt = &ticket->ticket;
krb5_principals spp = NULL;
}
ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
- NULL, &client);
+ &clientdb, &client);
if(ret) {
const char *krbtgt_realm;
if (ret) {
kdc_log(context, config, 0,
"failed to decrypt ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
+ "constrained delegation from %s to %s ", cpn, spn);
goto out;
}
if (adtkt.flags.forwardable == 0) {
kdc_log(context, config, 0,
"Missing forwardable flag on ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
+ "constrained delegation from %s to %s ", cpn, spn);
ret = KRB5KDC_ERR_BADOPTION;
goto out;
}
- ret = check_constrained_delegation(context, config, client, sp);
+ ret = check_constrained_delegation(context, config, clientdb,
+ client, sp);
if (ret) {
kdc_log(context, config, 0,
"constrained delegation from %s to %s not allowed",
- spn, cpn);
+ cpn, spn);
goto out;
}
#endif
#ifndef GSSAPI_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define GSSAPI_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#define GSSAPI_DEPRECATED __declspec(deprecated)
+#else
+#define GSSAPI_DEPRECATED
+#endif
#endif
/*
gss_buffer_t prf_out
);
-/*
- * AEAD support
- */
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_wrap_iov(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int /* conf_req_flag */,
- gss_qop_t /* qop_req */,
- int * /* conf_state */,
- gss_iov_buffer_desc * /*iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_unwrap_iov(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int * /* conf_state */,
- gss_qop_t * /* qop_state */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_wrap_iov_length(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int /* conf_req_flag */,
- gss_qop_t /* qop_req */,
- int * /* conf_state */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_release_iov_buffer(OM_uint32 * /* minor_status */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-
OM_uint32
gss_store_cred(OM_uint32 * /* minor_status */,
gss_cred_id_t /* input_cred_handle */,
+/*
+ * AEAD support
+ */
+
+/*
+ * GSS_IOV
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *,
+ gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
+
+
#ifdef __cplusplus
}
#endif
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
krb5_error_code
_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
{
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
krb5_keytab _gsskrb5_keytab;
}
/*
- * Samba style get some flags (but not DCE-STYLE)
+ * Samba style get some flags (but not DCE-STYLE), use
+ * ap_options to guess the mutual flag.
*/
- ctx->flags =
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
+ ctx->flags |= GSS_C_MUTUAL_FLAG;
}
}
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
__gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
krb5_context context,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_add_cred (
OM_uint32 *minor_status,
const gss_cred_id_t input_cred_handle,
#include <roken.h>
-static OM_uint32
-iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count)
-{
- unsigned int i;
-
- for (i = 0; i < iov_count; i++) {
- if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){
- void *ptr = malloc(iov[i].buffer.length);
- if (ptr == NULL)
- abort();
- if (iov[i].buffer.value)
- memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length);
- iov[i].buffer.value = ptr;
- iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
- }
- }
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-iov_map(OM_uint32 *minor_status,
- const gss_iov_buffer_desc *iov,
- int iov_count,
- krb5_crypto_iov *data)
-{
- unsigned int i;
-
- for (i = 0; i < iov_count; i++) {
- switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
- case GSS_IOV_BUFFER_TYPE_EMPTY:
- data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
- break;
- case GSS_IOV_BUFFER_TYPE_DATA:
- data[i].flags = KRB5_CRYPTO_TYPE_DATA;
- break;
- case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
- data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
- break;
- case GSS_IOV_BUFFER_TYPE_HEADER:
- data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
- break;
- case GSS_IOV_BUFFER_TYPE_TRAILER:
- data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
- break;
- case GSS_IOV_BUFFER_TYPE_PADDING:
- data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
- break;
- case GSS_IOV_BUFFER_TYPE_STREAM:
- abort();
- break;
- default:
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
- data[i].data.data = iov[i].buffer.value;
- data[i].data.length = iov[i].buffer.length;
- }
- return GSS_S_COMPLETE;
-}
-
OM_uint32 GSSAPI_LIB_FUNCTION
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
- krb5_context context;
- OM_uint32 major_status, junk;
- krb5_crypto_iov *data;
- krb5_error_code ret;
- unsigned usage;
-
- GSSAPI_KRB5_INIT (&context);
-
- major_status = iov_allocate(minor_status, iov, iov_count);
- if (major_status != GSS_S_COMPLETE)
- return major_status;
-
- data = calloc(iov_count, sizeof(data[0]));
- if (data == NULL) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- major_status = iov_map(minor_status, iov, iov_count, data);
- if (major_status != GSS_S_COMPLETE) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- free(data);
- return major_status;
- }
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
- if (ctx->more_flags & LOCAL) {
- usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
- } else {
- usage = KRB5_KU_USAGE_INITIATOR_SIGN;
- }
+ GSSAPI_KRB5_INIT (&context);
- ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage,
- data, iov_count, NULL);
- free(data);
- if (ret) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
+ conf_req_flag, conf_state,
+ iov, iov_count);
- *minor_status = 0;
- return GSS_S_COMPLETE;
+ return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
- krb5_error_code ret;
- OM_uint32 major_status, junk;
- krb5_crypto_iov *data;
- unsigned usage;
GSSAPI_KRB5_INIT (&context);
-
- major_status = iov_allocate(minor_status, iov, iov_count);
- if (major_status != GSS_S_COMPLETE)
- return major_status;
-
- data = calloc(iov_count, sizeof(data[0]));
- if (data == NULL) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- major_status = iov_map(minor_status, iov, iov_count, data);
- if (major_status != GSS_S_COMPLETE) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- free(data);
- return major_status;
- }
-
- if (ctx->more_flags & LOCAL) {
- usage = KRB5_KU_USAGE_INITIATOR_SIGN;
- } else {
- usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
- }
-
- ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage,
- data, iov_count, NULL);
- free(data);
- if (ret) {
- *minor_status = ret;
- gss_release_iov_buffer(&junk, iov, iov_count);
- return GSS_S_FAILURE;
- }
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
+ conf_state, qop_state, iov, iov_count);
+
+ return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
- unsigned int i;
- size_t size;
- size_t *padding = NULL;
-
+
GSSAPI_KRB5_INIT (&context);
- *minor_status = 0;
-
- for (size = 0, i = 0; i < iov_count; i++) {
- switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
- case GSS_IOV_BUFFER_TYPE_EMPTY:
- break;
- case GSS_IOV_BUFFER_TYPE_DATA:
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_HEADER:
- iov[i].buffer.length =
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER);
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_TRAILER:
- iov[i].buffer.length =
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER);
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_PADDING:
- if (padding != NULL) {
- *minor_status = 0;
- return GSS_S_FAILURE;
- }
- padding = &iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_STREAM:
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
- break;
- default:
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
- }
- if (padding) {
- size_t pad = krb5_crypto_length(context, ctx->crypto,
- KRB5_CRYPTO_TYPE_PADDING);
- if (pad > 1) {
- *padding = pad - (size % pad);
- if (*padding == pad)
- *padding = 0;
- } else
- *padding = 0;
- }
-
- return GSS_S_COMPLETE;
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+
+ return GSS_S_FAILURE;
}
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
*
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_canonicalize_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
- * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
+ * Implementation of RFC 4121
*/
#define CFXSentByAcceptor (1 << 0)
return 0;
}
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx ctx,
- krb5_context context,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_output_size,
- OM_uint32 *max_input_size)
+OM_uint32
+_gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
{
krb5_error_code ret;
return 0;
}
+gss_iov_buffer_desc *
+_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
+{
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (type == GSS_IOV_BUFFER_TYPE(iov[i].type))
+ return &iov[i];
+ return NULL;
+}
+
+static OM_uint32
+allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
+{
+ if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) {
+ if (buffer->buffer.length == size)
+ return GSS_S_COMPLETE;
+ free(buffer->buffer.value);
+ }
+
+ buffer->buffer.value = malloc(size);
+ buffer->buffer.length = size;
+ if (buffer->buffer.value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ buffer->type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+OM_uint32
+_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 major_status, junk;
+ gss_iov_buffer_desc *header, *trailer, *padding;
+ size_t gsshsize, k5hsize;
+ size_t gsstsize, k5tsize;
+ size_t i, padlength, rrc = 0, ec = 0;
+ gss_cfx_wrap_token token;
+ krb5_error_code ret;
+ int32_t seq_number;
+ unsigned usage;
+ krb5_crypto_iov *data = NULL;
+ int paddingoffset = 0;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength);
+
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ if (padlength != 0 && padding == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ if (conf_req_flag) {
+ ec = padlength;
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+
+ gsshsize = k5hsize + sizeof(*token);
+ gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */
+
+ } else {
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize);
+
+ gsshsize = sizeof(*token);
+ gsstsize = k5tsize;
+ }
+
+ /*
+ *
+ */
+
+ if (trailer == NULL) {
+ /* conf_req_flag=0 doesn't support DCE_STYLE */
+ if (conf_req_flag == 0) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+ rrc = gsstsize;
+ if (IS_DCE_STYLE(ctx))
+ rrc -= ec;
+ gsshsize += gsstsize;
+ gsstsize = 0;
+ } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = allocate_buffer(minor_status, trailer, gsstsize);
+ if (major_status)
+ goto failure;
+ } else if (trailer->buffer.length < gsstsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ trailer->buffer.length = gsstsize;
+
+ /*
+ *
+ */
+
+ if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = allocate_buffer(minor_status, header, gsshsize);
+ if (major_status != GSS_S_COMPLETE)
+ goto failure;
+ } else if (header->buffer.length < gsshsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ header->buffer.length = gsshsize;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ token->TOK_ID[0] = 0x05;
+ token->TOK_ID[1] = 0x04;
+ token->Flags = 0;
+ token->Filler = 0xFF;
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
+ token->Flags |= CFXAcceptorSubkey;
+
+ if (ctx->more_flags & LOCAL)
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ else
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+
+ if (conf_req_flag) {
+ /*
+ * In Wrap tokens with confidentiality, the EC field is
+ * used to encode the size (in bytes) of the random filler.
+ */
+ token->Flags |= CFXSealed;
+ token->EC[0] = (padlength >> 8) & 0xFF;
+ token->EC[1] = (padlength >> 0) & 0xFF;
+
+ } else {
+ /*
+ * In Wrap tokens without confidentiality, the EC field is
+ * used to encode the size (in bytes) of the trailing
+ * checksum.
+ *
+ * This is not used in the checksum calcuation itself,
+ * because the checksum length could potentially vary
+ * depending on the data length.
+ */
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ }
+
+ /*
+ * In Wrap tokens that provide for confidentiality, the RRC
+ * field in the header contains the hex value 00 00 before
+ * encryption.
+ *
+ * In Wrap tokens that do not provide for confidentiality,
+ * both the EC and RRC fields in the appended checksum
+ * contain the hex value 00 00 for the purpose of calculating
+ * the checksum.
+ */
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (conf_req_flag) {
+ /*
+ plain packet:
+
+ {"header" | encrypt(plaintext-data | padding | E"header")}
+
+ Expanded, this is with with RRC = 0:
+
+ {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer }
+
+ In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer)
+
+ {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
+ */
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+
+ for (i = 1; i < iov_count + 1; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
+ paddingoffset = i;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i - 1].buffer.length;
+ data[i].data.data = iov[i - 1].buffer.value;
+ }
+
+ /*
+ * Any necessary padding is added here to ensure that the
+ * encrypted token header is always at the end of the
+ * ciphertext.
+ */
+
+ /* XXX KRB5_CRYPTO_TYPE_PADDING */
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer)
+ data[i].data.data = trailer->buffer.value;
+ else
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+
+ data[i].data.length = sizeof(*token);
+ memcpy(data[i].data.data, token, sizeof(*token));
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (rrc) {
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+ }
+
+ if (paddingoffset)
+ padding->buffer.length = data[paddingoffset].data.length;
+
+ } else {
+ /*
+ plain packet:
+
+ {data | "header" | gss-trailer (krb5 checksum)
+
+ don't do RRC != 0
+
+ */
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = header->buffer.length;
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ data[i].data.data = trailer->buffer.value;
+ data[i].data.length = trailer->buffer.length;
+ i++;
+
+ ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ token->EC[0] = (trailer->buffer.length >> 8) & 0xFF;
+ token->EC[1] = (trailer->buffer.length >> 0) & 0xFF;
+ }
+
+ if (conf_state != NULL)
+ *conf_state = conf_req_flag;
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+
+/* This is slowpath */
+static OM_uint32
+unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count)
+{
+ uint8_t *p, *q;
+ size_t len = 0, skip;
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ len += iov[i].buffer.length;
+
+ p = malloc(len);
+ if (p == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ q = p;
+
+ /* copy up */
+
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, iov[i].buffer.length);
+ q += iov[i].buffer.length;
+ }
+ }
+ assert((q - p) == len);
+
+ /* unrotate first part */
+ q = p + rrc;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ if (iov[i].buffer.length <= skip) {
+ skip -= iov[i].buffer.length;
+ } else {
+ memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip);
+ q += iov[i].buffer.length - skip;
+ skip = 0;
+ }
+ }
+ }
+ /* copy trailer */
+ q = p;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip));
+ if (iov[i].buffer.length > skip)
+ break;
+ skip -= iov[i].buffer.length;
+ q += iov[i].buffer.length;
+ }
+ }
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32
+_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
+ gss_iov_buffer_desc *header, *trailer;
+ gss_cfx_wrap_token token, ttoken;
+ u_char token_flags;
+ krb5_error_code ret;
+ unsigned usage;
+ uint16_t ec, rrc;
+ krb5_crypto_iov *data = NULL;
+ int i, j;
+
+ *minor_status = 0;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (header->buffer.length < sizeof(*token)) /* we check exact below */
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ /* Ignore unknown flags */
+ token_flags = token->Flags &
+ (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
+
+ if (token_flags & CFXSentByAcceptor) {
+ if ((ctx->more_flags & LOCAL) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+ if ((token_flags & CFXAcceptorSubkey) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ } else {
+ if (token_flags & CFXAcceptorSubkey)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (token->Filler != 0xFF)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (conf_state != NULL)
+ *conf_state = (token_flags & CFXSealed) ? 1 : 0;
+
+ ec = (token->EC[0] << 8) | token->EC[1];
+ rrc = (token->RRC[0] << 8) | token->RRC[1];
+
+ /*
+ * Check sequence number
+ */
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ if (seq_number_hi) {
+ /* no support for 64-bit sequence numbers */
+ *minor_status = ERANGE;
+ return GSS_S_UNSEQ_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+ if (ret != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * Decrypt and/or verify checksum
+ */
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+ } else {
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ }
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (token_flags & CFXSealed) {
+ size_t k5tsize, k5hsize;
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+
+ /* Rotate by RRC; bogus to do this in-place XXX */
+ /* Check RRC */
+
+ if (trailer == NULL) {
+ size_t gsstsize = k5tsize + sizeof(*token);
+ size_t gsshsize = k5hsize + sizeof(*token);
+
+ if (IS_DCE_STYLE(ctx))
+ gsstsize += ec;
+ gsshsize += gsstsize;
+
+ if (rrc != gsstsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+ if (header->buffer.length != gsshsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+ } else if (trailer->buffer.length != sizeof(*token) + k5tsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (header->buffer.length != sizeof(*token) + k5hsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (rrc != 0) {
+ /* go though slowpath */
+ major_status = unrotate_iov(minor_status, rrc, iov, iov_count);
+ if (major_status)
+ goto failure;
+ }
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+ i++;
+
+ for (j = 0; j < iov_count; i++, j++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[j].buffer.length;
+ data[i].data.data = iov[j].buffer.value;
+ }
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer)
+ data[i].data.data = trailer->buffer.value;
+ else
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+ data[i].data.length = sizeof(*token);
+ ttoken = (gss_cfx_wrap_token)data[i].data.data;
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ttoken->RRC[0] = token->RRC[0];
+ ttoken->RRC[1] = token->RRC[1];
+
+ /* Check the integrity of the header */
+ if (memcmp(ttoken, token, sizeof(*token)) != 0) {
+ major_status = GSS_S_BAD_MIC;
+ goto failure;
+ }
+ } else {
+ /* Check RRC */
+ if (rrc != 0) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (trailer == NULL) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (trailer->buffer.length != ec) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = header->buffer.length;
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ data[i].data.data = trailer->buffer.value;
+ data[i].data.length = trailer->buffer.length;
+ i++;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+ }
+
+ if (qop_state != NULL) {
+ *qop_state = GSS_C_QOP_DEFAULT;
+ }
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+
+OM_uint32
+_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ size_t size;
+ int i;
+ size_t *padding = NULL;
+
+ GSSAPI_KRB5_INIT (&context);
+ *minor_status = 0;
+
+ for (size = 0, i = 0; i < iov_count; i++) {
+ switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_EMPTY:
+ break;
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ size += iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_HEADER:
+ *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ break;
+ case GSS_IOV_BUFFER_TYPE_TRAILER:
+ *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ if (padding != NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ padding = &iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+ if (padding) {
+ size_t pad;
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
+ if (pad > 1) {
+ *padding = pad - (size % pad);
+ if (*padding == pad)
+ *padding = 0;
+ } else
+ *padding = 0;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx ctx,
krb5_context context,
int conf_req_flag,
- gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer)
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_compare_name
(OM_uint32 * minor_status,
const gss_name_t name1,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
-
static krb5_error_code
check_compat(OM_uint32 *minor_status,
krb5_context context, krb5_const_principal name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_lifetime_left(OM_uint32 *minor_status,
krb5_context context,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
#if 0
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* return the length of the mechanism in token or -1
* (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static const char *
calling_error(OM_uint32 v)
{
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
void
_gssapi_encap_length (size_t data_len,
size_t *len,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_export_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_export_sec_context (
OM_uint32 * minor_status,
#include "gsskrb5_locl.h"
#include <gssapi_mech.h>
-RCSID("$Id$");
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
mic_des
(OM_uint32 * minor_status,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
parse_krb5_name (OM_uint32 *minor_status,
krb5_context context,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_import_sec_context (
OM_uint32 * minor_status,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_indicate_mechs
(OM_uint32 * minor_status,
gss_OID_set * mech_set
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
static int created_key;
static HEIMDAL_thread_key context_key;
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* copy the addresses from `input_chan_bindings' (if any) to
* the auth context `ac'
if (actual_mech_type)
*actual_mech_type = GSS_KRB5_MECHANISM;
- if (ctx->flags & GSS_C_DCE_STYLE) {
+ if (IS_DCE_STYLE(ctx)) {
/* There is no OID wrapping. */
indata.length = input_token->length;
indata.data = input_token->value;
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_context (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred_by_oid
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_mechs_for_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
-
static gss_OID *name_list[] = {
&GSS_C_NT_HOSTBASED_SERVICE,
&GSS_C_NT_USER_NAME,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static int
oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
{
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_pseudo_random(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_process_context_token (
OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_buffer
(OM_uint32 * minor_status,
gss_buffer_t buffer
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_cred
(OM_uint32 * minor_status,
gss_cred_id_t * cred_handle
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
#define DEFAULT_JITTER_WINDOW 20
struct gss_msg_order {
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/* 1.2.752.43.13.17 */
static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
get_bool(OM_uint32 *minor_status,
const gss_buffer_t value,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* Return initiator subkey, or if that doesn't exists, the subkey.
*/
if (ctx->more_flags & IS_CFX)
return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
- qop_req, input_message_buffer, conf_state,
+ input_message_buffer, conf_state,
output_message_buffer);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
int i;
*minor_status = 0;
- if (output_cred_handle)
+ if (output_cred_handle == NULL)
return GSS_S_CALL_INACCESSIBLE_READ;
if (actual_mechs)
*actual_mechs = GSS_C_NO_OID_SET;
*/
#include "mech_locl.h"
-RCSID("$Id$");
/**
* Encrypts or sign the data.
*
+ * This is a more complicated version of gss_wrap(), it allows the
+ * caller to use AEAD data (signed header/trailer) and allow greater
+ * controll over where the encrypted data is placed.
+ *
* The maximum packet size is gss_context_stream_sizes.max_msg_size.
*
- * The caller needs provide the folloing buffers:
+ * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:
*
* - HEADER (of size gss_context_stream_sizes.header)
- * SIGN_ONLY (optional, zero or more)
- * DATA
- * SIGN_ONLY (optional, zero or more)
- * PADDING (of size gss_context_stream_sizes.blocksize)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
* TRAILER (of size gss_context_stream_sizes.trailer)
*
* - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
- * DATA elements is padded to a block bountry.
+ * DATA elements is padded to a block bountry and header is of at
+ * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.
+ *
+ * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.
*
* To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
*
+ * When used in conf_req_flag=0,
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
+ * TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ *
* The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
* gss_context_query_attributes().
*
iov, iov_count);
}
+/**
+ * Decrypt or verifies the signature on the data.
+ *
+ *
+ * @ingroup gssapi
+ */
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
iov, iov_count);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+/**
+ * Update the length fields in iov buffer for the types:
+ * - GSS_IOV_BUFFER_TYPE_HEADER
+ * - GSS_IOV_BUFFER_TYPE_PADDING
+ * - GSS_IOV_BUFFER_TYPE_TRAILER
+ *
+ * Consider using gss_context_query_attributes() to fetch the data instead.
+ *
+ * @ingroup gssapi
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
iov, iov_count);
}
+/**
+ * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by
+ * looking at the GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED flag.
+ *
+ * @ingroup gssapi
+ */
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_iov_buffer(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
return GSS_S_CALL_INACCESSIBLE_READ;
for (i = 0; i < iov_count; i++) {
- if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED)
+ if ((iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) == 0)
continue;
gss_release_buffer(&junk, &iov[i].buffer);
+ iov[i].type &= ~GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
}
return GSS_S_COMPLETE;
}
* SSPI equivalent if this function is QueryContextAttributes.
*
* - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ *
+ * @ingroup gssapi
*/
static gss_OID_desc gss_c_attr_stream_sizes_desc =
gss_buffer_t output_token)
{
NegotiationTokenWin nt;
- char hostname[MAXHOSTNAMELEN + 1], *p;
- gss_buffer_desc name_buf;
- gss_OID name_type;
- gss_name_t target_princ;
- gss_name_t canon_princ;
- OM_uint32 minor;
size_t buf_len;
gss_buffer_desc data;
OM_uint32 ret;
return ret;
}
- memset(&target_princ, 0, sizeof(target_princ));
- if (gethostname(hostname, sizeof(hostname) - 2) != 0) {
- *minor_status = errno;
- free_NegotiationTokenWin(&nt);
- return GSS_S_FAILURE;
- }
- hostname[sizeof(hostname) - 1] = '\0';
-
- /* Send the constructed SAM name for this host */
- for (p = hostname; *p != '\0' && *p != '.'; p++) {
- *p = toupper((unsigned char)*p);
- }
- *p++ = '$';
- *p = '\0';
-
- name_buf.length = strlen(hostname);
- name_buf.value = hostname;
-
- ret = gss_import_name(minor_status, &name_buf,
- GSS_C_NO_OID,
- &target_princ);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- return ret;
- }
-
- name_buf.length = 0;
- name_buf.value = NULL;
-
- /* Canonicalize the name using the preferred mechanism */
- ret = gss_canonicalize_name(minor_status,
- target_princ,
- GSS_C_NO_OID,
- &canon_princ);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- gss_release_name(&minor, &target_princ);
- return ret;
- }
-
- ret = gss_display_name(minor_status, canon_princ,
- &name_buf, &name_type);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- gss_release_name(&minor, &canon_princ);
- gss_release_name(&minor, &target_princ);
- return ret;
- }
-
- gss_release_name(&minor, &canon_princ);
- gss_release_name(&minor, &target_princ);
-
ALLOC(nt.u.negTokenInit.negHints, 1);
if (nt.u.negTokenInit.negHints == NULL) {
*minor_status = ENOMEM;
- gss_release_buffer(&minor, &name_buf);
free_NegotiationTokenWin(&nt);
return GSS_S_FAILURE;
}
ALLOC(nt.u.negTokenInit.negHints->hintName, 1);
if (nt.u.negTokenInit.negHints->hintName == NULL) {
*minor_status = ENOMEM;
- gss_release_buffer(&minor, &name_buf);
free_NegotiationTokenWin(&nt);
return GSS_S_FAILURE;
}
- *(nt.u.negTokenInit.negHints->hintName) = name_buf.value;
- name_buf.value = NULL;
+ *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore");
nt.u.negTokenInit.negHints->hintAddress = NULL;
ASN1_MALLOC_ENCODE(NegotiationTokenWin,
data.value, data.length, &nt, &buf_len, ret);
free_NegotiationTokenWin(&nt);
if (ret) {
- return ret;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
}
if (data.length != buf_len)
abort();
*
*/
-#if !defined(__GNUC__) && !defined(__attribute__)
-#define __attribute__(x)
-#endif
-
#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
+#endif
#endif
#ifdef __cplusplus
#endif
#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
#endif
+#endif
+
#ifndef HC_DEPRECATED_CRYPTO
-#define HC_DEPRECATED_CRYPTO __attribute__((deprecated))
+#define HC_DEPRECATED_CRYPTO HC_DEPRECATED
#endif
#include "hdb_locl.h"
-RCSID("$Id$");
-
#if HAVE_DB1
#if defined(HAVE_DB_185_H)
}
(*db)->hdb_master_key_set = 0;
(*db)->hdb_openp = 0;
+ (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
(*db)->hdb_open = DB_open;
(*db)->hdb_close = DB_close;
(*db)->hdb_fetch = _hdb_fetch;
#include "hdb_locl.h"
-RCSID("$Id$");
-
struct hdb_dbinfo {
char *label;
char *realm;
#include "hdb_locl.h"
#include <der.h>
-RCSID("$Id$");
-
krb5_error_code
hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
{
immutable(13), -- may not be deleted
trusted-for-delegation(14), -- Trusted to print forwardabled tickets
allow-kerberos4(15), -- Allow Kerberos 4 requests
- allow-digest(16) -- Allow digest requests
+ allow-digest(16), -- Allow digest requests
+ locked-out(17) -- Account is locked out,
+ -- authentication will be denied
}
GENERATION ::= SEQUENCE {
#include "krb5_locl.h"
#include "hdb_locl.h"
-RCSID("$Id$");
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */
#define HDB_F_CANON 32 /* want canonicalition */
+/* hdb_capability_flags */
#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
+#define HDB_CAP_F_HANDLE_PASSWORDS 2
+#define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4
+
+/* auth status values */
+#define HDB_AUTH_SUCCESS 0
+#define HDB_AUTH_WRONG_PASSWORD 1
+#define HDB_AUTH_INVALID_SIGNATURE 2
/* key usage for master key */
#define HDB_KU_MKEY 0x484442
* point for the module.
*/
krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
+ /**
+ * Change password.
+ *
+ * Will update keys for the entry when given password. The new
+ * keys must be written into the entry and and will then later be
+ * ->hdb_store() into the database. The backend will still perform
+ * all other operations, increasing the kvno, and update
+ * modification timestamp.
+ *
+ * The backen need to call _kadm5_set_keys() and perform password
+ * quality checks.
+ */
+ krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int);
+
+ /**
+ * Auth feedback
+ *
+ * This is a feedback call that allows backends that provides
+ * lockout functionality to register failure and/or successes.
+ *
+ * In case the entry is locked out, the backend should set the
+ * hdb_entry.flags.locked-out flag.
+ */
+ krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int);
+ /**
+ * Check is delegation is allowed.
+ */
+ krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
}HDB;
#define HDB_INTERFACE_VERSION 5
#include "hdb_locl.h"
-RCSID("$Id$");
-
/*
* free all the memory used by (len, keys)
*/
/* keytab backend for HDB databases */
-RCSID("$Id$");
-
struct hdb_data {
char *dbname;
char *mkey;
return 0;
}
-static void
-set_config (krb5_context context,
- const krb5_config_binding *binding,
- const char **dbname,
- const char **mkey)
-{
- *dbname = krb5_config_get_string(context, binding, "dbname", NULL);
- *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL);
-}
-
/*
* try to figure out the database (`dbname') and master-key (`mkey')
* that should be used for `principal'.
*/
-static void
+static krb5_error_code
find_db (krb5_context context,
- const char **dbname,
- const char **mkey,
+ char **dbname,
+ char **mkey,
krb5_const_principal principal)
{
- const krb5_config_binding *top_bind = NULL;
- const krb5_config_binding *default_binding = NULL;
- const krb5_config_binding *db;
krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+ krb5_error_code ret;
+ struct hdb_dbinfo *head, *dbinfo = NULL;
*dbname = *mkey = NULL;
- while ((db =
- krb5_config_get_next(context,
- NULL,
- &top_bind,
- krb5_config_list,
- "kdc",
- "database",
- NULL)) != NULL) {
- const char *p;
-
- p = krb5_config_get_string (context, db, "realm", NULL);
- if (p == NULL) {
- if(default_binding) {
- krb5_warnx(context, "WARNING: more than one realm-less "
- "database specification");
- krb5_warnx(context, "WARNING: using the first encountered");
- } else
- default_binding = db;
- } else if (strcmp (realm, p) == 0) {
- set_config (context, db, dbname, mkey);
+ ret = hdb_get_dbinfo(context, &head);
+ if (ret)
+ return ret;
+
+ while ((dbinfo = hdb_dbinfo_get_next(head, dbinfo)) != NULL) {
+ const char *p = hdb_dbinfo_get_realm(context, dbinfo);
+ if (p && strcmp (realm, p) == 0) {
+ p = hdb_dbinfo_get_dbname(context, dbinfo);
+ if (p)
+ *dbname = strdup(p);
+ p = hdb_dbinfo_get_mkey_file(context, dbinfo);
+ if (p)
+ *mkey = strdup(p);
break;
}
}
- if (*dbname == NULL && default_binding != NULL)
- set_config (context, default_binding, dbname, mkey);
+ hdb_free_dbinfo(context, &head);
if (*dbname == NULL)
- *dbname = HDB_DEFAULT_DB;
+ *dbname = strdup(HDB_DEFAULT_DB);
+ return 0;
}
/*
hdb_entry_ex ent;
krb5_error_code ret;
struct hdb_data *d = id->data;
- int i;
- HDB *db;
const char *dbname = d->dbname;
const char *mkey = d->mkey;
+ char *fdbname = NULL, *fmkey = NULL;
+ HDB *db;
+ int i;
memset(&ent, 0, sizeof(ent));
- if (dbname == NULL)
- find_db (context, &dbname, &mkey, principal);
+ if (dbname == NULL) {
+ ret = find_db(context, &fdbname, &fmkey, principal);
+ if (ret)
+ return ret;
+ dbname = fdbname;
+ mkey = fmkey;
+ }
ret = hdb_create (context, &db, dbname);
if (ret)
- return ret;
+ goto out2;
ret = hdb_set_master_keyfile (context, db, mkey);
if (ret) {
(*db->hdb_destroy)(context, db);
- return ret;
+ goto out2;
}
ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
if (ret) {
(*db->hdb_destroy)(context, db);
- return ret;
+ goto out2;
}
ret = (*db->hdb_fetch)(context, db, principal,
HDB_F_DECRYPT|
}
}
hdb_free_entry(context, &ent);
-out:
+ out:
(*db->hdb_close)(context, db);
(*db->hdb_destroy)(context, db);
+ out2:
+ free(fdbname);
+ free(fmkey);
return ret;
}
#define O_BINARY 0
#endif
-RCSID("$Id$");
-
struct hdb_master_key_data {
krb5_keytab_entry keytab;
krb5_crypto crypto;
#include "hdb_locl.h"
-RCSID("$Id$");
-
#if HAVE_NDBM
#if defined(HAVE_GDBM_NDBM_H)
}
(*db)->hdb_master_key_set = 0;
(*db)->hdb_openp = 0;
+ (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
(*db)->hdb_open = NDBM_open;
(*db)->hdb_close = NDBM_close;
(*db)->hdb_fetch = _hdb_fetch;
struct signature_alg;
-enum crypto_op_type {
- COT_SIGN
-};
-
struct hx509_generate_private_context {
const heim_oid *key_oid;
int isCA;
krb5_error_code ret;
struct key_data *dkey;
const struct encryption_type *et = crypto->et;
- krb5_crypto_iov *tiv, *piv, *hiv, *div;
+ krb5_crypto_iov *tiv, *piv, *hiv;
if (num_data < 0) {
krb5_clear_error_message(context);
headersz = et->confoundersize;
trailersz = CHECKSUMSIZE(et->keyed_checksum);
- div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
- if (div == NULL)
- return KRB5_CRYPTO_INTERNAL;
-
- len = div->data.length;
+ for (len = 0, i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ len += data[i].data.length;
+ }
sz = headersz + len;
block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
krb5_generate_random_block(hiv->data.data, hiv->data.length);
/* padding */
-
piv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
/* its ok to have no TYPE_PADDING if there is no padding */
if (piv == NULL && pad_sz != 0)
if (piv->data.length < pad_sz)
return KRB5_BAD_MSIZE;
piv->data.length = pad_sz;
+ if (pad_sz)
+ memset(piv->data.data, pad_sz, pad_sz);
+ else
+ piv = NULL;
}
-
/* trailer */
-
tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
if (tiv == NULL || tiv->data.length != trailersz)
return KRB5_BAD_MSIZE;
-
/*
* XXX replace with EVP_Sign? at least make create_checksum an iov
* function.
* XXX CTS EVP is broken, can't handle multi buffers :(
*/
- len = hiv->data.length;
+ len = block_sz;
for (i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
- data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
continue;
len += data[i].data.length;
}
memcpy(q, data[i].data.data, data[i].data.length);
q += data[i].data.length;
}
+ if (piv) {
+ memset(q, 0, piv->data.length);
+ q += piv->data.length;
+ }
ret = create_checksum(context,
et->keyed_checksum,
memcpy(tiv->data.data, cksum.checksum.data, cksum.checksum.length);
free_Checksum (&cksum);
- /* now encrypt data */
-
- ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
- if(ret)
- return ret;
- ret = _key_schedule(context, dkey);
- if(ret)
- return ret;
-
/* XXX replace with EVP_Cipher */
-
- len = hiv->data.length + div->data.length;
- if (piv)
- len += piv->data.length;
-
- p = q = malloc(len);
+ p = q = malloc(block_sz);
if(p == NULL)
return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
- memcpy(q, div->data.data, div->data.length);
- q += div->data.length;
- memset(q, 0, pad_sz);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
+ if (piv) {
+ memset(q, 0, piv->data.length);
+ q += piv->data.length;
+ }
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) {
return ret;
}
- ret = (*et->encrypt)(context, dkey, p, len, 1, usage, ivec);
+ ret = (*et->encrypt)(context, dkey, p, block_sz, 1, usage, ivec);
if (ret) {
free(p);
return ret;
memcpy(hiv->data.data, q, hiv->data.length);
q += hiv->data.length;
- memcpy(div->data.data, q, div->data.length);
- q += div->data.length;
-
- if (piv)
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(data[i].data.data, q, data[i].data.length);
+ q += data[i].data.length;
+ }
+ if (piv) {
memcpy(piv->data.data, q, pad_sz);
+ q += pad_sz;
+ }
+
free(p);
return ret;
{
unsigned int i;
size_t headersz, trailersz, len;
- size_t sz, block_sz, pad_sz;
Checksum cksum;
unsigned char *p, *q;
krb5_error_code ret;
struct key_data *dkey;
struct encryption_type *et = crypto->et;
- krb5_crypto_iov *tiv, *hiv, *div;
+ krb5_crypto_iov *tiv, *hiv;
if (num_data < 0) {
krb5_clear_error_message(context);
}
headersz = et->confoundersize;
- trailersz = CHECKSUMSIZE(et->keyed_checksum);
-
- for (len = 0, i = 0; i < num_data; i++) {
- if (data[i].flags == KRB5_CRYPTO_TYPE_DATA) {
- if (len != 0)
- return KRB5_CRYPTO_INTERNAL;
- len += data[i].data.length;
- }
- }
-
- sz = headersz + len;
- block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
-
- pad_sz = block_sz - sz;
- trailersz += pad_sz;
-
- /* header */
hiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
- if (hiv == NULL || hiv->data.length < headersz)
+ if (hiv == NULL || hiv->data.length != headersz)
return KRB5_BAD_MSIZE;
- hiv->data.length = headersz;
/* trailer */
+ trailersz = CHECKSUMSIZE(et->keyed_checksum);
tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
- if (tiv == NULL || tiv->data.length < trailersz)
+ if (tiv->data.length != trailersz)
return KRB5_BAD_MSIZE;
- tiv->data.length = trailersz;
-
- div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
- if (div == NULL)
- return KRB5_CRYPTO_INTERNAL;
- /* XXX replace with EVP_Cipher */
+ /* Find length of data we will decrypt */
- for (len = 0, i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_HEADER &&
- data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ len = headersz;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
continue;
len += data[i].data.length;
}
+ if ((len % et->padsize) != 0) {
+ krb5_clear_error_message(context);
+ return KRB5_BAD_MSIZE;
+ }
+
+ /* XXX replace with EVP_Cipher */
+
p = q = malloc(len);
if (p == NULL)
return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
- memcpy(q, div->data.data, div->data.length);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) {
/* copy data back to buffers */
memcpy(hiv->data.data, p, hiv->data.length);
- memcpy(div->data.data, p + hiv->data.length, len - hiv->data.length);
+ q = p + hiv->data.length;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(data[i].data.data, q, data[i].data.length);
+ q += data[i].data.length;
+ }
+
free(p);
/* check signature */
-
- len = hiv->data.length;
for (i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
- data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
continue;
len += data[i].data.length;
}
p = q = malloc(len);
+ if (p == NULL)
+ return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
return 0;
}
+/**
+ * Verify a Kerberos message checksum.
+ *
+ * @param context Kerberos context
+ * @param crypto Kerberos crypto context
+ * @param usage Key usage for this buffer
+ * @param data array of buffers to process
+ * @param num_data length of array
+ *
+ * @return Return an error code or 0.
+ * @ingroup krb5_crypto
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_verify_checksum_iov(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ krb5_crypto_iov *data,
+ unsigned int num_data,
+ krb5_cksumtype *type)
+{
+ struct encryption_type *et = crypto->et;
+ Checksum cksum;
+ krb5_crypto_iov *civ;
+ krb5_error_code ret;
+ int i;
+ size_t len;
+ char *p, *q;
+
+ if (num_data < 0) {
+ krb5_clear_error_message(context);
+ return KRB5_CRYPTO_INTERNAL;
+ }
+
+ if(!derived_crypto(context, crypto)) {
+ krb5_clear_error_message(context);
+ return KRB5_CRYPTO_INTERNAL;
+ }
+
+ civ = find_iv(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
+ if (civ == NULL)
+ return KRB5_BAD_MSIZE;
+
+ len = 0;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+ data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ continue;
+ len += data[i].data.length;
+ }
+
+ p = q = malloc(len);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+ data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
+
+ cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
+ cksum.checksum.length = civ->data.length;
+ cksum.checksum.data = civ->data.data;
+
+ ret = krb5_verify_checksum(context, crypto, usage, p, len, &cksum);
+ free(p);
+
+ if (ret == 0 && type)
+ *type = cksum.cksumtype;
+
+ return ret;
+}
+
-size_t KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_length(krb5_context context,
krb5_crypto crypto,
- int type)
+ int type,
+ size_t *len)
{
- if (!derived_crypto(context, crypto))
- return (size_t)-1;
+ if (!derived_crypto(context, crypto)) {
+ krb5_set_error_message(context, EINVAL, "not a derived crypto");
+ return EINVAL;
+ }
+
switch(type) {
case KRB5_CRYPTO_TYPE_EMPTY:
+ *len = 0;
return 0;
case KRB5_CRYPTO_TYPE_HEADER:
- return crypto->et->blocksize;
+ *len = crypto->et->blocksize;
+ return 0;
+ case KRB5_CRYPTO_TYPE_DATA:
+ case KRB5_CRYPTO_TYPE_SIGN_ONLY:
+ /* len must already been filled in */
+ return 0;
case KRB5_CRYPTO_TYPE_PADDING:
if (crypto->et->padsize > 1)
- return crypto->et->padsize;
+ *len = crypto->et->padsize;
+ else
+ *len = 0;
return 0;
case KRB5_CRYPTO_TYPE_TRAILER:
- return CHECKSUMSIZE(crypto->et->keyed_checksum);
+ *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+ return 0;
case KRB5_CRYPTO_TYPE_CHECKSUM:
if (crypto->et->keyed_checksum)
- return CHECKSUMSIZE(crypto->et->keyed_checksum);
- return CHECKSUMSIZE(crypto->et->checksum);
+ *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+ else
+ *len = CHECKSUMSIZE(crypto->et->checksum);
+ return 0;
+ }
+ krb5_set_error_message(context, EINVAL,
+ "%d not a supported type", type);
+ return EINVAL;
+}
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_crypto_length_iov(krb5_context context,
+ krb5_crypto crypto,
+ krb5_crypto_iov *data,
+ unsigned int num_data)
+{
+ krb5_error_code ret;
+ int i;
+
+ for (i = 0; i < num_data; i++) {
+ ret = krb5_crypto_length(context, crypto,
+ data[i].flags,
+ &data[i].data.length);
+ if (ret)
+ return ret;
}
- return (size_t)-1;
+ return 0;
}
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_encrypt_ivec(krb5_context context,
krb5_crypto crypto,
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
-#ifdef HAVE_IFADDR_H
#include <ifaddrs.h>
-#endif
static krb5_error_code
gethostname_fallback (krb5_context context, krb5_addresses *res)
ret = 0;
} else if (ret == KRB5_KDC_ERR_WRONG_REALM && ctx->flags.canonicalize) {
/* client referal to a new realm */
- if (ctx->error.crealm) {
+ if (ctx->error.crealm == NULL) {
krb5_set_error_message(context, ret,
N_("Got a client referral, not but no realm", ""));
goto out;
#endif
#ifndef KRB5_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define KRB5_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define KRB5_DEPRECATED __declspec(deprecated)
+#else
+#define KRB5_DEPRECATED
+#endif
#endif
/* simple constants */
*/
#include "krb5_locl.h"
+#include <vis.h>
struct facility {
int min;
void *data)
{
struct file_data *f = data;
+ char *msgclean;
+ size_t len = strlen(msg) + 1;
if(f->keep_open == 0)
f->fd = fopen(f->filename, f->mode);
if(f->fd == NULL)
return;
- fprintf(f->fd, "%s %s\n", timestr, msg);
+ /* make sure the log doesn't contain special chars */
+ len *= 4;
+ msgclean = malloc(len);
+ if (msgclean == NULL)
+ goto out;
+ strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL);
+ fprintf(f->fd, "%s %s\n", timestr, msgclean);
+ free(msgclean);
+ out:
if(f->keep_open == 0) {
fclose(f->fd);
f->fd = NULL;
* If offset is larget then current size, or current size is
* shrunk more then half of the current size, adjust buffer.
*/
- if (offset > s->size || (s->size / 2) > offset) {
+ if (offset == 0) {
+ free(s->base);
+ s->size = 0;
+ s->base = NULL;
+ s->ptr = NULL;
+ } else if (offset > s->size || (s->size / 2) > offset) {
void *base;
size_t off;
off = s->ptr - s->base;
--- /dev/null
+#include "system/network.h"
AC_CHECK_HEADERS([err.h], [],
[ cp heimdal/lib/roken/err.hin heimdal_build/err.h ])
+dnl Not all systems have ifaddrs.h, so we provide a replacement. Heimdal
+dnl unconditionally #includes <ifaddrs.h>, so we need to create an ifaddrs.h,
+dnl but we can't just have a static one because we don't want to use
+dnl it on systems that have a real ifaddrs.h. If the system has a real
+dnl ifaddrs.h. We don't use heimdal's lib/roken/ifaddrs.hin because
+dnl our libreplace would conflict with it.
+AC_CHECK_HEADERS([ifaddrs.h], [],
+ [ cp heimdal_build/ifaddrs.hin heimdal_build/ifaddrs.h ])
+
AC_CHECK_HEADERS([ \
crypt.h \
curses.h \
*/
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
#include "err.h"
#include "roken.h"
+#include "system/filesys.h"
#ifndef HAVE_ERR
void err(int eval, const char *format, ...)
#ifndef HAVE_FLOCK
int flock(int fd, int op)
{
+#undef flock
struct flock lock;
lock.l_whence = 0;
lock.l_start = 0;
#define HAVE_SETEUID 1
#endif
+#ifndef HAVE_STRNLEN
+#define HAVE_STRNLEN
+#endif
+
#ifndef HAVE_STRNDUP
#define HAVE_STRNDUP
#endif
#define HAVE_STRCASECMP
#endif
+#ifndef HAVE_ASPRINTF
+#define HAVE_ASPRINTF
+#endif
+
+#ifndef HAVE_VASPRINTF
+#define HAVE_VASPRINTF
+#endif
+
#ifndef HAVE_MKSTEMP
#define HAVE_MKSTEMP
#endif
#define HAVE_INNETGR
#endif
+#ifndef HAVE_INET_ATON
+#define HAVE_INET_ATON
+#endif
+
/* we lie about having pidfile() so that NetBSD5 can compile. Nothing
in the parts of heimdal we use actually uses pidfile(), and we
don't use it in Samba, so this works, although its ugly */
#include "includes.h"
#include "system/time.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "librpc/gen_ndr/netlogon.h"
flags.invalid = 1;
}
-/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */
+/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in hdb_samba4_message2entry() */
/*
if (userAccountControl & UF_MNS_LOGON_ACCOUNT) {
talloc_free(entry_ex->ctx);
}
-static krb5_error_code LDB_message2entry_keys(krb5_context context,
+static krb5_error_code hdb_samba4_message2entry_keys(krb5_context context,
struct smb_iconv_convenience *iconv_convenience,
TALLOC_CTX *mem_ctx,
struct ldb_message *msg,
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
- krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
goto out;
}
if (newer_keys && _pkb.version != 4) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
- krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
goto out;
}
if (!newer_keys && _pkb.version != 3) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
- krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
goto out;
}
/*
* Construct an hdb_entry from a directory entry.
*/
-static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_message2entry(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
enum hdb_ldb_ent_type ent_type,
if (!samAccountName) {
ret = ENOENT;
- krb5_set_error_message(context, ret, "LDB_message2entry: no samAccountName present");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry: no samAccountName present");
goto out;
}
entry_ex->entry.generation = NULL;
/* Get keys from the db */
- ret = LDB_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
+ ret = hdb_samba4_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
if (ret) {
/* Could be bougus data in the entry, or out of memory */
goto out;
/*
* Construct an hdb_entry from a directory entry.
*/
-static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_trust_message2entry(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
enum trust_direction direction,
}
-static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,
+static krb5_error_code hdb_samba4_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,
TALLOC_CTX *mem_ctx,
const char *realm,
struct ldb_dn *realm_dn,
return 0;
}
-static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
+static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode)
{
if (db->hdb_master_key_set) {
krb5_error_code ret = HDB_ERR_NOENTRY;
- krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");
- krb5_set_error_message(context, ret, "LDB_open: use of a master key incompatible with LDB\n");
+ krb5_warnx(context, "hdb_samba4_open: use of a master key incompatible with LDB\n");
+ krb5_set_error_message(context, ret, "hdb_samba4_open: use of a master key incompatible with LDB\n");
return ret;
}
return 0;
}
-static krb5_error_code LDB_close(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_close(krb5_context context, HDB *db)
{
return 0;
}
-static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation)
+static krb5_error_code hdb_samba4_lock(krb5_context context, HDB *db, int operation)
{
return 0;
}
-static krb5_error_code LDB_unlock(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_unlock(krb5_context context, HDB *db)
{
return 0;
}
-static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name)
+static krb5_error_code hdb_samba4_rename(krb5_context context, HDB *db, const char *new_name)
{
return HDB_ERR_DB_INUSE;
}
-static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch_client(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx,
krb5_const_principal principal,
return EINVAL;
}
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
realm_dn, msg, entry_ex);
return ret;
}
-static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx,
krb5_const_principal principal,
int lret;
char *realm_fixed;
- const char * const *princ_attrs = user_attrs;
lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx,
realm_dn, LDB_SCOPE_SUBTREE,
- &msg, princ_attrs,
+ &msg, krbtgt_attrs,
"(&(objectClass=user)(samAccountName=krbtgt))");
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
- krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB!");
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB!");
+ krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
+ krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
return HDB_ERR_NOENTRY;
} else if (lret != LDB_SUCCESS) {
- krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+ krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+ krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
return HDB_ERR_NOENTRY;
}
talloc_free(realm_fixed);
if (!alloc_principal->name.name_string.val[1]) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_fetch: strdup() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: strdup() failed!");
return ret;
}
principal = alloc_principal;
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_KRBTGT,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: self krbtgt message2entry failed");
}
return ret;
/* Trusted domains are under CN=system */
- ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db,
+ ret = hdb_samba4_lookup_trust(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
realm, realm_dn, &msg);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: could not find principal in DB");
- krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB");
+ krb5_warnx(context, "hdb_samba4_fetch: could not find principal in DB");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: could not find principal in DB");
return ret;
}
- ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_trust_message2entry(context, db, lp_ctx, mem_ctx,
principal, direction,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: trust_message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: trust_message2entry failed");
}
return ret;
}
-static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
- struct loadparm_context *lp_ctx,
- TALLOC_CTX *mem_ctx,
- krb5_const_principal principal,
- unsigned flags,
- hdb_entry_ex *entry_ex)
+static krb5_error_code hdb_samba4_lookup_server(krb5_context context, HDB *db,
+ struct loadparm_context *lp_ctx,
+ TALLOC_CTX *mem_ctx,
+ krb5_const_principal principal,
+ const char **attrs,
+ struct ldb_dn **realm_dn,
+ struct ldb_message **msg)
{
krb5_error_code ret;
const char *realm;
- struct ldb_message *msg = NULL;
- struct ldb_dn *realm_dn;
if (principal->name.name_string.len >= 2) {
/* 'normal server' case */
int ldb_ret;
* referral instead */
nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,
mem_ctx, principal_string,
- &user_dn, &realm_dn);
+ &user_dn, realm_dn);
free(principal_string);
if (!NT_STATUS_IS_OK(nt_status)) {
ldb_ret = gendb_search_single_extended_dn((struct ldb_context *)db->hdb_db,
mem_ctx,
user_dn, LDB_SCOPE_BASE,
- &msg, user_attrs,
+ msg, attrs,
"(objectClass=*)");
if (ldb_ret != LDB_SUCCESS) {
return HDB_ERR_NOENTRY;
} else {
int lret;
char *filter = NULL;
- const char * const *princ_attrs = user_attrs;
char *short_princ;
/* server as client principal case, but we must not lookup userPrincipalNames */
- realm_dn = ldb_get_default_basedn(db->hdb_db);
+ *realm_dn = ldb_get_default_basedn(db->hdb_db);
realm = krb5_principal_get_realm(context, principal);
/* TODO: Check if it is our realm, otherwise give referall */
ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
if (ret != 0) {
- krb5_set_error_message(context, ret, "LDB_lookup_principal: could not parse principal");
- krb5_warnx(context, "LDB_lookup_principal: could not parse principal");
+ krb5_set_error_message(context, ret, "hdb_samba4_lookup_principal: could not parse principal");
+ krb5_warnx(context, "hdb_samba4_lookup_principal: could not parse principal");
return ret;
}
lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx,
- realm_dn, LDB_SCOPE_SUBTREE,
- &msg, princ_attrs, "(&(objectClass=user)(samAccountName=%s))",
+ *realm_dn, LDB_SCOPE_SUBTREE,
+ msg, attrs, "(&(objectClass=user)(samAccountName=%s))",
ldb_binary_encode_string(mem_ctx, short_princ));
free(short_princ);
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
}
}
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ return 0;
+}
+
+static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db,
+ struct loadparm_context *lp_ctx,
+ TALLOC_CTX *mem_ctx,
+ krb5_const_principal principal,
+ unsigned flags,
+ hdb_entry_ex *entry_ex)
+{
+ krb5_error_code ret;
+ struct ldb_dn *realm_dn;
+ struct ldb_message *msg;
+
+ ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, principal,
+ server_attrs, &realm_dn, &msg);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_SERVER,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: message2entry failed");
}
return ret;
}
-static krb5_error_code LDB_fetch(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch(krb5_context context, HDB *db,
krb5_const_principal principal,
unsigned flags,
hdb_entry_ex *entry_ex)
{
krb5_error_code ret = HDB_ERR_NOENTRY;
- TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");
+ TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_fetch context");
struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_fetch: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
return ret;
}
if (flags & HDB_F_GET_CLIENT) {
- ret = LDB_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
if (flags & HDB_F_GET_SERVER) {
/* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
- ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
/* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
- ret = LDB_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
if (flags & HDB_F_GET_KRBTGT) {
- ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
return ret;
}
-static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
{
return HDB_ERR_DB_INUSE;
}
-static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal)
+static krb5_error_code hdb_samba4_remove(krb5_context context, HDB *db, krb5_const_principal principal)
{
return HDB_ERR_DB_INUSE;
}
struct ldb_dn *realm_dn;
};
-static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
{
krb5_error_code ret;
struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;
return HDB_ERR_NOENTRY;
}
- mem_ctx = talloc_named(priv, 0, "LDB_seq context");
+ mem_ctx = talloc_named(priv, 0, "hdb_samba4_seq context");
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_seq: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_seq: talloc_named() failed!");
return ret;
}
if (priv->index < priv->count) {
- ret = LDB_message2entry(context, db, priv->lp_ctx,
+ ret = hdb_samba4_message2entry(context, db, priv->lp_ctx,
mem_ctx,
NULL, HDB_SAMBA4_ENT_TYPE_ANY,
priv->realm_dn, priv->msgs[priv->index++], entry);
return ret;
}
-static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
hdb_entry_ex *entry)
{
struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
priv->realm_dn = ldb_get_default_basedn(ldb_ctx);
priv->count = 0;
- mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
+ mem_ctx = talloc_named(priv, 0, "hdb_samba4_firstkey context");
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_firstkey: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_firstkey: talloc_named() failed!");
return ret;
}
db->hdb_dbc = priv;
- ret = LDB_seq(context, db, flags, entry);
+ ret = hdb_samba4_seq(context, db, flags, entry);
if (ret != 0) {
talloc_free(priv);
return ret;
}
-static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigned flags,
hdb_entry_ex *entry)
{
- return LDB_seq(context, db, flags, entry);
+ return hdb_samba4_seq(context, db, flags, entry);
}
-static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
{
talloc_free(db);
return 0;
}
+krb5_error_code hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db,
+ hdb_entry_ex *entry,
+ krb5_const_principal target_principal)
+{
+ struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
+ struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb_ctx, "loadparm"),
+ struct loadparm_context);
+ krb5_error_code ret;
+ krb5_principal enterprise_prinicpal = NULL;
+ struct ldb_dn *realm_dn;
+ struct ldb_message *msg;
+ struct dom_sid *orig_sid;
+ struct dom_sid *target_sid;
+ struct hdb_ldb_private *p = talloc_get_type(entry->ctx, struct hdb_ldb_private);
+ const char *delegation_check_attrs[] = {
+ "objectSid", NULL
+ };
+
+ TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_check_constrained_delegation");
+
+ if (!mem_ctx) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
+ return ret;
+ }
+
+ if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+ /* Need to reparse the enterprise principal to find the real target */
+ if (target_principal->name.name_string.len != 1) {
+ ret = KRB5_PARSE_MALFORMED;
+ krb5_set_error_message(context, ret, "hdb_samba4_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components",
+ target_principal->name.name_string.len);
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ ret = krb5_parse_name(context, target_principal->name.name_string.val[0],
+ &enterprise_prinicpal);
+ if (ret) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ target_principal = enterprise_prinicpal;
+ }
+
+ ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, target_principal,
+ delegation_check_attrs, &realm_dn, &msg);
+
+ krb5_free_principal(context, enterprise_prinicpal);
+
+ if (ret != 0) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
+ target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
+
+ /* Allow delegation to the same principal, even if by a different
+ * name. The easy and safe way to prove this is by SID
+ * comparison */
+ if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) {
+ talloc_free(mem_ctx);
+ return KRB5KDC_ERR_BADOPTION;
+ }
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
/* This interface is to be called by the KDC, which is expecting Samba
* calling conventions. It is also called by a wrapper
* (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
}
(*db)->hdb_dbc = NULL;
- (*db)->hdb_open = LDB_open;
- (*db)->hdb_close = LDB_close;
- (*db)->hdb_fetch = LDB_fetch;
- (*db)->hdb_store = LDB_store;
- (*db)->hdb_remove = LDB_remove;
- (*db)->hdb_firstkey = LDB_firstkey;
- (*db)->hdb_nextkey = LDB_nextkey;
- (*db)->hdb_lock = LDB_lock;
- (*db)->hdb_unlock = LDB_unlock;
- (*db)->hdb_rename = LDB_rename;
+ (*db)->hdb_open = hdb_samba4_open;
+ (*db)->hdb_close = hdb_samba4_close;
+ (*db)->hdb_fetch = hdb_samba4_fetch;
+ (*db)->hdb_store = hdb_samba4_store;
+ (*db)->hdb_remove = hdb_samba4_remove;
+ (*db)->hdb_firstkey = hdb_samba4_firstkey;
+ (*db)->hdb_nextkey = hdb_samba4_nextkey;
+ (*db)->hdb_lock = hdb_samba4_lock;
+ (*db)->hdb_unlock = hdb_samba4_unlock;
+ (*db)->hdb_rename = hdb_samba4_rename;
/* we don't implement these, as we are not a lockable database */
(*db)->hdb__get = NULL;
(*db)->hdb__put = NULL;
/* kadmin should not be used for deletes - use other tools instead */
(*db)->hdb__del = NULL;
- (*db)->hdb_destroy = LDB_destroy;
+ (*db)->hdb_destroy = hdb_samba4_destroy;
+
+ (*db)->hdb_auth_status = NULL;
+ (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation;
return NT_STATUS_OK;
}
*/
#include "includes.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "lib/ldb/include/ldb.h"
#include "librpc/gen_ndr/ndr_krb5pac.h"
#include "librpc/gen_ndr/krb5pac.h"
if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to load modules for %s: %s\n",
+ "Unable to load modules for %s: %s",
url, ldb_errstring(ldb));
return LDB_ERR_OTHER;
}
{
if (level <= LDB_DEBUG_WARNING) {
vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
}
}
}
}
if (!ldb_changetypes[i].name) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d",
ldif->changetype);
talloc_free(mem_ctx);
return -1;
/* first line must be a dn */
if (ldb_attr_cmp(attr, "dn") != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'",
attr);
goto failed;
}
msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value);
if ( ! ldb_dn_validate(msg->dn)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'",
(char *)value.data);
goto failed;
}
}
}
if (!ldb_changetypes[i].name) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: Bad ldif changetype '%s'\n",(char *)value.data);
+ ldb_debug(ldb, LDB_DEBUG_ERROR,
+ "Error: Bad ldif changetype '%s'",(char *)value.data);
}
flags = 0;
continue;
}
if (value.length == 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: Attribute value cannot be empty for attribute '%s'\n", el->name);
+ "Error: Attribute value cannot be empty for attribute '%s'", el->name);
goto failed;
}
if (value.data != el->values[el->num_values].data) {
}
}
if (comp == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
tree->u.extended.rule_id);
return -1;
}
/* spaces not admitted */
modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
if ( ! modstr) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()");
return NULL;
}
modules = talloc_realloc(mem_ctx, modules, char *, 2);
if ( ! modules ) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
talloc_free(modstr);
return NULL;
}
i++;
modules = talloc_realloc(mem_ctx, modules, char *, i + 2);
if ( ! modules ) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
return NULL;
}
if (fn == NULL) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to find backend for '%s'\n", url);
+ "Unable to find backend for '%s'", url);
return LDB_ERR_OTHER;
}
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Failed to connect to '%s'\n", url);
+ "Failed to connect to '%s'", url);
return ret;
}
return ret;
path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name,
SHLIBEXT);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path);
handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror());
return NULL;
}
sym = (int (*)(void))dlsym(handle, symbol);
if (sym == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s\n", symbol, path, dlerror());
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror());
return NULL;
}
}
if (ops == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n",
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found",
module_list[i]);
continue;
}
if (module) {
int ret = module->ops->init_context(module);
if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed\n", module->ops->name);
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name);
return ret;
}
}
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
} else if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb));
talloc_free(mem_ctx);
return ret;
} else {
if (res->count == 0) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
} else if (res->count > 1) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out", res->count);
talloc_free(mem_ctx);
return -1;
} else {
pyldb.o: $(ldbdir)/pyldb.c
$(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-pyldb_util.o: $(ldbdir)/pyldb_util.c
- $(CC) $(PICFLAG) -c $(ldbdir)/pyldb_util.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-
-ldb.$(SHLIBEXT): pyldb.o pyldb_util.o
- $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o pyldb_util.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
+ldb.$(SHLIBEXT): pyldb.o
+ $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
install-python:: build-python
mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-modulesdir=@modulesdir@
+modulesdir=@LDB_MODULESDIR@
Name: ldb
Description: An LDAP-like embedded database
status = ldap_connect(ildb->ldap, url);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s",
url, ldap_errstr(ildb->ldap, module, status));
goto failed;
}
const char *password = cli_credentials_get_password(creds);
status = ldap_bind_simple(ildb->ldap, bind_dn, password);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
} else {
status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
}
if (req->controls != NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n");
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!");
}
ldb_request_set_state(req, LDB_ASYNC_PENDING);
ret = ldap_initialize(&lldb->ldap, url);
if (ret != LDAP_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s",
url, ldap_err2string(ret));
goto failed;
}
ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
if (ret != LDAP_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s",
ldap_err2string(ret));
goto failed;
}
default:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Invalid remote request!\n");
+ "Invalid remote request!");
return LDB_ERR_OPERATIONS_ERROR;
}
case MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
case MAP_CONVERT:
if (map->u.convert.convert_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"'convert_local' not set for attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
/* fall through */
case MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
case MAP_CONVERT:
if (map->u.convert.convert_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"'convert_remote' not set for attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
/* fall through */
dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name);
if ( ! ldb_dn_validate(dn)) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Failed to construct '%s' DN!\n", MAP_DN_NAME);
+ "Failed to construct '%s' DN!", MAP_DN_NAME);
return LDB_ERR_OPERATIONS_ERROR;
}
}
if (res->count == 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "No results for '%s=%s'!\n", MAP_DN_NAME, name);
+ "No results for '%s=%s'!", MAP_DN_NAME, name);
talloc_free(res);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
if (res->count > 1) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Too many results for '%s=%s'!\n", MAP_DN_NAME, name);
+ "Too many results for '%s=%s'!", MAP_DN_NAME, name);
talloc_free(res);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
/* Unknown attribute: ignore */
if (map == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
- "Not mapping attribute '%s': no mapping found\n",
+ "Not mapping attribute '%s': no mapping found",
old->name);
goto local;
}
if (map->u.convert.convert_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
- "'convert_local' not set\n",
+ "'convert_local' not set",
map->local_name);
goto local;
}
if (map->u.generate.generate_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
- "'generate_remote' not set\n",
+ "'generate_remote' not set",
map->local_name);
goto local;
}
/* Skip 'IS_MAPPED' */
if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
- "Skipping attribute '%s'\n",
+ "Skipping attribute '%s'",
msg->elements[i].name);
continue;
}
if (map->u.convert.convert_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
- "'convert_remote' not set\n",
+ "'convert_remote' not set",
attr_name);
return LDB_SUCCESS;
}
if (map->u.generate.generate_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
- "'generate_local' not set\n",
+ "'generate_local' not set",
attr_name);
return LDB_SUCCESS;
}
if (map->type == MAP_GENERATE) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Skipping attribute '%s': "
- "'convert_operator' not set\n",
+ "'convert_operator' not set",
tree->u.equality.attr);
*new = NULL;
return 0;
ac->req->op.search.scope)) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "
"Skipping record '%s': "
- "doesn't match original search\n",
+ "doesn't match original search",
ldb_dn_get_linearized(ares->message->dn));
return LDB_SUCCESS;
}
const struct ldb_schema_syntax *s;
if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name);
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name);
goto failed;
}
switch (flags & ~LTDB_FLAG_HIDDEN) {
break;
default:
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n",
+ "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES",
flags, msg->elements[i].name);
goto failed;
}
s = ldb_standard_syntax_by_name(ldb, syntax);
if (s == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n",
+ "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES",
syntax, msg->elements[i].name);
goto failed;
}
struct ldb_ldif ldif;
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "ERROR: dn %s not found in %s\n", dn,
+ "ERROR: dn %s not found in %s", dn,
ldb_dn_get_linearized(dn_key));
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msg;
key2 = ltdb_key(module, msg->dn);
if (key2.dptr == NULL) {
/* probably a corrupt record ... darn */
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
ldb_dn_get_linearized(msg->dn));
talloc_free(msg);
return 0;
ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
} else {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Adding special ONE LEVEL index failed (%s)!\n",
+ "Adding special ONE LEVEL index failed (%s)!",
ldb_dn_get_linearized(msg->dn));
}
if (remaining != 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: %d bytes unread in ltdb_unpack_data\n", remaining);
+ "Error: %d bytes unread in ltdb_unpack_data", remaining);
}
return 0;
ldb_get_create_perms(ldb), ldb);
if (!ltdb->tdb) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Unable to open tdb '%s'\n", path);
+ "Unable to open tdb '%s'", path);
talloc_free(ltdb);
return -1;
}
ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID);
if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n");
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!");
}
return ldb_next_init(module);
return 0;
failed:
- ldb_debug_set(ldb, LDB_DEBUG_WARNING,
- "operational_search_post_process failed for attribute '%s'\n",
+ ldb_debug_set(ldb, LDB_DEBUG_WARNING,
+ "operational_search_post_process failed for attribute '%s'",
attrs[a]);
return -1;
}
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"paged_results:"
- "Unable to register control with rootdse!\n");
+ "Unable to register control with rootdse!");
}
return ldb_next_init(module);
int i, ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n");
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.add.message->dn)) {
int ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n");
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.rename.newdn)) {
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"server_sort:"
- "Unable to register control with rootdse!\n");
+ "Unable to register control with rootdse!");
}
return ldb_next_init(module);
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
#endif
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+ if (ret == LDB_ERR_PYTHON_EXCEPTION)
+ return; /* Python exception should already be set, just keep that */
+
+ PyErr_SetObject(error,
+ Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
+ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
+
static PyObject *PyExc_LdbError;
PyAPI_DATA(PyTypeObject) PyLdbMessage;
PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
#define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
-void PyErr_SetLdbError(PyObject *exctype, int ret, struct ldb_context *ldb_ctx);
#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \
if (ret != LDB_SUCCESS) { \
PyErr_SetLdbError(err, ret, ldb); \
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
-
- interface to ldb.
-
- Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "replace.h"
-#include <Python.h>
-#include "pyldb.h"
-#include <ldb.h>
-
-void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
-{
- if (ret == LDB_ERR_PYTHON_EXCEPTION)
- return; /* Python exception should already be set, just keep that */
-
- PyErr_SetObject(error,
- Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
- ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
-}
[PYTHON::pyldb]
LIBRARY_REALNAME = ldb.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBLDB PYTALLOC
-PRIVATE_DEPENDENCIES = pyldb_util
pyldb_OBJ_FILES = $(ldbsrcdir)/pyldb.o
$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
-
-[SUBSYSTEM::pyldb_util]
-PUBLIC_DEPENDENCIES = LIBPYTHON
-PRIVATE_DEPENDENCIES = LIBLDB
-
-pyldb_util_OBJ_FILES = $(ldbsrcdir)/pyldb_util.o
-$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
showflags::
@echo 'ldb will be compiled with flags:'
@echo ' CFLAGS = $(CFLAGS)'
+ @echo ' SHLD_FLAGS = $(SHLD_FLAGS)'
@echo ' LIBS = $(LIBS)'
distclean::
if (read(fd, &hdr, 4) != 4) {
DEBUG(0, ("Error reading registry patch file `%s'\n",
filename));
+ close(fd);
return WERR_GENERAL_FAILURE;
}
For example, the first file in this directory (smbpasswd.c) handles
portions of the smbpasswd file format.
-
-The other files in this directory support reading the various
-TDB databases from Samba3.
+++ /dev/null
---- Samba3 -> Samba4 Upgrade ---
-(C) 2005 Jelmer Vernooij <jelmer@samba.org>
-Published under the GNU GPL
-
-Sponsored by the Google Summer of Code program (http://code.google.com/summerofcode.html)
-Mentored by Andrew Bartlett <abartlet@samba.org>
-Thanks!
-
-Done:
- - Reading wins.dat
- - Reading registry.tdb
- - Reading passdb.tdb
- - Reading account_policy.tdb
- - Reading group_mappings.tdb
- - Reading winbindd_idmap.tdb
- - Reading share_info.tdb
- - Reading secrets.tdb
- - Reading smbpasswd
- - Reading + writing (generic) smb.conf files
- - Testsuite for read support mentioned above
- - Console utility for dumping Samba information
- - Import user accounts in Samba4
- - Import groups in Samba4
- - Import secrets in Samba4
- - Import WINS data in Samba4
- - Dump idmap data to LDB
- - Import registry keys/values in Samba4
- - Import account policies in Samba4
- - Testsuite for upgrade
- - Console utility from upgrading from Samba3 -> Samba4
- - SWAT (Web interface) support for upgrading from Samba3 -> Samba4
- - LDB generic mapping module
- - (Experimental) Samba4 LDB <-> Samba3 LDAP mapping module based on LDB generic mapping module
- - Testsuite for Samba4 LDB <-> Samba3 LDAP mapping module
-
-Source files:
-source/lib/ldb/modules/ldb_map.c
-source/lib/ldb/modules/ldb_map.h
-source/lib/samba3/group.c
-source/lib/samba3/idmap.c
-source/lib/samba3/policy.c
-source/lib/samba3/registry.c
-source/lib/samba3/samba3.c
-source/lib/samba3/secrets.c
-source/lib/samba3/share_info.c
-source/lib/samba3/smbpasswd.c
-source/lib/samba3/tdbsam.c
-source/lib/samba3/winsdb.c
-source/lib/samba3/samba3.h
-source/scripting/libjs/upgrade.js
-source/scripting/ejs/smbcalls_param.c
-source/scripting/ejs/smbcalls_samba3.c
-source/param/generic.c
-source/param/generic.h
-testdata/samba3/verify
-testprogs/ejs/samba3sam
-source/setup/upgrade
-source/scripting/bin/samba3dump
-source/dsdb/samdb/ldb_modules/samba3sam.c
-source/script/tests/test_s3upgrade.sh
-swat/install/samba3.esp
-
-Known remaining issues:
- - [upgrade] Conversion from the smbpasswd/TDB passwords to ntPwdHash / lmPwdHash is broken. Couldn't find out why.
- - [ldb_map] Conversion of attribute names in DN's is still a bit dodgy
- - [ldb_map] mapped objectClass names may be mentioned multiple times in returned records
- - [ldb_map] add/modify support not tested very well with LDAP yet (only LDB+TDB)
- - [ldb_map] group membership is not yet mapped (only primaryGroupID / sambaPrimaryGroupSID)
#include "librpc/gen_ndr/security.h"
#include "librpc/gen_ndr/samr.h"
-#include "param/param.h"
struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, const char *p);
char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info);
/*
Unix SMB/CIFS implementation.
- security descriptror utility functions
+ security descriptor utility functions
Copyright (C) Andrew Tridgell 2004
Copyright (C) Stefan Metzmacher 2005
req = talloc(transport, struct smb2_request);
if (req == NULL) return NULL;
- seqnum = transport->seqnum++;
- if (seqnum == UINT64_MAX) {
- seqnum = transport->seqnum++;
+ seqnum = transport->seqnum;
+ if (transport->credits.charge > 0) {
+ transport->seqnum += transport->credits.charge;
+ } else {
+ transport->seqnum += 1;
}
req->state = SMB2_REQUEST_INIT;
SIVAL(req->out.hdr, 0, SMB2_MAGIC);
SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
- SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0);
+ SSVAL(req->out.hdr, SMB2_HDR_EPOCH, transport->credits.charge);
SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0);
SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode);
SSVAL(req->out.hdr, SMB2_HDR_CREDIT, transport->credits.ask_num);
} compound;
struct {
+ uint16_t charge;
uint16_t ask_num;
} credits;
transport->socket = talloc_steal(transport, sock);
transport->options = *options;
+ transport->credits.charge = 0;
transport->credits.ask_num = 1;
/* setup the stream -> packet parser */
transport->credits.ask_num = ask_num;
}
+void smb2_transport_credits_set_charge(struct smb2_transport *transport,
+ uint16_t charge)
+{
+ transport->credits.charge = charge;
+}
+
static void idle_handler(struct tevent_context *ev,
struct tevent_timer *te, struct timeval t, void *private_data)
{
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_misc.h"
/* store the arguments in the state structure */
s->ctx = ctx;
s->page_size = io->in.page_size;
- s->resume_index = (uint32_t)io->in.resume_index;
+ s->resume_index = io->in.resume_index;
s->domain_name = talloc_strdup(c, io->in.domain_name);
s->monitor_fn = monitor;
struct {
const char *domain_name;
int page_size;
- uint resume_index;
+ uint32_t resume_index;
} in;
struct {
int count;
- uint resume_index;
+ uint32_t resume_index;
struct grouplist {
const char *sid;
#include "../lib/util/dlinklist.h"
#include "samba3/samba3.h"
#include "libcli/security/security.h"
+#include "param/param.h"
struct samdump_secret {
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "param/param.h"
/* store the arguments in the state structure */
s->ctx = ctx;
s->page_size = r->in.page_size;
- s->resume_index = (uint32_t)r->in.resume_index;
+ s->resume_index = r->in.resume_index;
s->domain_name = talloc_strdup(c, r->in.domain_name);
s->monitor_fn = monitor;
struct {
const char *domain_name;
int page_size;
- uint resume_index;
+ uint32_t resume_index;
} in;
struct {
int count;
- uint resume_index;
+ uint32_t resume_index;
struct userlist {
const char *sid;
NDR_WINSTATION_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winstation.o
-[SUBSYSTEM::NDR_ECHO]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o
-
[SUBSYSTEM::NDR_IRPC]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT
NDR_ROT_OBJ_FILES = ../librpc/gen_ndr/ndr_rot.o
-[SUBSYSTEM::NDR_LSA]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
-
-NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/lsa.h
-
-[SUBSYSTEM::NDR_DFS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs.o
-
[SUBSYSTEM::NDR_FRSRPC]
PUBLIC_DEPENDENCIES = LIBNDR
-NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o
+NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o ../librpc/ndr/ndr_frsrpc.o
[SUBSYSTEM::NDR_FRSAPI]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_FRSAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_frsapi.o
+[SUBSYSTEM::NDR_FRSTRANS]
+PUBLIC_DEPENDENCIES = LIBNDR
+
+NDR_FRSTRANS_OBJ_FILES = ../librpc/gen_ndr/ndr_frstrans.o
+
[SUBSYSTEM::NDR_DRSUAPI]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
+PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_STANDARD ASN1_UTIL
NDR_DRSUAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o
NDR_UNIXINFO_OBJ_FILES = ../librpc/gen_ndr/ndr_unixinfo.o
-[SUBSYSTEM::NDR_SAMR]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
-
-NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h ndr_samr_c.h)
-
[SUBSYSTEM::NDR_NFS4ACL]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_SPOOLSS_BUF_OBJ_FILES = ../librpc/ndr/ndr_spoolss_buf.o
-[SUBSYSTEM::NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY
-
-NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc.o
-
-[SUBSYSTEM::NDR_SRVSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY
-
-NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc.o
-
-[SUBSYSTEM::NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl.o ../librpc/ndr/ndr_svcctl.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, ndr_svcctl.h svcctl.h)
-
-[SUBSYSTEM::NDR_ATSVC]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h)
-
-[SUBSYSTEM::NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
-
-NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog.o
-
[SUBSYSTEM::NDR_EPMAPPER]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o
-[SUBSYSTEM::NDR_WINREG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY
-
-NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg.o
-
-[SUBSYSTEM::NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown.o
-
[SUBSYSTEM::NDR_MGMT]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc.o
-[SUBSYSTEM::NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o
-
-[SUBSYSTEM::NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY
-
-NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/netlogon.h
-
[SUBSYSTEM::NDR_TRKWKS]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc.o
[SUBSYSTEM::NDR_KRB5PAC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_SECURITY
NDR_KRB5PAC_OBJ_FILES = ../librpc/gen_ndr/ndr_krb5pac.o ../librpc/ndr/ndr_krb5pac.o
NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
[SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON
NDR_NBT_OBJ_FILES = ../librpc/gen_ndr/ndr_nbt.o
NDR_WINSREPL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winsrepl.o
[SUBSYSTEM::NDR_WINBIND]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD
NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o
#PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h
@$(PERL) ../librpc/tables.pl --output=$@ $^ > $(gen_ndrsrcdir)/tables.x
@mv $(gen_ndrsrcdir)/tables.x $@
+[LIBRARY::NDR_STANDARD]
+PUBLIC_DEPENDENCIES = LIBNDR
+PRIVATE_DEPENDENCIES = NDR_SECURITY
+
+NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \
+ ../librpc/gen_ndr/ndr_lsa.o \
+ ../librpc/gen_ndr/ndr_samr.o \
+ ../librpc/gen_ndr/ndr_netlogon.o \
+ ../librpc/ndr/ndr_netlogon.o \
+ ../librpc/gen_ndr/ndr_dfs.o \
+ ../librpc/gen_ndr/ndr_atsvc.o \
+ ../librpc/gen_ndr/ndr_wkssvc.o \
+ ../librpc/gen_ndr/ndr_srvsvc.o \
+ ../librpc/gen_ndr/ndr_svcctl.o \
+ ../librpc/ndr/ndr_svcctl.o \
+ ../librpc/gen_ndr/ndr_winreg.o \
+ ../librpc/gen_ndr/ndr_initshutdown.o \
+ ../librpc/gen_ndr/ndr_eventlog.o \
+ ../librpc/gen_ndr/ndr_ntsvcs.o
+
+PC_FILES += $(librpcsrcdir)/ndr_standard.pc
+
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h atsvc.h ndr_atsvc.h ndr_svcctl.h svcctl.h)
+
+NDR_STANDARD_VERSION = 0.0.1
+NDR_STANDARD_SOVERSION = 0
+
[SUBSYSTEM::NDR_TABLE]
PUBLIC_DEPENDENCIES = \
- NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \
- NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \
- NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \
- NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
- NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
- NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \
- NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
- NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \
- NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
- NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \
+ NDR_STANDARD \
+ NDR_AUDIOSRV \
+ NDR_DSBACKUP NDR_EFS NDR_DRSUAPI \
+ NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS \
+ NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
+ NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
+ NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC \
+ NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
+ NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \
+ NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
+ NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND \
+ NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS \
+ NDR_NFS4ACL NDR_NTP_SIGND \
NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH
NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
RPC_NDR_AUDIOSRV_OBJ_FILES = ../librpc/gen_ndr/ndr_audiosrv_c.o
[SUBSYSTEM::RPC_NDR_ECHO]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ECHO
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo_c.o
RPC_NDR_EFS_OBJ_FILES = ../librpc/gen_ndr/ndr_efs_c.o
[SUBSYSTEM::RPC_NDR_LSA]
-PUBLIC_DEPENDENCIES = dcerpc NDR_LSA
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa_c.o
[SUBSYSTEM::RPC_NDR_DFS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_DFS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs_c.o
RPC_NDR_IRPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_irpc_c.o
[LIBRARY::dcerpc_samr]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SAMR
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
PC_FILES += $(librpcsrcdir)/dcerpc_samr.pc
dcerpc_samr_SOVERSION = 0
dcerpc_samr_OBJ_FILES = ../librpc/gen_ndr/ndr_samr_c.o
+PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_samr_c.h
+
[SUBSYSTEM::RPC_NDR_SPOOLSS]
PUBLIC_DEPENDENCIES = dcerpc NDR_SPOOLSS
RPC_NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss_c.o
[SUBSYSTEM::RPC_NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WKSSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc_c.o
RPC_NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc_c.o
[SUBSYSTEM::RPC_NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SVCCTL
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl_c.o
PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_svcctl_c.h
[LIBRARY::dcerpc_atsvc]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ATSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
dcerpc_atsvc_VERSION = 0.0.1
dcerpc_atsvc_SOVERSION = 0
PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_atsvc_c.h
[SUBSYSTEM::RPC_NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_EVENTLOG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog_c.o
RPC_NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins_c.o
[SUBSYSTEM::RPC_NDR_WINREG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WINREG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg_c.o
[SUBSYSTEM::RPC_NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = dcerpc NDR_INITSHUTDOWN
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown_c.o
RPC_NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc_c.o
[SUBSYSTEM::RPC_NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_NTSVCS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs_c.o
[SUBSYSTEM::RPC_NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = NDR_NETLOGON
+PUBLIC_DEPENDENCIES = NDR_STANDARD
RPC_NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon_c.o
os_ex.major = server_info->version_major;
os_ex.minor = server_info->version_minor;
os_ex.build = server_info->version_build;
- os_ex.extra_string = "";
- os_ex.unknown2 = 0;
- os_ex.unknown3 = 0;
+ os_ex.extra_string = "";
+ os_ex.service_pack_major= 0;
+ os_ex.service_pack_minor= 0;
+ os_ex.suite_mask = 0;
+ os_ex.product_type = 0;
+ os_ex.reserved = 0;
ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
one of the interfaces attached to this pipe endpoint.
*/
ep_description->transport = NCACN_NP;
- ep_description->endpoint = talloc_reference(ep_description, p->pipe_name);
+ ep_description->endpoint = talloc_strdup(ep_description, p->pipe_name);
+ NT_STATUS_HAVE_NO_MEMORY(ep_description->endpoint);
/* The session info is refcount-increased in the
* dcesrv_endpoint_search_connect() function
(*name)->has_wildcard = false;
/* we can't get the correct 'original_name', but for the purposes
of this call this is close enough */
- (*name)->original_name = talloc_reference(*name, child->original_name);
+ (*name)->original_name = talloc_strdup(*name, child->original_name);
+ if ((*name)->original_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
(*name)->stream_name = NULL;
(*name)->stream_id = 0;
return NT_STATUS_INTERNAL_ERROR;
}
- ntvfs->private_data = priv;
priv->last_sec_ctx = NULL;
priv->last_token = NULL;
+ ntvfs->private_data = priv;
tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx,
unixuid_event_nesting_hook,
[MODULE::dcerpc_rpcecho]
INIT_FUNCTION = dcerpc_server_rpcecho_init
SUBSYSTEM = dcerpc_server
-PRIVATE_DEPENDENCIES = NDR_ECHO LIBEVENTS
+PRIVATE_DEPENDENCIES = NDR_STANDARD LIBEVENTS
# End MODULE dcerpc_rpcecho
################################################
INIT_FUNCTION = dcerpc_server_wkssvc_init
SUBSYSTEM = dcerpc_server
PRIVATE_DEPENDENCIES = \
- DCERPC_COMMON NDR_WKSSVC
+ DCERPC_COMMON NDR_STANDARD
# End MODULE dcerpc_wkssvc
################################################
PRIVATE_DEPENDENCIES = \
SAMDB \
DCERPC_COMMON \
- NDR_SAMR
+ NDR_STANDARD
# End MODULE dcesrv_samr
################################################
SUBSYSTEM = dcerpc_server
OUTPUT_TYPE = MERGED_OBJ
PRIVATE_DEPENDENCIES = \
- registry NDR_WINREG
+ registry NDR_STANDARD
# End MODULE dcerpc_winreg
################################################
PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SCHANNELDB \
- NDR_NETLOGON \
+ NDR_STANDARD \
auth_sam \
LIBSAMBA-HOSTCONFIG
# End MODULE dcerpc_netlogon
PRIVATE_DEPENDENCIES = \
SAMDB \
DCERPC_COMMON \
- NDR_LSA \
+ NDR_STANDARD \
LIBCLI_AUTH \
NDR_DSSETUP
# End MODULE dcerpc_lsa
= samdb_result_uint(msg, "posixOffset", 0);
return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
info->enc_types.enc_types
= samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
break;
atype = samdb_result_uint(res[i], "sAMAccountType", 0);
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
if (*rtype == SID_NAME_UNKNOWN) {
return STATUS_SOME_UNMAPPED;
}
atype = samdb_result_uint(res[0], "sAMAccountType", 0);
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
return NT_STATUS_OK;
}
#include "auth/auth.h"
#include "auth/auth_sam_reply.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "rpc_server/samr/proto.h"
#include "../lib/util/util_ldb.h"
#include "libcli/auth/libcli_auth.h"
}
/* pull the user attributes */
- num_records = gendb_search((struct ldb_context *)sam_ctx,
- mem_ctx, NULL, &msgs,
+ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
trust_dom_attrs,
"(&(trustPartner=%s)(objectclass=trustedDomain))",
encoded_account);
}
/* pull the user attributes */
- num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
- NULL, &msgs, attrs,
+ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
ldb_binary_encode_string(mem_ctx, account_name));
struct netr_GetDcName *r)
{
const char * const attrs[] = { NULL };
- void *sam_ctx;
+ struct ldb_context *sam_ctx;
struct ldb_message **res;
struct ldb_dn *domain_dn;
int ret;
return WERR_DS_SERVICE_UNAVAILABLE;
}
- domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
r->in.domainname);
if (domain_dn == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
- ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ ret = gendb_search_dn(sam_ctx, mem_ctx,
domain_dn, &res, attrs);
if (ret != 1) {
return WERR_NO_SUCH_DOMAIN;
struct netr_DsrEnumerateDomainTrusts *r)
{
struct netr_DomainTrustList *trusts;
- void *sam_ctx;
+ struct ldb_context *sam_ctx;
int ret;
struct ldb_message **dom_res;
const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
return WERR_GENERAL_FAILURE;
}
- ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
+ ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
&dom_res, dom_attrs);
if (ret == -1) {
return WERR_GENERAL_FAILURE;
#include "system/time.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/ldap/ldap_ndr.h"
#include "libcli/security/security.h"
UF_INTERDOMAIN_TRUST_ACCOUNT |
UF_WORKSTATION_TRUST_ACCOUNT |
UF_SERVER_TRUST_ACCOUNT));
- user_account_control |= samdb_acb2uf(r->in.acct_flags);
+ user_account_control |= ds_acb2uf(r->in.acct_flags);
talloc_free(msg);
msg = ldb_msg_new(mem_ctx);
continue;
}
- rtype = samdb_atype_map(atype);
+ rtype = ds_atype_map(atype);
if (rtype == SID_NAME_UNKNOWN) {
status = STATUS_SOME_UNMAPPED;
continue;
}
- ids[i] = samdb_atype_map(atype);
+ ids[i] = ds_atype_map(atype);
if (ids[i] == SID_NAME_UNKNOWN) {
status = STATUS_SOME_UNMAPPED;
#include "rpc_server/samr/dcesrv_samr.h"
#include "system/time.h"
#include "../lib/crypto/crypto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "libcli/ldap/ldap.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
echo "Installing setup templates"
mkdir -p $SETUPDIR || exit 1
+mkdir -p $SETUPDIR/ad-schema || exit 1
+cp setup/ad-schema/*.txt $SETUPDIR/ad-schema || exit 1
+for p in enableaccount newuser provision provision-backend setexpiry setpassword
+do
+ chmod 0555 setup/$p
+ cp setup/$p $SETUPDIR || exit 1
+done
cp setup/schema-map-* $SETUPDIR || exit 1
cp setup/DB_CONFIG $SETUPDIR || exit 1
-cp setup/provision-backend $SETUPDIR || exit 1
-cp setup/provision $SETUPDIR || exit 1
-cp setup/newuser $SETUPDIR || exit 1
cp setup/*.inf $SETUPDIR || exit 1
cp setup/*.ldif $SETUPDIR || exit 1
cp setup/*.reg $SETUPDIR || exit 1
} */\
ldb = PyLdb_AsLdbContext(py_ldb);
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+ if (ret == LDB_ERR_PYTHON_EXCEPTION)
+ return; /* Python exception should already be set, just keep that */
+
+ PyErr_SetObject(error,
+ Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
+ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
static PyObject *py_ldb_get_exception(void)
{
Py_RETURN_NONE;
}
+static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
+{
+ PyObject *py_ldb;
+ int value;
+ int *old_val, *new_val;
+ char *py_opaque_name, *opaque_name_talloc;
+ struct ldb_context *ldb;
+ TALLOC_CTX *tmp_ctx;
+
+ if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
+ return NULL;
+
+ PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+ /* see if we have a cached copy */
+ old_val = (int *)ldb_get_opaque(ldb,
+ py_opaque_name);
+
+ if (old_val) {
+ *old_val = value;
+ Py_RETURN_NONE;
+ }
+
+ tmp_ctx = talloc_new(ldb);
+ if (tmp_ctx == NULL) {
+ goto failed;
+ }
+
+ new_val = talloc(tmp_ctx, int);
+ if (!new_val) {
+ goto failed;
+ }
+
+ opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
+ if (!opaque_name_talloc) {
+ goto failed;
+ }
+
+ *new_val = value;
+
+ /* cache the domain_sid in the ldb */
+ if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
+ goto failed;
+ }
+
+ talloc_steal(ldb, new_val);
+ talloc_steal(ldb, opaque_name_talloc);
+ talloc_free(tmp_ctx);
+
+ Py_RETURN_NONE;
+
+failed:
+ talloc_free(tmp_ctx);
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
+ return NULL;
+}
+
static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
{
PyObject *py_ldb;
"Register Samba-specific LDB modules and schemas." },
{ "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
NULL },
+ { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
+ NULL },
{ "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
NULL },
{ "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS,
return;
PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
+
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2000", PyInt_FromLong(DS_BEHAVIOR_WIN2000));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003_INTERIM", PyInt_FromLong(DS_BEHAVIOR_WIN2003_INTERIM));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003", PyInt_FromLong(DS_BEHAVIOR_WIN2003));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2008", PyInt_FromLong(DS_BEHAVIOR_WIN2008));
+
}
import ldb
-import credentials
import glue
class Ldb(ldb.Ldb):
self.set_modules_dir(modules_dir)
elif default_ldb_modules_dir is not None:
self.set_modules_dir(default_ldb_modules_dir)
+ elif lp is not None:
+ self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb"))
if credentials is not None:
self.set_credentials(credentials)
return True
version = glue.version
+
+DS_BEHAVIOR_WIN2000 = glue.DS_BEHAVIOR_WIN2000
+DS_BEHAVIOR_WIN2003_INTERIM = glue.DS_BEHAVIOR_WIN2003_INTERIM
+DS_BEHAVIOR_WIN2003 = glue.DS_BEHAVIOR_WIN2003
+DS_BEHAVIOR_WIN2008 = glue.DS_BEHAVIOR_WIN2008
"""Support for parsing Samba-related command-line options."""
import optparse
-from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS
+from credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS
from hostconfig import Hostconfig
__docformat__ = "restructuredText"
__docformat__ = "restructuredText"
import samba
-import glue
-import ldb
class IDmapDB(samba.Ldb):
"""The IDmap database."""
assert(cn)
entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn])
entry.insert(1, ["objectClass", ["top", objectClass]])
+ entry.insert(2, ["cn", cn])
for l in entry:
key = l[0].lower()
import registry
import samba
from auth import system_session
-from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
+from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \
+ DS_BEHAVIOR_WIN2008
from samba.samdb import SamDB
from samba.idmap import IDmapDB
from samba.dcerpc import security
import urllib
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
- timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
+from ldb import SCOPE_SUBTREE, LdbError, timestring
from ms_schema import read_ms_schema
__docformat__ = "restructuredText"
def setup_self_join(samdb, names,
machinepass, dnspass,
domainsid, invocationid, setup_path,
- policyguid):
+ policyguid, domainControllerFunctionality):
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
"DNSPASS_B64": b64encode(dnspass),
"REALM": names.realm,
"DOMAIN": names.domain,
- "DNSDOMAIN": names.dnsdomain})
+ "DNSDOMAIN": names.dnsdomain,
+ "SAMBA_VERSION_STRING": version,
+ "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)})
setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {
"POLICYGUID": policyguid,
"DNSDOMAIN": names.dnsdomain,
:note: This will wipe the main SAM database file!
"""
+ domainFunctionality = DS_BEHAVIOR_WIN2008
+ forestFunctionality = DS_BEHAVIOR_WIN2008
+ domainControllerFunctionality = DS_BEHAVIOR_WIN2008
+
erase = (fill != FILL_DRS)
# Also wipes the database
return samdb
message("Pre-loading the Samba 4 and AD schema")
+
+ samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
+ samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
+ samdb.set_opaque_integer("domainControllerFunctionality", domainControllerFunctionality)
+
samdb.set_domain_sid(str(domainsid))
if serverrole == "domain controller":
samdb.set_invocation_id(invocationid)
"POLICYGUID": policyguid,
"DOMAINDN": names.domaindn,
"DOMAINGUID_MOD": domainguid_mod,
+ "DOMAIN_FUNCTIONALITY": str(domainFunctionality)
})
message("Adding configuration container (permitted to fail)")
"DOMAIN": names.domain,
"SCHEMADN": names.schemadn,
"DOMAINDN": names.domaindn,
- "SERVERDN": names.serverdn
+ "SERVERDN": names.serverdn,
+ "FOREST_FUNCTIONALALITY": str(forestFunctionality)
})
message("Setting up display specifiers")
dnspass=dnspass,
machinepass=machinepass,
domainsid=domainsid, policyguid=policyguid,
- setup_path=setup_path)
+ setup_path=setup_path, domainControllerFunctionality=domainControllerFunctionality)
except:
samdb.transaction_cancel()
class LdapSam(object):
"""Samba 3 LDAP passdb backend reader."""
def __init__(self, url):
- self.ldap_url = ldap_url
+ self.ldap_url = url
class TdbSam(TdbDatabase):
(k, v) = l.split("=", 1)
self._sections[section][self._sanitize_name(k)] = v
else:
- raise Error("Unable to parser line %d: %r" % (i+1,l))
+ raise Exception("Unable to parser line %d: %r" % (i+1,l))
def get(self, param, section=None):
"""Return the value of a parameter.
"""
glue.dsdb_set_ntds_invocation_id(self, invocation_id)
+ def set_opaque_integer(self, name, value):
+ """Set an integer as an opaque (a flag or other value) value on the database
+
+ :param name: The name for the opaque value
+ :param value: The integer value
+ """
+ glue.dsdb_set_opaque_integer(self, name, value)
+
def setexpiry(self, user, expiry_seconds, noexpiry):
"""Set the account expiry for a user
--- /dev/null
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation. Tests for shares
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+from samba.shares import SharesContainer
+from unittest import TestCase
+
+
+class MockService(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return self.data[name]
+
+
+class MockLoadParm(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return MockService(self.data[name])
+
+ def __contains__(self, name):
+ return name in self.data
+
+ def __len__(self):
+ return len(self.data)
+
+ def services(self):
+ return self.data.keys()
+
+
+class ShareTests(TestCase):
+
+ def _get_shares(self, conf):
+ return SharesContainer(MockLoadParm(conf))
+
+ def test_len_no_global(self):
+ shares = self._get_shares({})
+ self.assertEquals(0, len(shares))
+
+ def test_iter(self):
+ self.assertEquals([], list(self._get_shares({})))
+ self.assertEquals([], list(self._get_shares({"global":{}})))
+ self.assertEquals(["bla"], list(self._get_shares({"global":{}, "bla":{}})))
+
+ def test_len(self):
+ shares = self._get_shares({"global": {}})
+ self.assertEquals(0, len(shares))
+
+ def test_getitem_nonexistant(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "bla")
+
+ def test_getitem_global(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "global")
__docformat__ = "restructuredText"
-from provision import findnss, provision, FILL_DRS
+from provision import provision, FILL_DRS
import grp
import ldb
import time
import pwd
-import uuid
import registry
from samba import Ldb
-from samba.samdb import SamDB
+from samba.param import LoadParm
-def import_sam_policy(samldb, samba3_policy, domaindn):
+def import_sam_policy(samldb, policy, dn):
"""Import a Samba 3 policy database."""
samldb.modify_ldif("""
dn: %s
kept in the new configuration as "samba3:<name>"
"""
data = oldconf.data()
- newconf = param_init()
+ newconf = LoadParm()
for s in data:
for p in data[s]:
rpc.netlogon.*.ServerGetTrustInfo
samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet
samba4.rpc.samr.users.privileges
+samba4.rpc.spoolss.printer # Not provided by Samba 4 yet
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import getopt
import optparse
-import os
import sys
# Find right directory when running from source tree
from samba.credentials import DONT_USE_KERBEROS
from samba.auth import system_session
import samba.getopt as options
-from samba import param
from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir
# how do we make this case insensitive??
if opts.interactive:
from getpass import getpass
- import readline
import socket
def ask(prompt, default=None):
if default is not None:
+dn: CN=Builtin,${DOMAINDN}
+objectClass: top
+objectClass: builtinDomain
+forceLogoff: -9223372036854775808
+lockoutDuration: -18000000000
+lockOutObservationWindow: -18000000000
+lockoutThreshold: 0
+maxPwdAge: -37108517437440
+minPwdAge: 0
+minPwdLength: 0
+modifiedCountAtLastProm: 0
+nextRid: 1000
+pwdProperties: 0
+pwdHistoryLength: 0
+objectSid: S-1-5-32
+serverState: 1
+uASCompat: 1
+modifiedCount: 1
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
+
dn: OU=Domain Controllers,${DOMAINDN}
objectClass: top
objectClass: organizationalUnit
-cn: Domain Controllers
description: Default container for domain controllers
systemFlags: -1946157056
isCriticalSystemObject: TRUE
dn: CN=ForeignSecurityPrincipals,${DOMAINDN}
objectClass: top
objectClass: container
-cn: ForeignSecurityPrincipals
description: Default container for security identifiers (SIDs) associated with objects from external, trusted domains
systemFlags: -1946157056
isCriticalSystemObject: TRUE
showInAdvancedViewOnly: FALSE
+dn: CN=Infrastructure,${DOMAINDN}
+objectClass: top
+objectClass: infrastructureUpdate
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+isCriticalSystemObject: TRUE
+
+dn: CN=LostAndFound,${DOMAINDN}
+objectClass: top
+objectClass: lostAndFound
+description: Default container for orphaned objects
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=NTDS Quotas,${DOMAINDN}
+objectClass: top
+objectClass: msDS-QuotaContainer
+description: Quota specifications container
+msDS-TombstoneQuotaFactor: 100
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of application data.
+
+dn: CN=Microsoft,CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of Microsoft application data.
+
dn: CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: System
description: Builtin system settings
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-dn: CN=RID Manager$,CN=System,${DOMAINDN}
-objectclass: top
-objectclass: rIDManager
-cn: RID Manager$
+dn: CN=AdminSDHolder,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-rIDAvailablePool: 4611686014132423217
+
+dn: CN=ComPartitions,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: leaf
+objectClass: domainPolicy
+isCriticalSystemObject: TRUE
+
+dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: classStore
+isCriticalSystemObject: TRUE
+
+dn: CN=Dfs-Configuration,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: dfsConfiguration
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
dn: CN=DomainUpdates,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: DomainUpdates
+
+dn: CN=Operations,CN=DomainUpdates,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
dn: CN=Windows2003Update,CN=DomainUpdates,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: Windows2003Update
revision: 8
-dn: CN=Infrastructure,${DOMAINDN}
-objectclass: top
-objectclass: infrastructureUpdate
-cn: Infrastructure
+dn: CN=File Replication Service,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: applicationSettings
+objectClass: nTFRSSettings
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-dn: CN=Builtin,${DOMAINDN}
+dn: CN=FileLinks,CN=System,${DOMAINDN}
objectClass: top
-objectClass: builtinDomain
-cn: Builtin
-forceLogoff: -9223372036854775808
-lockoutDuration: -18000000000
-lockOutObservationWindow: -18000000000
-lockoutThreshold: 0
-maxPwdAge: -37108517437440
-minPwdAge: 0
-minPwdLength: 0
-modifiedCountAtLastProm: 0
-nextRid: 1000
-pwdProperties: 0
-pwdHistoryLength: 0
-objectSid: S-1-5-32
-serverState: 1
-uASCompat: 1
-modifiedCount: 1
+objectClass: fileLinkTracking
+systemFlags: -1946157056
isCriticalSystemObject: TRUE
-showInAdvancedViewOnly: FALSE
+
+dn: CN=ObjectMoveTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackObjectMoveTable
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=VolumeTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackVolumeTable
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=IP Security,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
+
+dn: CN=Meetings,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
dn: CN=Policies,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
-dn: CN=IP Security,CN=System,${DOMAINDN}
+dn: CN=RAS and IAS Servers Access Check,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
-dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+dn: CN=RID Manager$,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: rIDManager
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+rIDAvailablePool: 4611686014132423217
+isCriticalSystemObject: TRUE
+
+dn: CN=RpcServices,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
+objectClass: rpcContainer
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Server,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: securityObject
+objectClass: samServer
+systemFlags: -1946157056
+revision: 65543
+isCriticalSystemObject: TRUE
+dn: CN=WinsockServices,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
serverState: 1
-
replace: nTMixedDomain
-nTMixedDomain: 1
+nTMixedDomain: 0
-
replace: msDS-Behavior-Version
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${DOMAIN_FUNCTIONALITY}
-
replace: ridManagerReference
ridManagerReference: CN=RID Manager$,CN=System,${DOMAINDN}
replace: systemFlags
systemFlags: -1946157056
-
-replace: isCriticalSystemObject
-isCriticalSystemObject: TRUE
--
replace: subRefs
subRefs: ${CONFIGDN}
-
wellKnownObjects: B:32:aa312825768811d1aded00c04fd8d5cd:CN=Computers,${DOMAINDN}
wellKnownObjects: B:32:a9d1ca15768811d1aded00c04fd8d5cd:CN=Users,${DOMAINDN}
-
+replace: isCriticalSystemObject
+isCriticalSystemObject: TRUE
+-
${DOMAINGUID_MOD}
replace: description
description: Default container for upgraded computer accounts
-
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
replace: systemFlags
systemFlags: -1946157056
-
replace: isCriticalSystemObject
isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
objectClass: crossRefContainer
cn: Partitions
systemFlags: -2147483648
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${FOREST_FUNCTIONALALITY}
fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+showInAdvancedViewOnly: TRUE
dn: CN=Enterprise Configuration,CN=Partitions,${CONFIGDN}
objectClass: top
-dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: leaf
-objectClass: domainPolicy
-isCriticalSystemObject: TRUE
-
-dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: classStore
-isCriticalSystemObject: TRUE
-
dn: CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
dnsHostName: ${DNSNAME}
ldapServiceName: ${DNSDOMAIN}:${NETBIOSNAME}$@${REALM}
serverName: ${SERVERDN}
-domainFunctionality: 0
-forestFunctionality: 0
-domainControllerFunctionality: 2
isSynchronized: FALSE
vendorName: Samba Team (http://samba.org)
supportedCapabilities: 1.2.840.113556.1.4.800
accountExpires: 9223372036854775807
sAMAccountName: ${NETBIOSNAME}$
operatingSystem: Samba
-operatingSystemVersion: 4.0
+operatingSystemVersion: ${SAMBA_VERSION_STRING}
dNSHostName: ${DNSNAME}
-isCriticalSystemObject: TRUE
userPassword:: ${MACHINEPASS_B64}
servicePrincipalName: HOST/${DNSNAME}
servicePrincipalName: HOST/${NETBIOSNAME}
servicePrincipalName: HOST/${NETBIOSNAME}/${REALM}
servicePrincipalName: HOST/${DNSNAME}/${DOMAIN}
servicePrincipalName: HOST/${NETBIOSNAME}/${DOMAIN}
+isCriticalSystemObject: TRUE
#Provide a account for DNS keytab export
dn: CN=dns,CN=Users,${DOMAINDN}
accountExpires: 9223372036854775807
sAMAccountName: dns
servicePrincipalName: DNS/${DNSDOMAIN}
-isCriticalSystemObject: TRUE
userPassword:: ${DNSPASS_B64}
-showInAdvancedViewOnly: TRUE
+isCriticalSystemObject: TRUE
dn: ${SERVERDN}
objectClass: top
systemFlags: 33554432
dMDLocation: ${SCHEMADN}
invocationId: ${INVOCATIONID}
-msDS-Behavior-Version: 2
+msDS-Behavior-Version: ${DOMAIN_CONTROLLER_FUNCTIONALITY}
msDS-hasMasterNCs: ${CONFIGDN}
msDS-hasMasterNCs: ${SCHEMADN}
msDS-hasMasterNCs: ${DOMAINDN}
adminCount: 1
accountExpires: 9223372036854775807
sAMAccountName: Administrator
-isCriticalSystemObject: TRUE
userPassword:: ${ADMINPASS_B64}
+isCriticalSystemObject: TRUE
dn: CN=Guest,CN=Users,${DOMAINDN}
objectClass: user
accountExpires: 9223372036854775807
sAMAccountName: krbtgt
servicePrincipalName: kadmin/changepw
-isCriticalSystemObject: TRUE
userPassword:: ${KRBTGTPASS_B64}
+isCriticalSystemObject: TRUE
dn: CN=Domain Computers,CN=Users,${DOMAINDN}
objectClass: top
groupType: -2147483644
isCriticalSystemObject: TRUE
-dn: CN=IIS_IUSRS,CN=Users,${DOMAINDN}
-objectClass: top
-objectClass: group
-cn: IIS_IUSRS
-description: IIS_IUSRS
-objectSid: ${DOMAINSID}-568
-sAMAccountName: IIS_IUSRS
-groupType: -2147483644
-isCriticalSystemObject: TRUE
-
dn: CN=Administrators,CN=Builtin,${DOMAINDN}
objectClass: top
objectClass: group
sAMAccountName: Administrators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeSecurityPrivilege
privilege: SeBackupPrivilege
privilege: SeRestorePrivilege
privilege: SeInteractiveLogonRight
privilege: SeNetworkLogonRight
privilege: SeRemoteInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Users,CN=Builtin,${DOMAINDN}
objectClass: top
sAMAccountName: Print Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeLoadDriverPrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Backup Operators,CN=Builtin,${DOMAINDN}
objectClass: top
sAMAccountName: Backup Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeBackupPrivilege
privilege: SeRestorePrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Replicator,CN=Builtin,${DOMAINDN}
objectClass: top
sAMAccountName: Server Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeBackupPrivilege
privilege: SeSystemtimePrivilege
privilege: SeRemoteShutdownPrivilege
privilege: SeRestorePrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Account Operators,CN=Builtin,${DOMAINDN}
objectClass: top
sAMAccountName: Account Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Pre-Windows 2000 Compatible Access,CN=Builtin,${DOMAINDN}
objectClass: top
sAMAccountName: Pre-Windows 2000 Compatible Access
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeRemoteInteractiveLogonRight
privilege: SeChangeNotifyPrivilege
+isCriticalSystemObject: TRUE
dn: CN=Incoming Forest Trust Builders,CN=Builtin,${DOMAINDN}
objectClass: top
replace: description
description: Default container for upgraded user accounts
-
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
replace: systemFlags
systemFlags: -1946157056
-
replace: isCriticalSystemObject
isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
subClassOf: top
governsID: 1.3.6.1.4.1.7165.4.2.2
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4-Local-Domain
adminDescription: Samba4-Local-Domain
systemMayContain: msDS-Behavior-Version
governsID: 1.3.6.1.4.1.7165.4.2.1
mayContain: msDS-ObjectReferenceBL
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4TopTop
adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
objectClassCategory: 3
subClassOf: top
governsID: 1.3.6.1.4.1.7165.4.2.3
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4TopExtra
adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
objectClassCategory: 2
#include "libcli/security/security.h"
#include "torture/torture.h"
#include "auth/auth_sam_reply.h"
+#include "param/param.h"
static bool torture_pac_self_check(struct torture_context *tctx)
{
{
struct frsapi_IsPathReplicated r;
struct GUID guid;
- uint32_t unknown1, unknown2, unknown3 = 0;
+ uint32_t replicated, primary, root;
ZERO_STRUCT(r);
r.in.path = path;
r.in.replica_set_type = type;
- r.out.unknown1 = &unknown1;
- r.out.unknown2 = &unknown2;
- r.out.unknown3 = &unknown3;
+ r.out.replicated = &replicated;
+ r.out.primary = &primary;
+ r.out.root = &root;
r.out.replica_set_guid = &guid;
torture_assert_ntstatus_ok(tctx,
ZERO_STRUCT(r);
- r.in.guid1 = NULL;
- r.in.guid2 = NULL;
- r.in.replica_set = talloc_asprintf(tctx, "%s",
- lp_realm(tctx->lp_ctx));
- r.in.partner_name = dcerpc_server_name(p);
+ r.in.replica_set_guid = NULL;
+ r.in.connection_guid = NULL;
+ r.in.replica_set_name = talloc_asprintf(tctx, "%s",
+ lp_realm(tctx->lp_ctx));
+ r.in.partner_dns_name = dcerpc_server_name(p);
torture_assert_ntstatus_ok(tctx,
dcerpc_frsapi_ForceReplication(p, tctx, &r),
NTSTATUS status;
uint16_t system_name = '\\';
- printf("\nTesting OpenPolicy\n");
+ torture_comment(tctx, "\nTesting OpenPolicy\n");
qos.len = 0;
qos.impersonation_level = 2;
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("OpenPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status));
return false;
}
struct lsa_OpenPolicy2 r;
NTSTATUS status;
- printf("\nTesting OpenPolicy2\n");
+ torture_comment(tctx, "\nTesting OpenPolicy2\n");
*handle = talloc(tctx, struct policy_handle);
if (!*handle) {
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
talloc_free(*handle);
*handle = NULL;
return true;
}
- printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
return false;
}
NTSTATUS status;
int i;
- printf("\nTesting LookupNames with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
for (i=0;i< tnames->count;i++) {
if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
- printf("LookupName of %s was unmapped\n",
+ torture_comment(tctx, "LookupName of %s was unmapped\n",
tnames->names[i].name.string);
} else if (i >=count) {
- printf("LookupName of %s failed to return a result\n",
+ torture_comment(tctx, "LookupName of %s failed to return a result\n",
tnames->names[i].name.string);
}
}
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
} else if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
}
for (i=0;i< tnames->count;i++) {
if (i < count && sids.sids[i].sid_type != tnames->names[i].sid_type) {
- printf("LookupName of %s got unexpected name type: %s\n",
+ torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n",
tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type));
} else if (i >=count) {
- printf("LookupName of %s failed to return a result\n",
+ torture_comment(tctx, "LookupName of %s failed to return a result\n",
tnames->names[i].name.string);
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
name[0].name.string = "NT AUTHORITY\\BOGUS";
name[1].name.string = NULL;
- printf("\nTesting LookupNames with bogus names\n");
+ torture_comment(tctx, "\nTesting LookupNames with bogus names\n");
sids.count = 0;
sids.sids = NULL;
status = dcerpc_lsa_LookupNames(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
struct lsa_TransNameArray tnames;
bool ret = true;
- printf("Testing LookupNames with well known names\n");
+ torture_comment(tctx, "Testing LookupNames with well known names\n");
tnames.names = &name;
tnames.count = 1;
NTSTATUS status;
int i;
- printf("\nTesting LookupNames2 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
status = dcerpc_lsa_LookupNames2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status));
return false;
}
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
NTSTATUS status;
int i;
- printf("\nTesting LookupNames3 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
status = dcerpc_lsa_LookupNames3(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames3 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status));
return false;
}
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
NTSTATUS status;
int i;
- printf("\nTesting LookupNames4 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
status = dcerpc_lsa_LookupNames4(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames4 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status));
return false;
}
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids\n");
+ torture_comment(tctx, "\nTesting LookupSids\n");
names.count = 0;
names.names = NULL;
status = dcerpc_lsa_LookupSids(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames(p, tctx, handle, &names)) {
return false;
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids2\n");
+ torture_comment(tctx, "\nTesting LookupSids2\n");
names.count = 0;
names.names = NULL;
status = dcerpc_lsa_LookupSids2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames2(p, tctx, handle, &names, false)) {
return false;
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids3\n");
+ torture_comment(tctx, "\nTesting LookupSids3\n");
names.count = 0;
names.names = NULL;
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("LookupSids3 failed - %s - not considered an error\n",
+ torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n",
nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames4(p, tctx, &names, false)) {
return false;
struct lsa_SidArray sids;
int i;
- printf("\nTesting LookupSids with lots of SIDs\n");
+ torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
sids.num_sids = 100;
status = dcerpc_lsa_LookupSids(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames(p, tctx, handle, &names)) {
return false;
names.count = 0;
names.names = NULL;
- printf("\nTesting LookupSids3\n");
+ torture_comment(tctx, "\nTesting LookupSids3\n");
r.in.sids = &sids;
r.in.names = &names;
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("LookupSids3 failed - %s\n",
+ torture_comment(tctx, "LookupSids3 failed - %s\n",
nt_errstr(status));
return false;
}
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
- printf("\nTesting %d async lookupsids request\n", num_async_requests);
+ torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
req = talloc_array(tctx, struct rpc_request *, num_async_requests);
status = dcerpc_lsa_LookupPrivValue(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_LookupPrivName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
return false;
}
struct lsa_PrivilegeSet privs;
bool ret = true;
- printf("\nTesting RemovePrivilegesFromAccount\n");
+ torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
r.in.handle = acct_handle;
r.in.remove_all = 0;
status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
return false;
}
/* Windows 2008 does not allow this to be removed */
return ret;
}
- printf("RemovePrivilegesFromAccount failed to remove %s - %s\n",
+ torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
name->string,
nt_errstr(status));
return false;
struct lsa_PrivilegeSet privs;
bool ret = true;
- printf("\nTesting AddPrivilegesToAccount\n");
+ torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
r.in.handle = acct_handle;
r.in.privs = &privs;
status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
return false;
}
struct lsa_PrivilegeSet *privs = NULL;
bool ret = true;
- printf("\nTesting EnumPrivsAccount\n");
+ torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
r.in.handle = acct_handle;
r.out.privs = &privs;
status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status));
return false;
}
uint32_t access_mask;
struct lsa_GetSystemAccessAccount r;
- printf("\nTesting GetSystemAccessAccount\n");
+ torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
r.in.handle = acct_handle;
r.out.access_mask = &access_mask;
status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status));
return false;
}
if (r.out.access_mask != NULL) {
- printf("Rights:");
+ torture_comment(tctx, "Rights:");
if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
- printf(" LSA_POLICY_MODE_NETWORK");
+ torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
- printf(" LSA_POLICY_MODE_BATCH");
+ torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
- printf(" LSA_POLICY_MODE_SERVICE");
+ torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
- printf(" LSA_POLICY_MODE_PROXY");
+ torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
- printf(" LSA_POLICY_MODE_DENY_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
- printf(" LSA_POLICY_MODE_DENY_NETWORK");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
- printf(" LSA_POLICY_MODE_DENY_BATCH");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
- printf(" LSA_POLICY_MODE_DENY_SERVICE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
- printf(" LSA_POLICY_MODE_ALL");
+ torture_comment(tctx, " LSA_POLICY_MODE_ALL");
if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
- printf(" LSA_POLICY_MODE_ALL_NT4");
- printf("\n");
+ torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
+ torture_comment(tctx, "\n");
}
return true;
NTSTATUS status;
struct lsa_Delete r;
- printf("\nTesting Delete\n");
+ torture_comment(tctx, "\nTesting Delete\n");
r.in.handle = handle;
status = dcerpc_lsa_Delete(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
- printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
return false;
}
NTSTATUS status;
struct lsa_DeleteObject r;
- printf("\nTesting DeleteObject\n");
+ torture_comment(tctx, "\nTesting DeleteObject\n");
r.in.handle = handle;
r.out.handle = handle;
status = dcerpc_lsa_DeleteObject(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("DeleteObject failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status));
return false;
}
newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
- printf("\nTesting CreateAccount\n");
+ torture_comment(tctx, "\nTesting CreateAccount\n");
r.in.handle = handle;
r.in.sid = newsid;
status = dcerpc_lsa_OpenAccount(p, tctx, &r_o);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
return false;
}
} else if (!NT_STATUS_IS_OK(status)) {
- printf("CreateAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status));
return false;
}
secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random());
for (i=0; i< 2; i++) {
- printf("\nTesting CreateSecret of %s\n", secname[i]);
+ torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
init_lsa_String(&r.in.name, secname[i]);
status = dcerpc_lsa_CreateSecret(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_CreateSecret(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
- printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
return false;
}
r2.in.name = r.in.name;
r2.out.sec_handle = &sec_handle2;
- printf("Testing OpenSecret\n");
+ torture_comment(tctx, "Testing OpenSecret\n");
status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
- printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
return false;
}
r3.in.new_val->length = enc_key.length;
r3.in.new_val->size = enc_key.length;
- printf("Testing SetSecret\n");
+ torture_comment(tctx, "Testing SetSecret\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r3);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
return false;
}
/* break the encrypted data */
enc_key.data[0]++;
- printf("Testing SetSecret with broken key\n");
+ torture_comment(tctx, "Testing SetSecret with broken key\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r3);
if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
- printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
ret = false;
}
bufp1.buf = NULL;
- printf("Testing QuerySecret\n");
+ torture_comment(tctx, "Testing QuerySecret\n");
status = dcerpc_lsa_QuerySecret(p, tctx, &r4);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
} else {
if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
- printf("No secret buffer returned\n");
+ torture_comment(tctx, "No secret buffer returned\n");
ret = false;
} else {
blob1.data = r4.out.new_val->buf->data;
&blob1, &session_key);
if (strcmp(secret1, secret2) != 0) {
- printf("Returned secret (r4) '%s' doesn't match '%s'\n",
+ torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
secret2, secret1);
ret = false;
}
msleep(200);
- printf("Testing SetSecret (existing value should move to old)\n");
+ torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r5);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_QuerySecret(p, tctx, &r6);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
secret4 = NULL;
} else {
if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
|| r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
- printf("Both secret buffers and both times not returned\n");
+ torture_comment(tctx, "Both secret buffers and both times not returned\n");
ret = false;
secret4 = NULL;
} else {
&blob1, &session_key);
if (strcmp(secret3, secret4) != 0) {
- printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
+ torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
ret = false;
}
&blob1, &session_key);
if (strcmp(secret1, secret2) != 0) {
- printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1);
+ torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
ret = false;
}
if (*r6.out.new_mtime == *r6.out.old_mtime) {
- printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
+ torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
i,
secname[i],
nt_time_string(tctx, *r6.out.old_mtime),
r7.in.old_val->size = enc_key.length;
r7.in.new_val = NULL;
- printf("Testing SetSecret of old Secret only\n");
+ torture_comment(tctx, "Testing SetSecret of old Secret only\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r7);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_QuerySecret(p, tctx, &r8);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
} else {
if (!r8.out.new_val || !r8.out.old_val) {
- printf("in/out pointers not returned, despite being set on in for QuerySecret\n");
+ torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
ret = false;
} else if (r8.out.new_val->buf != NULL) {
- printf("NEW secret buffer must not be returned after OLD set\n");
+ torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
ret = false;
} else if (r8.out.old_val->buf == NULL) {
- printf("OLD secret buffer was not returned after OLD set\n");
+ torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
ret = false;
} else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
- printf("Both times not returned after OLD set\n");
+ torture_comment(tctx, "Both times not returned after OLD set\n");
ret = false;
} else {
blob1.data = r8.out.old_val->buf->data;
&blob1, &session_key);
if (strcmp(secret5, secret6) != 0) {
- printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6);
+ torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
ret = false;
}
if (*r8.out.new_mtime != *r8.out.old_mtime) {
- printf("Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
+ torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
secname[i],
nt_time_string(tctx, *r8.out.old_mtime),
nt_time_string(tctx, *r8.out.new_mtime));
d_o.out.handle = &sec_handle2;
status = dcerpc_lsa_DeleteObject(p, tctx, &d_o);
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
- printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
ret = false;
} else {
- printf("Testing OpenSecret of just-deleted secret\n");
+ torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
- printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
ret = false;
}
}
struct lsa_EnumAccountRights r;
struct lsa_RightSet rights;
- printf("\nTesting EnumAccountRights\n");
+ torture_comment(tctx, "\nTesting EnumAccountRights\n");
r.in.handle = acct_handle;
r.in.sid = sid;
status = dcerpc_lsa_EnumAccountRights(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccountRights of %s failed - %s\n",
+ torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
dom_sid_string(tctx, sid), nt_errstr(status));
return false;
}
struct sec_desc_buf *sdbuf = NULL;
if (torture_setting_bool(tctx, "samba4", false)) {
- printf("\nskipping QuerySecurity test against Samba4\n");
+ torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
return true;
}
- printf("\nTesting QuerySecurity\n");
+ torture_comment(tctx, "\nTesting QuerySecurity\n");
r.in.handle = acct_handle;
- r.in.sec_info = 7;
+ r.in.sec_info = SECINFO_OWNER |
+ SECINFO_GROUP |
+ SECINFO_DACL;
r.out.sdbuf = &sdbuf;
status = dcerpc_lsa_QuerySecurity(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecurity failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status));
return false;
}
struct lsa_OpenAccount r;
struct policy_handle acct_handle;
- printf("\nTesting OpenAccount\n");
+ torture_comment(tctx, "\nTesting OpenAccount\n");
r.in.handle = handle;
r.in.sid = sid;
status = dcerpc_lsa_OpenAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
return false;
}
int i;
bool ret = true;
- printf("\nTesting EnumAccounts\n");
+ torture_comment(tctx, "\nTesting EnumAccounts\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
break;
}
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccounts failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
return false;
}
* be on schannel, or we would not be able to do the
* rest */
- printf("Testing all accounts\n");
+ torture_comment(tctx, "Testing all accounts\n");
for (i=0;i<sids1.num_sids;i++) {
ret &= test_OpenAccount(p, tctx, handle, sids1.sids[i].sid);
ret &= test_EnumAccountRights(p, tctx, handle, sids1.sids[i].sid);
}
- printf("\n");
+ torture_comment(tctx, "\n");
}
if (sids1.num_sids < 3) {
return ret;
}
- printf("Trying EnumAccounts partial listing (asking for 1 at 2)\n");
+ torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
resume_handle = 2;
r.in.num_entries = 1;
r.out.sids = &sids2;
status = dcerpc_lsa_EnumAccounts(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccounts failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
return false;
}
if (sids2.num_sids != 1) {
- printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
+ torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
return false;
}
uint16_t returned_language_id = 0;
struct lsa_StringLarge *disp_name = NULL;
- printf("\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
+ torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
r.in.handle = handle;
r.in.name = priv_name;
status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status));
return false;
}
- printf("%s -> \"%s\" (language 0x%x/0x%x)\n",
+ torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
priv_name->string, disp_name->string,
r.in.language_id, *r.out.returned_language_id);
ZERO_STRUCT(sids);
- printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
+ torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
r.in.handle = handle;
r.in.name = priv_name;
}
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
return false;
}
int i;
bool ret = true;
- printf("\nTesting EnumPrivs\n");
+ torture_comment(tctx, "\nTesting EnumPrivs\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
resume_handle = 0;
status = dcerpc_lsa_EnumPrivs(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumPrivs failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status));
return false;
}
struct lsa_String string;
struct lsa_ForestTrustInformation info, *info_ptr;
- printf("\nTesting lsaRQueryForestTrustInformation\n");
+ torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
if (torture_setting_bool(tctx, "samba4", false)) {
- printf("skipping QueryForestTrustInformation against Samba4\n");
+ torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
return true;
}
status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
+ torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
ret = false;
}
int i,j;
bool ret = true;
- printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
+ torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
for (i=0; i< domains->count; i++) {
struct lsa_OpenTrustedDomain trust;
struct lsa_OpenTrustedDomainByName trust_by_name;
status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status));
return false;
}
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfo level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
- printf("Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_Close(p, tctx, &c);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfoBySid level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
return false;
}
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfo level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_Close(p, tctx, &c);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
return false;
}
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfoByName level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
struct lsa_DomainListEx domains_ex;
bool ret = true;
- printf("\nTesting EnumTrustDom\n");
+ torture_comment(tctx, "\nTesting EnumTrustDom\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
if (NT_STATUS_IS_OK(enum_status)) {
if (domains.count == 0) {
- printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
} else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
- printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains.count == 0) {
return true;
}
- printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
return false;
} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
/* Windows 2003 gets this off by one on the first run */
if (r.out.domains->count < 3 || r.out.domains->count > 4) {
- printf("EnumTrustDom didn't fill the buffer we "
+ torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
"asked it to (got %d, expected %d / %d == %d entries)\n",
r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
ret = false;
}
} else if (!NT_STATUS_IS_OK(enum_status)) {
- printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains.count == 0) {
- printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
- printf("\nTesting EnumTrustedDomainsEx\n");
+ torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
r_ex.in.handle = handle;
r_ex.in.resume_handle = &resume_handle;
enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex);
if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
- printf("EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains_ex.count == 0) {
return true;
}
- printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+ torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
return false;
} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
/* Windows 2003 gets this off by one on the first run */
if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
- printf("EnumTrustDom didn't fill the buffer we "
+ torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
"asked it to (got %d, expected %d / %d == %d entries)\n",
r_ex.out.domains->count,
r_ex.in.max_size,
r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
}
} else if (!NT_STATUS_IS_OK(enum_status)) {
- printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains_ex.count == 0) {
- printf("EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
union lsa_TrustedDomainInfo *info = NULL;
int i;
- printf("\nTesting CreateTrustedDomain for 12 domains\n");
+ torture_comment(tctx, "\nTesting CreateTrustedDomain for 12 domains\n");
if (!test_EnumTrustDom(p, tctx, handle)) {
ret = false;
status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status));
ret = false;
} else {
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
- printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = false;
} else if (!q.out.info) {
ret = false;
} else {
if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
- printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
info->info_ex.netbios_name.string, trustinfo.name.string);
ret = false;
}
if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
ret = false;
}
if (info->info_ex.trust_attributes != 0) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
trust_name, info->info_ex.trust_attributes, 0);
ret = false;
}
if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
ret = false;
}
enum ndr_err_code ndr_err;
int i;
- printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n");
+ torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for 12 domains\n");
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
- printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
return false;
}
ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct,
(ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- printf("ndr_push_struct_blob of trustDomainPasswords structure failed");
+ torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed");
ret = false;
}
status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
ret = false;
} else {
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
- printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = false;
} else if (!q.out.info) {
- printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
ret = false;
} else {
if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
- printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
ret = false;
}
if (info->info_ex.trust_type != trustinfo.trust_type) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
trust_name, info->info_ex.trust_type, trustinfo.trust_type);
ret = false;
}
if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
ret = false;
}
if (info->info_ex.trust_direction != trustinfo.trust_direction) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
ret = false;
}
/* now that we have some domains to look over, we can test the enum calls */
if (!test_EnumTrustDom(p, tctx, handle)) {
- printf("test_EnumTrustDom failed\n");
+ torture_comment(tctx, "test_EnumTrustDom failed\n");
ret = false;
}
for (i=0; i<12; i++) {
if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) {
- printf("test_DeleteTrustedDomainBySid failed\n");
+ torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
ret = false;
}
}
int i;
bool ret = true;
- printf("\nTesting QueryDomainInformationPolicy\n");
+ torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
for (i=2;i<4;i++) {
r.in.handle = handle;
r.in.level = i;
r.out.info = &info;
- printf("\nTrying QueryDomainInformationPolicy level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r);
if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
continue;
} else if (!NT_STATUS_IS_OK(status)) {
- printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
ret = false;
continue;
}
bool ret = true;
if (version2)
- printf("\nTesting QueryInfoPolicy2\n");
+ torture_comment(tctx, "\nTesting QueryInfoPolicy2\n");
else
- printf("\nTesting QueryInfoPolicy\n");
+ torture_comment(tctx, "\nTesting QueryInfoPolicy\n");
for (i=1;i<=14;i++) {
r.in.handle = handle;
r.out.info = &info;
if (version2)
- printf("\nTrying QueryInfoPolicy2 level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryInfoPolicy2 level %d\n", i);
else
- printf("\nTrying QueryInfoPolicy level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryInfoPolicy level %d\n", i);
if (version2)
/* We can perform the cast, because both types are
case LSA_POLICY_INFO_AUDIT_FULL_SET:
case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
- printf("Server should have failed level %u: %s\n", i, nt_errstr(status));
+ torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status));
ret = false;
}
break;
case LSA_POLICY_INFO_PD:
if (!NT_STATUS_IS_OK(status)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
break;
/* Other levels not implemented yet */
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
} else if (!NT_STATUS_IS_OK(status)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
break;
struct lsa_String *authority_name_p = NULL;
struct lsa_String *account_name_p = NULL;
- printf("\nTesting GetUserName\n");
+ torture_comment(tctx, "\nTesting GetUserName\n");
r.in.system_name = "\\";
r.in.account_name = &account_name_p;
status = dcerpc_lsa_GetUserName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetUserName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
ret = false;
}
status = dcerpc_lsa_GetUserName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetUserName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
ret = false;
}
struct lsa_Close r;
struct policy_handle handle2;
- printf("\nTesting Close\n");
+ torture_comment(tctx, "\nTesting Close\n");
r.in.handle = handle;
r.out.handle = &handle2;
status = dcerpc_lsa_Close(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_Close(p, tctx, &r);
/* its really a fault - we need a status code for rpc fault */
if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- printf("Close failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
ret = false;
}
- if (!test_CreateAccount(p, tctx, handle)) {
- ret = false;
- }
-
if (!test_CreateSecret(p, tctx, handle)) {
ret = false;
}
- if (!test_CreateTrustedDomain(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_EnumAccounts(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_EnumPrivs(p, tctx, handle)) {
- ret = false;
- }
if (!test_QueryInfoPolicy(p, tctx, handle)) {
ret = false;
return suite;
}
+
+static bool testcase_TrustedDomains(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle *handle;
+
+ if (!test_OpenPolicy(p, tctx)) {
+ ret = false;
+ }
+
+ if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+ ret = false;
+ }
+
+ if (!handle) {
+ ret = false;
+ }
+
+ if (!test_CreateTrustedDomain(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_lsa_Close(p, tctx, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite;
+ struct torture_rpc_tcase *tcase;
+
+ suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS");
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+ &ndr_table_lsarpc);
+ torture_rpc_tcase_add_test(tcase, "TrustedDomains",
+ testcase_TrustedDomains);
+
+ return suite;
+}
+
+static bool testcase_Privileges(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle *handle;
+
+ if (!test_OpenPolicy(p, tctx)) {
+ ret = false;
+ }
+
+ if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+ ret = false;
+ }
+
+ if (!handle) {
+ ret = false;
+ }
+
+ if (!test_CreateAccount(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_EnumAccounts(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_EnumPrivs(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_lsa_Close(p, tctx, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+
+struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite;
+ struct torture_rpc_tcase *tcase;
+
+ suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES");
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+ &ndr_table_lsarpc);
+ torture_rpc_tcase_add_test(tcase, "Privileges",
+ testcase_Privileges);
+
+ return suite;
+}
{
NTSTATUS status;
struct dcerpc_pipe *p1, *p2;
- struct rpc_request *req;
struct GUID uuid;
struct dssetup_DsRoleGetPrimaryDomainInformation r1;
struct lsa_GetUserName r2;
torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite));
torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite));
torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite));
+ torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite));
+ torture_suite_add_suite(suite, torture_rpc_lsa_privileges(suite));
torture_suite_add_suite(suite, torture_rpc_echo(suite));
torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs);
torture_suite_add_suite(suite, torture_rpc_frsapi(suite));
torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss);
torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
+ torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users);
torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords);
#include "torture/rpc/rpc.h"
#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
+#define TORTURE_PRINTER "torture_printer"
+#define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex"
+#define TORTURE_PRINTER_EX "torture_printer_ex"
+
struct test_spoolss_context {
/* print server handle */
struct policy_handle server_handle;
#define COMPARE_STRING_ARRAY(tctx, c,r,e)
-static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx)
+static bool test_OpenPrinter_server(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *server_handle)
{
NTSTATUS status;
struct spoolss_OpenPrinter op;
- op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
+ op.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
op.in.datatype = NULL;
op.in.devmode_ctr.devmode= NULL;
op.in.access_mask = 0;
- op.out.handle = &ctx->server_handle;
+ op.out.handle = server_handle;
torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
- status = dcerpc_spoolss_OpenPrinter(p, ctx, &op);
+ status = dcerpc_spoolss_OpenPrinter(p, tctx, &op);
torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
return true;
}
+static bool test_SetPrinter_errors(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct spoolss_SetPrinter r;
+ uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int i;
+
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+
+ info_ctr.level = 0;
+ info_ctr.info.info0 = NULL;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ r.in.handle = handle;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.in.command = 0;
+
+ torture_comment(tctx, "Testing SetPrinter all zero\n");
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+ "failed to call SetPrinter");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+ "failed to call SetPrinter");
+
+ again:
+ for (i=0; i < ARRAY_SIZE(levels); i++) {
+
+ struct spoolss_SetPrinterInfo0 info0;
+ struct spoolss_SetPrinterInfo1 info1;
+ struct spoolss_SetPrinterInfo2 info2;
+ struct spoolss_SetPrinterInfo3 info3;
+ struct spoolss_SetPrinterInfo4 info4;
+ struct spoolss_SetPrinterInfo5 info5;
+ struct spoolss_SetPrinterInfo6 info6;
+ struct spoolss_SetPrinterInfo7 info7;
+ struct spoolss_DeviceModeInfo info8;
+ struct spoolss_DeviceModeInfo info9;
+
+
+ info_ctr.level = levels[i];
+ switch (levels[i]) {
+ case 0:
+ ZERO_STRUCT(info0);
+ info_ctr.info.info0 = &info0;
+ break;
+ case 1:
+ ZERO_STRUCT(info1);
+ info_ctr.info.info1 = &info1;
+ break;
+ case 2:
+ ZERO_STRUCT(info2);
+ info_ctr.info.info2 = &info2;
+ break;
+ case 3:
+ ZERO_STRUCT(info3);
+ info_ctr.info.info3 = &info3;
+ break;
+ case 4:
+ ZERO_STRUCT(info4);
+ info_ctr.info.info4 = &info4;
+ break;
+ case 5:
+ ZERO_STRUCT(info5);
+ info_ctr.info.info5 = &info5;
+ break;
+ case 6:
+ ZERO_STRUCT(info6);
+ info_ctr.info.info6 = &info6;
+ break;
+ case 7:
+ ZERO_STRUCT(info7);
+ info_ctr.info.info7 = &info7;
+ break;
+ case 8:
+ ZERO_STRUCT(info8);
+ info_ctr.info.info8 = &info8;
+ break;
+ case 9:
+ ZERO_STRUCT(info9);
+ info_ctr.info.info9 = &info9;
+ break;
+ }
+
+ torture_comment(tctx, "Testing SetPrinter level %d, command %d\n",
+ info_ctr.level, r.in.command);
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+ "failed to call SetPrinter");
+
+ switch (r.in.command) {
+ case SPOOLSS_PRINTER_CONTROL_UNPAUSE: /* 0 */
+ /* is ignored for all levels other then 0 */
+ if (info_ctr.level > 0) {
+ /* ignored then */
+ break;
+ }
+ case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */
+ case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */
+ case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */
+ if (info_ctr.level > 0) {
+ /* is invalid for all levels other then 0 */
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+ "unexpected error code returned");
+ continue;
+ } else {
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call SetPrinter with non 0 command");
+ continue;
+ }
+ break;
+
+ case SPOOLSS_PRINTER_CONTROL_SET_STATUS: /* 4 */
+ /* FIXME: gd needs further investigation */
+ default:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+ "unexpected error code returned");
+ continue;
+ }
+
+ switch (info_ctr.level) {
+ case 1:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
+ "unexpected error code returned");
+ break;
+ case 2:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_PRINTER_DRIVER,
+ "unexpected error code returned");
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+ "unexpected error code returned");
+ break;
+ case 9:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
+ "unexpected error code returned");
+ break;
+ default:
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call SetPrinter");
+ break;
+ }
+ }
+
+ if (r.in.command < 5) {
+ r.in.command++;
+ goto again;
+ }
+
+ return true;
+}
+
+static void clear_info2(struct spoolss_SetPrinterInfoCtr *r)
+{
+ if ((r->level == 2) && (r->info.info2)) {
+ r->info.info2->secdesc = NULL;
+ r->info.info2->devmode = NULL;
+ }
+}
+
+static bool test_PrinterInfo(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct spoolss_SetPrinter s;
+ struct spoolss_GetPrinter q;
+ struct spoolss_GetPrinter q0;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ union spoolss_PrinterInfo info;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ uint32_t needed;
+ bool ret = true;
+ int i;
+
+ uint32_t status_list[] = {
+ /* these do not stick
+ PRINTER_STATUS_PAUSED,
+ PRINTER_STATUS_ERROR,
+ PRINTER_STATUS_PENDING_DELETION, */
+ PRINTER_STATUS_PAPER_JAM,
+ PRINTER_STATUS_PAPER_OUT,
+ PRINTER_STATUS_MANUAL_FEED,
+ PRINTER_STATUS_PAPER_PROBLEM,
+ PRINTER_STATUS_OFFLINE,
+ PRINTER_STATUS_IO_ACTIVE,
+ PRINTER_STATUS_BUSY,
+ PRINTER_STATUS_PRINTING,
+ PRINTER_STATUS_OUTPUT_BIN_FULL,
+ PRINTER_STATUS_NOT_AVAILABLE,
+ PRINTER_STATUS_WAITING,
+ PRINTER_STATUS_PROCESSING,
+ PRINTER_STATUS_INITIALIZING,
+ PRINTER_STATUS_WARMING_UP,
+ PRINTER_STATUS_TONER_LOW,
+ PRINTER_STATUS_NO_TONER,
+ PRINTER_STATUS_PAGE_PUNT,
+ PRINTER_STATUS_USER_INTERVENTION,
+ PRINTER_STATUS_OUT_OF_MEMORY,
+ PRINTER_STATUS_DOOR_OPEN,
+ PRINTER_STATUS_SERVER_UNKNOWN,
+ PRINTER_STATUS_POWER_SAVE,
+ /* these do not stick
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000 */
+ };
+ uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL;
+ uint32_t attribute_list[] = {
+ PRINTER_ATTRIBUTE_QUEUED,
+ /* fails with WERR_INVALID_DATATYPE:
+ PRINTER_ATTRIBUTE_DIRECT, */
+ /* does not stick
+ PRINTER_ATTRIBUTE_DEFAULT, */
+ PRINTER_ATTRIBUTE_SHARED,
+ /* does not stick
+ PRINTER_ATTRIBUTE_NETWORK, */
+ PRINTER_ATTRIBUTE_HIDDEN,
+ PRINTER_ATTRIBUTE_LOCAL,
+ PRINTER_ATTRIBUTE_ENABLE_DEVQ,
+ PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS,
+ PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST,
+ PRINTER_ATTRIBUTE_WORK_OFFLINE,
+ /* does not stick
+ PRINTER_ATTRIBUTE_ENABLE_BIDI, */
+ /* fails with WERR_INVALID_DATATYPE:
+ PRINTER_ATTRIBUTE_RAW_ONLY, */
+ /* these do not stick
+ PRINTER_ATTRIBUTE_PUBLISHED,
+ PRINTER_ATTRIBUTE_FAX,
+ PRINTER_ATTRIBUTE_TS,
+ 0x00010000,
+ 0x00020000,
+ 0x00040000,
+ 0x00080000,
+ 0x00100000,
+ 0x00200000,
+ 0x00400000,
+ 0x00800000,
+ 0x01000000,
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000 */
+ };
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ s.in.handle = handle;
+ s.in.command = 0;
+ s.in.info_ctr = &info_ctr;
+ s.in.devmode_ctr = &devmode_ctr;
+ s.in.secdesc_ctr = &secdesc_ctr;
+
+ q.in.handle = handle;
+ q.out.info = &info;
+ q0 = q;
+
+#define TESTGETCALL(call, r) \
+ r.in.buffer = NULL; \
+ r.in.offered = 0;\
+ r.out.needed = &needed; \
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ }\
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); \
+ data_blob_clear(&blob); \
+ r.in.buffer = &blob; \
+ r.in.offered = needed; \
+ }\
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, win_errstr(r.out.result), __location__); \
+ ret = false; \
+ break; \
+ }
+
+
+#define TESTSETCALL_EXP(call, r, err) \
+ clear_info2(&info_ctr);\
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.info_ctr->level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(err)) { \
+ if (!W_ERROR_EQUAL(err, r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
+ r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
+ ret = false; \
+ } \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define TESTSETCALL(call, r) \
+ TESTSETCALL_EXP(call, r, WERR_OK)
+
+#define STRING_EQUAL(s1, s2, field) \
+ if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define MEM_EQUAL(s1, s2, length, field) \
+ if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, (const char *)s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define INT_EQUAL(i1, i2, field) \
+ if (i1 != i2) { \
+ torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
+ #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.level = lvl1; \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ info_ctr.info.info ## lvl1->field1 = value;\
+ TESTSETCALL_EXP(SetPrinter, s, err) \
+ info_ctr.info.info ## lvl1->field1 = ""; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl1->field1 = value; \
+ STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
+ q.in.level = lvl2; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+ STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
+ } while (0)
+
+#define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
+ TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
+ } while (0);
+
+#define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.level = lvl1; \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ info_ctr.info.info ## lvl1->field1 = value; \
+ TESTSETCALL(SetPrinter, s) \
+ info_ctr.info.info ## lvl1->field1 = 0; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
+ q.in.level = lvl2; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+ INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
+ } while (0)
+
+#define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
+ TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
+ } while (0)
+
+ q0.in.level = 0;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ TEST_PRINTERINFO_STRING(2, comment, 1, comment, "xx2-1 comment");
+ TEST_PRINTERINFO_STRING(2, comment, 2, comment, "xx2-2 comment");
+
+ /* level 0 printername does not stick */
+/* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
+ TEST_PRINTERINFO_STRING(2, printername, 1, name, "xx2-1 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 2, printername, "xx2-2 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 4, printername, "xx2-4 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 5, printername, "xx2-5 printer");
+/* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
+ TEST_PRINTERINFO_STRING(4, printername, 1, name, "xx4-1 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 2, printername, "xx4-2 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 4, printername, "xx4-4 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 5, printername, "xx4-5 printer");
+/* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
+ TEST_PRINTERINFO_STRING(5, printername, 1, name, "xx5-1 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 2, printername, "xx5-2 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 4, printername, "xx5-4 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 5, printername, "xx5-5 printer");
+
+ /* servername can be set but does not stick
+ TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername");
+ TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername");
+ TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername");
+ */
+
+ /* passing an invalid port will result in WERR_UNKNOWN_PORT */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT);
+
+ TEST_PRINTERINFO_STRING(2, sharename, 2, sharename, "xx2-2 sharename");
+ /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername, 2, drivername, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER);
+ TEST_PRINTERINFO_STRING(2, location, 2, location, "xx2-2 location");
+ /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile, 2, sepfile, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE);
+ /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR);
+ TEST_PRINTERINFO_STRING(2, datatype, 2, datatype, "xx2-2 datatype");
+ TEST_PRINTERINFO_STRING(2, parameters, 2, parameters, "xx2-2 parameters");
+
+ for (i=0; i < ARRAY_SIZE(attribute_list); i++) {
+/* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+/* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+/* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ }
+
+ for (i=0; i < ARRAY_SIZE(status_list); i++) {
+ /* level 2 sets do not stick
+ TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
+ TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
+ TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
+ TEST_PRINTERINFO_INT(6, status, 0, status, status_list[i]);
+ TEST_PRINTERINFO_INT(6, status, 2, status, status_list[i]);
+ TEST_PRINTERINFO_INT(6, status, 6, status, status_list[i]);
+ }
+
+ /* priorities need to be between 0 and 99
+ passing an invalid priority will result in WERR_INVALID_PRIORITY */
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 0);
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 1);
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 99);
+ /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 0);
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 1);
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 99);
+ /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
+
+ TEST_PRINTERINFO_INT(2, starttime, 2, starttime, __LINE__);
+ TEST_PRINTERINFO_INT(2, untiltime, 2, untiltime, __LINE__);
+
+ /* does not stick
+ TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__);
+ TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */
+
+ /* does not stick
+ TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
+ TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
+
+ /* FIXME: gd also test devmode and secdesc behavior */
+
+ {
+ /* verify composition of level 1 description field */
+ const char *description;
+ const char *tmp;
+
+ q0.in.level = 1;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ description = talloc_strdup(tctx, q0.out.info->info1.description);
+
+ q0.in.level = 2;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ tmp = talloc_asprintf(tctx, "%s,%s,%s",
+ q0.out.info->info2.printername,
+ q0.out.info->info2.drivername,
+ q0.out.info->info2.location);
+
+ do { STRING_EQUAL(description, tmp, "description")} while (0);
+ }
+
+ return ret;
+}
+
static bool test_ClosePrinter(struct torture_context *tctx,
struct dcerpc_pipe *p,
return ret;
}
-#if 0
-static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
+static bool test_GetPrinterDriver(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle,
+ const char *driver_name)
+{
+ struct spoolss_GetPrinterDriver r;
+ uint32_t needed;
+
+ r.in.handle = handle;
+ r.in.architecture = "W32X86";
+ r.in.level = 1;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+ r.out.needed = &needed;
+
+ torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+ "failed to call GetPrinterDriver");
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+ r.in.offered = needed;
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+ "failed to call GetPrinterDriver");
+ }
+
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call GetPrinterDriver");
+
+ return true;
+}
+
+static bool test_GetPrinterDriver2(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
struct policy_handle *handle,
const char *driver_name)
{
- NTSTATUS status;
struct spoolss_GetPrinterDriver2 r;
uint32_t needed;
uint32_t server_major_version;
r.out.server_major_version = &server_major_version;
r.out.server_minor_version = &server_minor_version;
- printf("Testing GetPrinterDriver2\n");
-
- status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
- return false;
- }
+ torture_comment(tctx, "Testing GetPrinterDriver2 level %d\n", r.in.level);
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+ "failed to call GetPrinterDriver2");
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
r.in.offered = needed;
- status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- printf("GetPrinterDriver2 failed - %s\n",
- nt_errstr(status));
- return false;
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+ "failed to call GetPrinterDriver2");
}
- if (!W_ERROR_IS_OK(r.out.result)) {
- printf("GetPrinterDriver2 failed - %s\n",
- win_errstr(r.out.result));
- return false;
- }
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call GetPrinterDriver2");
return true;
}
-#endif
static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
struct dcerpc_pipe *p)
return true;
}
+static bool test_DeletePrinter(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct spoolss_DeletePrinter r;
+
+ torture_comment(tctx, "Testing DeletePrinter\n");
+
+ r.in.handle = handle;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter(p, tctx, &r),
+ "failed to delete printer");
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to delete printer");
+
+ return true;
+}
+
+static bool test_EnumPrinters_findname(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ uint32_t flags,
+ uint32_t level,
+ const char *name,
+ bool *found)
+{
+ struct spoolss_EnumPrinters e;
+ uint32_t count;
+ union spoolss_PrinterInfo *info;
+ uint32_t needed;
+ int i;
+
+ *found = false;
+
+ e.in.flags = flags;
+ e.in.server = NULL;
+ e.in.level = level;
+ e.in.buffer = NULL;
+ e.in.offered = 0;
+ e.out.count = &count;
+ e.out.info = &info;
+ e.out.needed = &needed;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+ "failed to enum printers");
+
+ if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ e.in.buffer = &blob;
+ e.in.offered = needed;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+ "failed to enum printers");
+ }
+
+ torture_assert_werr_ok(tctx, e.out.result,
+ "failed to enum printers");
+
+ for (i=0; i < count; i++) {
+
+ const char *current = NULL;
+
+ switch (level) {
+ case 1:
+ current = info[i].info1.name;
+ break;
+ }
+
+ if (strequal(current, name)) {
+ *found = true;
+ break;
+ }
+ }
+
+ return true;
+}
+
+static bool test_AddPrinter_wellknown(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ const char *printername,
+ bool ex)
+{
+ WERROR result;
+ struct spoolss_AddPrinter r;
+ struct spoolss_AddPrinterEx rex;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_SetPrinterInfo1 info1;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ struct spoolss_UserLevelCtr userlevel_ctr;
+ struct policy_handle handle;
+ bool found = false;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+ ZERO_STRUCT(userlevel_ctr);
+ ZERO_STRUCT(info1);
+
+ torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":"");
+
+ /* try to add printer to wellknown printer list (level 1) */
+
+ userlevel_ctr.level = 1;
+
+ info_ctr.info.info1 = &info1;
+ info_ctr.level = 1;
+
+ rex.in.server = NULL;
+ rex.in.info_ctr = &info_ctr;
+ rex.in.devmode_ctr = &devmode_ctr;
+ rex.in.secdesc_ctr = &secdesc_ctr;
+ rex.in.userlevel_ctr = &userlevel_ctr;
+ rex.out.handle = &handle;
+
+ r.in.server = NULL;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.out.handle = &handle;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+ "unexpected result code");
+
+ info1.name = printername;
+ info1.flags = PRINTER_ATTRIBUTE_SHARED;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+ better do a real check to see the printer is really there */
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_NETWORK, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+
+ torture_assert(tctx, found, "failed to find newly added printer");
+
+ info1.flags = 0;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+ better do a real check to see the printer has really been removed
+ from the well known printer list */
+
+ found = false;
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_NETWORK, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+#if 0
+ torture_assert(tctx, !found, "printer still in well known printer list");
+#endif
+ return true;
+}
+
+static bool test_AddPrinter_normal(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname,
+ bool ex)
+{
+ WERROR result;
+ struct spoolss_AddPrinter r;
+ struct spoolss_AddPrinterEx rex;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_SetPrinterInfo2 info2;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ struct spoolss_UserLevelCtr userlevel_ctr;
+ struct policy_handle handle;
+ bool found = false;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+ ZERO_STRUCT(userlevel_ctr);
+
+ torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":"");
+
+ userlevel_ctr.level = 1;
+
+ rex.in.server = NULL;
+ rex.in.info_ctr = &info_ctr;
+ rex.in.devmode_ctr = &devmode_ctr;
+ rex.in.secdesc_ctr = &secdesc_ctr;
+ rex.in.userlevel_ctr = &userlevel_ctr;
+ rex.out.handle = &handle;
+
+ r.in.server = NULL;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.out.handle = &handle;
+
+ again:
+
+ /* try to add printer to printer list (level 2) */
+
+ ZERO_STRUCT(info2);
+
+ info_ctr.info.info2 = &info2;
+ info_ctr.level = 2;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+ "unexpected result code");
+
+ info2.printername = printername;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+
+ if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
+ struct policy_handle printer_handle;
+
+ torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, &printer_handle),
+ "failed to open printer handle");
+
+ torture_assert(tctx, test_DeletePrinter(tctx, p, &printer_handle),
+ "failed to delete printer");
+
+ torture_assert(tctx, test_ClosePrinter(tctx, p, &printer_handle),
+ "failed to close server handle");
+
+ goto again;
+ }
+
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
+ "unexpected result code");
+
+ info2.portname = portname;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
+ "unexpected result code");
+
+ info2.drivername = drivername;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
+ "unexpected result code");
+
+ info2.printprocessor = "winprint";
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_ok(tctx, result,
+ "failed to add printer");
+
+ *handle_p = handle;
+
+ /* we are paranoid, really check if the printer is there now */
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_LOCAL, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+ torture_assert(tctx, found, "failed to find newly added printer");
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ return true;
+}
+
+static bool test_AddPrinterEx(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname)
+{
+ bool ret = true;
+
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER_EX, true)) {
+ torture_comment(tctx, "failed to add printer to well known list\n");
+ ret = false;
+ }
+ }
+
+ if (!test_AddPrinter_normal(tctx, p, handle_p,
+ printername, drivername, portname,
+ true)) {
+ torture_comment(tctx, "failed to add printer to printer list\n");
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_AddPrinter(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname)
+{
+ bool ret = true;
+
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER, false)) {
+ torture_comment(tctx, "failed to add printer to well known list\n");
+ ret = false;
+ }
+ }
+
+ if (!test_AddPrinter_normal(tctx, p, handle_p,
+ printername, drivername, portname,
+ false)) {
+ torture_comment(tctx, "failed to add printer to printer list\n");
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_printer_info(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ bool ret = true;
+
+ if (!test_PrinterInfo(tctx, p, handle)) {
+ ret = false;
+ }
+
+ if (!test_SetPrinter_errors(tctx, p, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_printer(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle handle[2];
+ bool found = false;
+ const char *drivername = "Microsoft XPS Document Writer";
+ const char *portname = "LPT1:";
+
+ /* test printer created via AddPrinter */
+
+ if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, portname)) {
+ return false;
+ }
+
+ if (!test_printer_info(tctx, p, &handle[0])) {
+ ret = false;
+ }
+
+ if (!test_DeletePrinter(tctx, p, &handle[0])) {
+ ret = false;
+ }
+
+ if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+ TORTURE_PRINTER, &found)) {
+ ret = false;
+ }
+
+ torture_assert(tctx, !found, "deleted printer still there");
+
+ /* test printer created via AddPrinterEx */
+
+ if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, portname)) {
+ return false;
+ }
+
+ if (!test_printer_info(tctx, p, &handle[1])) {
+ ret = false;
+ }
+
+ if (!test_DeletePrinter(tctx, p, &handle[1])) {
+ ret = false;
+ }
+
+ if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+ TORTURE_PRINTER_EX, &found)) {
+ ret = false;
+ }
+
+ torture_assert(tctx, !found, "deleted printer still there");
+
+ return ret;
+}
+
bool torture_rpc_spoolss(struct torture_context *torture)
{
NTSTATUS status;
ctx = talloc_zero(torture, struct test_spoolss_context);
- ret &= test_OpenPrinter_server(torture, p, ctx);
+ ret &= test_OpenPrinter_server(torture, p, &ctx->server_handle);
ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled");
ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled");
return ret;
}
+
+struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-PRINTER");
+
+ struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
+ "printer", &ndr_table_spoolss);
+
+ torture_rpc_tcase_add_test(tcase, "printer", test_printer);
+
+ return suite;
+}
smb2.o \
durable_open.o \
oplocks.o \
+ dir.o \
lease.o \
create.o \
read.o \
return false;
}
+ smb2_util_unlink(tree, "test9.dat");
+
h1 = torture_smb2_createfile(tree, "test9.dat");
h2 = torture_smb2_createfile(tree, "test9.dat");
status = torture_smb2_write(torture, tree, h1);
-/*
+/*
Unix SMB/CIFS implementation.
SMB2 dir list test suite
Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Zachary Loafman 2009
+ Copyright (C) Aravind Srinivasan 2009
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/libcli.h"
#include "torture/torture.h"
#include "torture/smb2/proto.h"
+#include "torture/util.h"
+
+#include "system/filesys.h"
+
+#define CHECK_STATUS(status, correct) do { \
+ if (!NT_STATUS_EQUAL(status, correct)) { \
+ torture_result(tctx, TORTURE_FAIL, __location__": \
+ Incorrect status %s - should be %s", \
+ nt_errstr(status), nt_errstr(correct)); \
+ ret = false; \
+ goto done; \
+ }} while (0)
+
+#define CHECK_VALUE(v, correct) torture_assert_int_equal(tctx, (v), \
+ (correct), "incorrect value");
+
+#define DNAME "smb2_dir"
+#define NFILES 100
+
+struct file_elem {
+ char *name;
+ bool found;
+};
+
+static NTSTATUS populate_tree(struct torture_context *tctx,
+ TALLOC_CTX *mem_ctx,
+ struct smb2_tree *tree,
+ struct file_elem *files,
+ int nfiles,
+ struct smb2_handle *h_out)
+{
+ struct smb2_create create;
+ NTSTATUS status;
+ bool ret;
+ int i;
+
+ smb2_deltree(tree, DNAME);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ *h_out = create.out.file.handle;
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = 0; i < nfiles; i++) {
+ files[i].name = generate_random_str(tctx, 8);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+ done:
+ return status;
+}
/*
test find continue
*/
-static bool torture_smb2_find_dir(struct smb2_tree *tree)
+
+static bool test_find(struct torture_context *tctx,
+ struct smb2_tree *tree)
{
- struct smb2_handle handle;
- NTSTATUS status;
- int i;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_handle h;
struct smb2_find f;
- bool ret = true;
union smb_search_data *d;
+ struct file_elem files[NFILES] = {};
+ NTSTATUS status;
+ bool ret = true;
uint_t count;
+ int i, j, file_count = 0;
- status = smb2_util_roothandle(tree, &handle);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
+ status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ bool expected;
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ expected = false;
+ for (j = 0; j < NFILES; j++) {
+ if (!strcmp(files[j].name, found)) {
+ files[j].found = true;
+ expected = true;
+ break;
+ }
+ }
+
+ if (expected)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
+ }
+
+ file_count = file_count + i;
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ CHECK_VALUE(file_count, NFILES + 2);
+
+ for (i = 0; i < NFILES; i++) {
+ if (files[j].found)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): expected to find %s, but didn't\n",
+ __location__, files[j].name);
+ ret = false;
+ goto done;
}
+ done:
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ test fixed enumeration
+*/
+
+static bool test_fixed(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create create;
+ struct smb2_handle h, h2;
+ struct smb2_find f;
+ union smb_search_data *d;
+ struct file_elem files[NFILES] = {};
+ NTSTATUS status;
+ bool ret = true;
+ uint_t count;
+ int i;
+
+ status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h2 = create.out.file.handle;
+
ZERO_STRUCT(f);
- f.in.file.handle = handle;
+ f.in.file.handle = h;
f.in.pattern = "*";
f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
f.in.max_response_size = 0x100;
f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+ /* Start enumeration on h, then delete all from h2 */
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ f.in.file.handle = h2;
+
do {
status = smb2_find_level(tree, tree, &f, &count, &d);
- if (!NT_STATUS_IS_OK(status)) {
- printf("SMB2_FIND_ID_BOTH_DIRECTORY_INFO failed - %s\n", nt_errstr(status));
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ const char *found = d[i].both_directory_info.name.s;
+ char *path = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, found);
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ status = smb2_util_unlink(tree, path);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ talloc_free(path);
}
- printf("Got %d files\n", count);
- for (i=0;i<count;i++) {
- printf("\t'%s'\n",
- d[i].both_directory_info.name.s);
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ /* Now finish h enumeration. */
+ f.in.file.handle = h;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
}
+
f.in.continue_flags = 0;
f.in.max_response_size = 4096;
} while (count != 0);
+ done:
+ smb2_util_close(tree, h);
+ smb2_util_close(tree, h2);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
return ret;
}
+static struct {
+ const char *name;
+ uint8_t level;
+ enum smb_search_data_level data_level;
+ int name_offset;
+ int resume_key_offset;
+ uint32_t capability_mask;
+ NTSTATUS status;
+ union smb_search_data data;
+} levels[] = {
+ {"SMB2_FIND_DIRECTORY_INFO",
+ SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
+ offsetof(union smb_search_data, directory_info.name.s),
+ offsetof(union smb_search_data, directory_info.file_index),
+ },
+ {"SMB2_FIND_FULL_DIRECTORY_INFO",
+ SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
+ offsetof(union smb_search_data, full_directory_info.name.s),
+ offsetof(union smb_search_data, full_directory_info.file_index),
+ },
+ {"SMB2_FIND_NAME_INFO",
+ SMB2_FIND_NAME_INFO, RAW_SEARCH_DATA_NAME_INFO,
+ offsetof(union smb_search_data, name_info.name.s),
+ offsetof(union smb_search_data, name_info.file_index),
+ },
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO",
+ SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+ offsetof(union smb_search_data, both_directory_info.name.s),
+ offsetof(union smb_search_data, both_directory_info.file_index),
+ },
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO",
+ SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
+ offsetof(union smb_search_data, id_full_directory_info.name.s),
+ offsetof(union smb_search_data, id_full_directory_info.file_index),
+ },
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO",
+ SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
+ offsetof(union smb_search_data, id_both_directory_info.name.s),
+ offsetof(union smb_search_data, id_both_directory_info.file_index),
+ }
+};
+
+/*
+ extract the name from a smb_data structure and level
+*/
+static const char *extract_name(union smb_search_data *data,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ if (level == levels[i].level &&
+ data_level == levels[i].data_level) {
+ return *(const char **)(levels[i].name_offset + (char *)data);
+ }
+ }
+ return NULL;
+}
+
+/* find a level in the table by name */
+static union smb_search_data *find(const char *name)
+{
+ int i;
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ if (NT_STATUS_IS_OK(levels[i].status) &&
+ strcmp(levels[i].name, name) == 0) {
+ return &levels[i].data;
+ }
+ }
+ return NULL;
+}
+
+static bool fill_level_data(TALLOC_CTX *mem_ctx,
+ union smb_search_data *data,
+ union smb_search_data *d,
+ uint_t count,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ const char *sname = NULL;
+ for (i=0; i < count ; i++) {
+ sname = extract_name(&d[i], level, data_level);
+ if (sname == NULL)
+ return false;
+ if (!strcmp(sname, ".") || !strcmp(sname, ".."))
+ continue;
+ *data = d[i];
+ }
+ return true;
+}
+
+
+NTSTATUS torture_single_file_search(struct smb2_tree *tree,
+ TALLOC_CTX *mem_ctx,
+ const char *pattern,
+ uint8_t level,
+ enum smb_search_data_level data_level,
+ int index,
+ union smb_search_data *d,
+ uint_t *count,
+ struct smb2_handle *h)
+{
+ struct smb2_find f;
+ NTSTATUS status;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = *h;
+ f.in.pattern = pattern;
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+ f.in.max_response_size = 0x100;
+ f.in.level = level;
+
+ status = smb2_find_level(tree, tree, &f, count, &d);
+ if (NT_STATUS_IS_OK(status))
+ fill_level_data(mem_ctx, &levels[index].data, d, *count, level,
+ data_level);
+ return status;
+}
+
+/*
+ basic testing of all File Information Classes using a single file
+*/
+static bool test_one_file(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ bool ret = true;
+ const char *fname = "torture_search.txt";
+ NTSTATUS status;
+ int i;
+ uint_t count;
+ union smb_fileinfo all_info2, alt_info, internal_info;
+ union smb_search_data *s;
+ union smb_search_data d;
+ struct smb2_handle h, h2;
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ status = smb2_create_complex_file(tree, DNAME "\\torture_search.txt",
+ &h2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* call all the File Information Classes */
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ torture_comment(tctx, "testing %s %d\n", levels[i].name,
+ levels[i].level);
+
+ levels[i].status = torture_single_file_search(tree, mem_ctx,
+ fname, levels[i].level, levels[i].data_level,
+ i, &d, &count, &h);
+ CHECK_STATUS(levels[i].status, NT_STATUS_OK);
+ }
+
+ /* get the all_info file into to check against */
+ all_info2.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ all_info2.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &all_info2);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_ALL_INFO failed");
+
+ alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
+ alt_info.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &alt_info);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_ALT_NAME_INFO failed");
+
+ internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
+ internal_info.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &internal_info);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_INTERNAL_INFORMATION failed");
+
+#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if ((s->sname1.field1) != (v.sname2.out.field2)) { \
+ printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \
+ __location__, \
+ #sname1, #field1, (int)s->sname1.field1, \
+ #sname2, #field2, (int)v.sname2.out.field2); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (s->sname1.field1 != \
+ (~1 & nt_time_to_unix(v.sname2.out.field2))) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, \
+ timestring(tctx, s->sname1.field1), \
+ #sname2, #field2, \
+ nt_time_string(tctx, v.sname2.out.field2)); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (s->sname1.field1 != v.sname2.out.field2) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, \
+ nt_time_string(tctx, s->sname1.field1), \
+ #sname2, #field2, \
+ nt_time_string(tctx, v.sname2.out.field2)); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1 || \
+ strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1, \
+ #sname2, #field2, v.sname2.out.field2.s); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1.s || \
+ strcmp(s->sname1.field1.s, v.sname2.out.field2.s)) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1.s, \
+ #sname2, #field2, v.sname2.out.field2.s); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_NAME(name, sname1, field1, fname, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1.s || \
+ strcmp(s->sname1.field1.s, fname)) { \
+ printf("(%s) %s/%s [%s] != %s\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1.s, \
+ fname); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1 || \
+ strcmp(s->sname1.field1, fname)) { \
+ printf("(%s) %s/%s [%s] != %s\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1, \
+ fname); \
+ ret = false; \
+ } \
+ }} while (0)
+
+ /* check that all the results are as expected */
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, attrib, all_info2, all_info2, attrib);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time);
+
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, size, all_info2, all_info2, size);
+
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, ea_size, all_info2, all_info2, ea_size);
+
+ CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, short_name, alt_info, alt_name_info, fname, STR_UNICODE);
+
+ CHECK_NAME("SMB2_FIND_DIRECTORY_INFO", directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_NAME_INFO", name_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id);
+
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id);
+
+done:
+ smb2_util_close(tree, h);
+ smb2_util_unlink(tree, fname);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+
+struct multiple_result {
+ TALLOC_CTX *tctx;
+ int count;
+ union smb_search_data *list;
+};
+
+bool fill_result(void *private_data,
+ union smb_search_data *file,
+ int count,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ const char *sname;
+ struct multiple_result *data = (struct multiple_result *)private_data;
+
+ for (i=0; i<count; i++) {
+ sname = extract_name(&file[i], level, data_level);
+ if (!strcmp(sname, ".") || !(strcmp(sname, "..")))
+ continue;
+ data->count++;
+ data->list = talloc_realloc(data->tctx,
+ data->list,
+ union smb_search_data,
+ data->count);
+ data->list[data->count-1] = file[i];
+ }
+ return true;
+}
+
+enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART};
+
+static NTSTATUS multiple_smb2_search(struct smb2_tree *tree,
+ TALLOC_CTX *tctx,
+ const char *pattern,
+ uint8_t level,
+ enum smb_search_data_level data_level,
+ enum continue_type cont_type,
+ void *data,
+ struct smb2_handle *h)
+{
+ struct smb2_find f;
+ bool ret = true;
+ uint_t count = 0;
+ union smb_search_data *d;
+ NTSTATUS status;
+ struct multiple_result *result = (struct multiple_result *)data;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = *h;
+ f.in.pattern = pattern;
+ f.in.max_response_size = 0x1000;
+ f.in.level = level;
+
+ /* The search should start from the beginning everytime */
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(result, d, count, level, data_level)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * After the first iteration is complete set the CONTINUE
+ * FLAGS appropriately
+ */
+ switch (cont_type) {
+ case CONT_INDEX:
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+ break;
+ case CONT_SINGLE:
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ break;
+ case CONT_RESTART:
+ default:
+ /* we should prevent staying in the loop forever */
+ f.in.continue_flags = 0;
+ break;
+ }
+ } while (count != 0);
+done:
+ return status;
+}
+
+
+static enum smb_search_data_level compare_data_level;
+uint8_t level_sort;
-/*
- basic testing of directory listing with continue
+static int search_compare(union smb_search_data *d1,
+ union smb_search_data *d2)
+{
+ const char *s1, *s2;
+
+ s1 = extract_name(d1, level_sort, compare_data_level);
+ s2 = extract_name(d2, level_sort, compare_data_level);
+ return strcmp_safe(s1, s2);
+}
+
+/*
+ basic testing of search calls using many files
*/
-bool torture_smb2_dir(struct torture_context *torture)
+static bool test_many_files(struct torture_context *tctx,
+ struct smb2_tree *tree)
{
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- struct smb2_tree *tree;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 700;
+ int i, t;
+ char *fname;
bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_create create;
+ struct smb2_handle h;
+ struct {
+ const char *name;
+ const char *cont_name;
+ uint8_t level;
+ enum smb_search_data_level data_level;
+ enum continue_type cont_type;
+ } search_types[] = {
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_DIRECTORY_INFO", "SINGLE", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_DIRECTORY_INFO", "INDEX", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_DIRECTORY_INFO", "RESTART", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART}
+ };
- if (!torture_smb2_connection(torture, &tree)) {
+ smb2_deltree(tree, DNAME);
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ torture_comment(tctx, "Testing with %d files\n", num_files);
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i=num_files-1;i>=0;i--) {
+ fname = talloc_asprintf(mem_ctx, DNAME "\\t%03d-%d.txt", i, i);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s", fname);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ talloc_free(fname);
+ }
+
+ for (t=0;t<ARRAY_SIZE(search_types);t++) {
+ ZERO_STRUCT(result);
+ result.tctx = talloc_new(tctx);
+
+ torture_comment(tctx,
+ "Continue %s via %s\n", search_types[t].name,
+ search_types[t].cont_name);
+ status = multiple_smb2_search(tree, tctx, "*",
+ search_types[t].level,
+ search_types[t].data_level,
+ search_types[t].cont_type,
+ &result, &h);
+
+ CHECK_VALUE(result.count, num_files);
+
+ compare_data_level = search_types[t].data_level;
+ level_sort = search_types[t].level;
+
+ qsort(result.list, result.count, sizeof(result.list[0]),
+ QSORT_CAST search_compare);
+
+ for (i=0;i<result.count;i++) {
+ const char *s;
+ enum smb_search_level level;
+ level = RAW_SEARCH_SMB2;
+ s = extract_name(&result.list[i],
+ search_types[t].level,
+ compare_data_level);
+ fname = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+ torture_assert_str_equal(tctx, fname, s,
+ "Incorrect name");
+ talloc_free(fname);
+ }
+ talloc_free(result.tctx);
+ }
+
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ check a individual file result
+*/
+static bool check_result(struct multiple_result *result,
+ const char *name,
+ bool exist,
+ uint32_t attrib)
+{
+ int i;
+ for (i=0;i<result->count;i++) {
+ if (strcmp(name,
+ result->list[i].both_directory_info.name.s) == 0) {
+ break;
+ }
+ }
+ if (i == result->count) {
+ if (exist) {
+ printf("failed: '%s' should exist with attribute %s\n",
+ name, attrib_string(result->list, attrib));
+ return false;
+ }
+ return true;
+ }
+
+ if (!exist) {
+ printf("failed: '%s' should NOT exist (has attribute %s)\n",
+ name, attrib_string(result->list,
+ result->list[i].both_directory_info.attrib));
return false;
}
- ret &= torture_smb2_find_dir(tree);
+ if ((result->list[i].both_directory_info.attrib&0xFFF) != attrib) {
+ printf("failed: '%s' should have attribute 0x%x (has 0x%x)\n",
+ name,
+ attrib, result->list[i].both_directory_info.attrib);
+ return false;
+ }
+ return true;
+}
+
+/*
+ test what happens when the directory is modified during a search
+*/
+static bool test_modify_search(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ int num_files = 700;
+ struct multiple_result result;
+ union smb_setfileinfo sfinfo;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create create;
+ struct smb2_handle h;
+ struct smb2_find f;
+ union smb_search_data *d;
+ struct file_elem files[700] = {};
+ NTSTATUS status;
+ bool ret = true;
+ int i;
+ uint_t count;
+
+ smb2_deltree(tree, DNAME);
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("Creating %d files\n", num_files);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = num_files-1; i >= 0; i--) {
+ files[i].name = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+
+ printf("pulling the first two files\n");
+ ZERO_STRUCT(result);
+ result.tctx = talloc_new(tctx);
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ }while(result.count < 2);
+
+ printf("Changing attributes and deleting\n");
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ files[num_files].name = talloc_asprintf(mem_ctx, "T003-03.txt.2");
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+ files[num_files].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ files[num_files + 1].name = talloc_asprintf(mem_ctx, "T013-13.txt.2");
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+ files[num_files + 1].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+
+ files[num_files + 2].name = talloc_asprintf(mem_ctx, "T013-13.txt.3");
+ status = smb2_create_complex_file(tree, DNAME "\\T013-13.txt.3", &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ smb2_util_unlink(tree, DNAME "\\T014-14.txt");
+ smb2_util_setatr(tree, DNAME "\\T015-15.txt", FILE_ATTRIBUTE_HIDDEN);
+ smb2_util_setatr(tree, DNAME "\\T016-16.txt", FILE_ATTRIBUTE_NORMAL);
+ smb2_util_setatr(tree, DNAME "\\T017-17.txt", FILE_ATTRIBUTE_SYSTEM);
+ smb2_util_setatr(tree, DNAME "\\T018-18.txt", 0);
+ smb2_util_setatr(tree, DNAME "\\T039-39.txt", FILE_ATTRIBUTE_HIDDEN);
+ smb2_util_setatr(tree, DNAME "\\T000-0.txt", FILE_ATTRIBUTE_HIDDEN);
+ sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
+ sfinfo.generic.in.file.path = DNAME "\\T013-13.txt.3";
+ sfinfo.disposition_info.in.delete_on_close = 1;
+ status = smb2_composite_setpathinfo(tree, &sfinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* Reset the numfiles to include the new files and start the
+ * search from the beginning */
+ num_files = num_files + 2;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+ result.count = 0;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+
+ ret &= check_result(&result, "t039-39.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t000-0.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t014-14.txt", false, 0);
+ ret &= check_result(&result, "t015-15.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t016-16.txt", true, FILE_ATTRIBUTE_NORMAL);
+ ret &= check_result(&result, "t017-17.txt", true, FILE_ATTRIBUTE_SYSTEM);
+ ret &= check_result(&result, "t018-18.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "t019-19.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "T013-13.txt.2", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "T003-3.txt.2", false, 0);
+ ret &= check_result(&result, "T013-13.txt.3", true, FILE_ATTRIBUTE_NORMAL);
+
+ if (!ret) {
+ for (i=0;i<result.count;i++) {
+ printf("%s %s (0x%x)\n",
+ result.list[i].both_directory_info.name.s,
+ attrib_string(tctx,
+ result.list[i].both_directory_info.attrib),
+ result.list[i].both_directory_info.attrib);
+ }
+ }
+ done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
talloc_free(mem_ctx);
return ret;
}
+
+/*
+ testing if directories always come back sorted
+*/
+static bool test_sorted(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 700;
+ int i;
+ struct file_elem files[700] = {};
+ bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_handle h;
+
+ printf("Testing if directories always come back sorted\n");
+ status = populate_tree(tctx, mem_ctx, tree, files, num_files, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+
+ status = multiple_smb2_search(tree, tctx, "*",
+ SMB2_FIND_BOTH_DIRECTORY_INFO,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+ SMB2_CONTINUE_FLAG_SINGLE,
+ &result, &h);
+
+ CHECK_VALUE(result.count, num_files);
+
+ for (i=0;i<num_files-1;i++) {
+ const char *name1, *name2;
+ name1 = result.list[i].both_directory_info.name.s;
+ name2 = result.list[i+1].both_directory_info.name.s;
+ if (strcasecmp_m(name1, name2) > 0) {
+ printf("non-alphabetical order at entry %d '%s' '%s'"
+ "\n", i, name1, name2);
+ torture_comment(tctx,
+ "Server does not produce sorted directory listings"
+ "(not an error)\n");
+ goto done;
+ }
+ }
+ talloc_free(result.list);
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/* test the behavior of file_index field in the SMB2_FIND struct */
+
+static bool test_file_index(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 100;
+ int resume_index = 4;
+ int i;
+ char *fname;
+ bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_create create;
+ struct smb2_find f;
+ struct smb2_handle h;
+ union smb_search_data *d;
+ int count;
+
+ smb2_deltree(tree, DNAME);
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("Testing the behavior of file_index flag\n");
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ for (i = num_files-1; i >= 0; i--) {
+ fname = talloc_asprintf(mem_ctx, DNAME "\\file%u.txt", i);
+ create.in.fname = fname;
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ talloc_free(fname);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x1000;
+ f.in.level = SMB2_FIND_FULL_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ } while(result.count < 10);
+
+ if (result.list[0].full_directory_info.file_index == 0) {
+ torture_comment(tctx,
+ "Talking to a server that doesn't provide a "
+ "file index.\nWindows servers using NTFS do "
+ "not provide a file_index. Skipping test\n");
+ goto done;
+ } else {
+ /* We are not talking to a Windows based server. Windows
+ * servers using NTFS do not provide a file_index. Windows
+ * server using FAT do provide a file index, however in both
+ * cases they do not honor a file index on a resume request.
+ * See MS-FSCC <62> and MS-SMB2 <54> for more information. */
+
+ /* Set the file_index flag to point to the fifth file from the
+ * previous enumeration and try to start the subsequent
+ * searches from that point */
+ f.in.file_index =
+ result.list[resume_index].full_directory_info.file_index;
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+
+ /* get the name of the next expected file */
+ fname = talloc_asprintf(mem_ctx, DNAME "\\%s",
+ result.list[resume_index].full_directory_info.name.s);
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ goto done;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ if (strcmp(fname,
+ result.list[0].full_directory_info.name.s)) {
+ printf("next expected file: %s but the server "
+ "returned %s\n", fname,
+ result.list[0].full_directory_info.name.s);
+ torture_comment(tctx,
+ "Not an error. Resuming using a file "
+ "index is an optional feature of the "
+ "protocol.\n");
+ goto done;
+ }
+ }
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ * Tests directory enumeration in a directory containing >1000 files with
+ * names of varying lengths.
+ */
+static bool test_large_files(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 2000;
+ int i, j = 1, retry_count = 0;
+ struct file_elem files[2000] = {};
+ bool ret = true;
+ NTSTATUS status;
+ struct smb2_create create;
+ struct smb2_find f;
+ struct smb2_handle h;
+ union smb_search_data *d;
+ int count, file_count = 0;
+
+ torture_comment(tctx,
+ "Testing directory enumeration in a directory with >1000 files\n");
+
+ smb2_deltree(tree, DNAME);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h = create.out.file.handle;
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = 0; i < num_files; i++) {
+ files[i].name = generate_random_str(tctx, j);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ retry_count = 0;
+ if (i%9 == 0)
+ j = j + 1;
+ }
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ bool expected;
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ expected = false;
+ for (j = 0; j < 2000; j++) {
+ if (!strcmp(files[j].name, found)) {
+ files[j].found = true;
+ expected = true;
+ break;
+ }
+ }
+
+ if (expected)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
+ }
+ file_count = file_count + i;
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ CHECK_VALUE(file_count, num_files + 2);
+
+ for (i = 0; i < num_files; i++) {
+ if (files[j].found)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): expected to find %s, but didn't\n",
+ __location__, files[j].name);
+ ret = false;
+ goto done;
+ }
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+struct torture_suite *torture_smb2_dir_init(void)
+{
+ struct torture_suite *suite =
+ torture_suite_create(talloc_autofree_context(), "DIR");
+
+ torture_suite_add_1smb2_test(suite, "FIND", test_find);
+ torture_suite_add_1smb2_test(suite, "FIXED", test_fixed);
+ torture_suite_add_1smb2_test(suite, "ONE", test_one_file);
+ torture_suite_add_1smb2_test(suite, "MANY", test_many_files);
+ torture_suite_add_1smb2_test(suite, "MODIFY", test_modify_search);
+ torture_suite_add_1smb2_test(suite, "SORTED", test_sorted);
+ torture_suite_add_1smb2_test(suite, "FILE-INDEX", test_file_index);
+ torture_suite_add_1smb2_test(suite, "LARGE-FILES", test_large_files);
+ suite->description = talloc_strdup(suite, "SMB2-DIR tests");
+
+ return suite;
+}
{ LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
{ LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
{ LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
-/*
+
{ LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
-*/
+
{ LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
{ LEVEL(RAW_FILEINFO_SEC_DESC) }
};
torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
torture_suite_add_suite(suite, torture_smb2_durable_open_init());
torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1);
+ torture_suite_add_suite(suite, torture_smb2_dir_init());
torture_suite_add_suite(suite, torture_smb2_lease_init());
torture_suite_add_suite(suite, torture_smb2_compound_init());
struct wbsrv_domain *domain;
char *domain_name;
- uint resume_index;
+ uint32_t resume_index;
char *result;
};