summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-05-28 16:12:34 +1000
committerAndrew Tridgell <tridge@samba.org>2009-05-28 16:12:34 +1000
commit5ab03dbecc33320e23304b126f26bde3f6bc6c7d (patch)
treef8478334db04fe03f6ed0a88622a50fe2586b91c
parent47692f39b1b3b5c589bfb63a6968aaf9f9af70c4 (diff)
parentbd1194810787901c5caa08961f97fecbcbd01978 (diff)
downloadsamba-5ab03dbecc33320e23304b126f26bde3f6bc6c7d.tar.gz
samba-5ab03dbecc33320e23304b126f26bde3f6bc6c7d.tar.bz2
samba-5ab03dbecc33320e23304b126f26bde3f6bc6c7d.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
-rw-r--r--.gitignore4
-rw-r--r--WHATSNEW.txt35
-rw-r--r--docs-xml/Samba3-HOWTO/index.xml2
-rw-r--r--docs-xml/manpages-3/idmap_rid.8.xml2
-rw-r--r--docs-xml/manpages-3/smbclient.1.xml8
-rw-r--r--docs-xml/smbdotconf/security/mapuntrustedtodomain.xml33
-rw-r--r--docs-xml/smbdotconf/security/passdbbackend.xml8
-rw-r--r--lib/tdb/tools/tdbtool.c12
-rw-r--r--librpc/gen_ndr/security.h1
-rw-r--r--librpc/idl/security.idl1
-rw-r--r--source3/Makefile.in5
-rw-r--r--source3/client/client.c95
-rw-r--r--source3/client/clitar.c5
-rw-r--r--source3/configure.in2
-rw-r--r--source3/include/includes.h46
-rw-r--r--source3/include/proto.h42
-rw-r--r--source3/include/smb_macros.h6
-rw-r--r--source3/lib/debug.c2
-rw-r--r--source3/lib/system.c231
-rw-r--r--source3/lib/time.c245
-rw-r--r--source3/lib/util.c22
-rw-r--r--source3/libsmb/clifile.c661
-rw-r--r--source3/libsmb/clirap.c6
-rw-r--r--source3/libsmb/libsmb_stat.c12
-rw-r--r--source3/modules/nfs4_acls.c16
-rw-r--r--source3/modules/vfs_acl_tdb.c4
-rw-r--r--source3/modules/vfs_acl_xattr.c4
-rw-r--r--source3/modules/vfs_afsacl.c6
-rw-r--r--source3/modules/vfs_commit.c2
-rw-r--r--source3/modules/vfs_default.c44
-rw-r--r--source3/modules/vfs_fake_perms.c20
-rw-r--r--source3/modules/vfs_fileid.c4
-rw-r--r--source3/modules/vfs_gpfs.c4
-rw-r--r--source3/modules/vfs_hpuxacl.c2
-rw-r--r--source3/modules/vfs_netatalk.c12
-rw-r--r--source3/modules/vfs_recycle.c8
-rw-r--r--source3/modules/vfs_shadow_copy2.c2
-rw-r--r--source3/modules/vfs_streams_depot.c10
-rw-r--r--source3/modules/vfs_streams_xattr.c54
-rw-r--r--source3/modules/vfs_tsmsm.c15
-rw-r--r--source3/nmbd/asyncdns.c4
-rw-r--r--source3/nmbd/nmbd.c4
-rw-r--r--source3/pam_smbpass/pam_smb_acct.c17
-rw-r--r--source3/pam_smbpass/pam_smb_auth.c19
-rw-r--r--source3/pam_smbpass/pam_smb_passwd.c40
-rw-r--r--source3/pam_smbpass/support.c102
-rw-r--r--source3/pam_smbpass/support.h6
-rw-r--r--source3/param/loadparm.c66
-rw-r--r--source3/passdb/lookup_sid.c5
-rw-r--r--source3/passdb/pdb_smbpasswd.c2
-rw-r--r--source3/printing/nt_printing.c4
-rw-r--r--source3/printing/print_cups.c4
-rw-r--r--source3/printing/printfsp.c2
-rw-r--r--source3/printing/printing.c7
-rw-r--r--source3/registry/regfio.c4
-rw-r--r--source3/smbd/close.c2
-rw-r--r--source3/smbd/dir.c12
-rw-r--r--source3/smbd/dosmode.c69
-rw-r--r--source3/smbd/file_access.c14
-rw-r--r--source3/smbd/fileio.c2
-rw-r--r--source3/smbd/filename.c2
-rw-r--r--source3/smbd/globals.c1
-rw-r--r--source3/smbd/globals.h20
-rw-r--r--source3/smbd/msdfs.c2
-rw-r--r--source3/smbd/nttrans.c28
-rw-r--r--source3/smbd/open.c56
-rw-r--r--source3/smbd/posix_acls.c58
-rw-r--r--source3/smbd/process.c18
-rw-r--r--source3/smbd/reply.c71
-rw-r--r--source3/smbd/server.c19
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/signing.c26
-rw-r--r--source3/smbd/smb2_negprot.c23
-rw-r--r--source3/smbd/smb2_server.c116
-rw-r--r--source3/smbd/smb2_sesssetup.c70
-rw-r--r--source3/smbd/smb2_signing.c135
-rw-r--r--source3/smbd/trans2.c165
-rw-r--r--source3/smbd/vfs.c28
-rw-r--r--source3/torture/cmd_vfs.c180
-rw-r--r--source3/torture/torture.c87
-rw-r--r--source3/utils/net_conf.c2
-rw-r--r--source3/utils/net_usershare.c14
-rw-r--r--source3/utils/testparm.c6
-rw-r--r--source3/web/cgi.c8
-rw-r--r--source3/winbindd/idmap.c2
-rw-r--r--source3/winbindd/idmap_ldap.c71
-rw-r--r--source3/winbindd/idmap_tdb.c75
-rw-r--r--source3/winbindd/idmap_tdb2.c61
-rw-r--r--source3/winbindd/winbindd.c5
-rw-r--r--source3/winbindd/winbindd_dual.c5
-rwxr-xr-xsource4/autogen.sh7
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/show_deleted.c2
-rw-r--r--source4/kdc/hdb-samba4.c78
-rw-r--r--source4/lib/events/tevent_s4.c2
-rw-r--r--source4/lib/ldb/common/ldb_controls.c4
-rw-r--r--source4/lib/ldb/modules/asq.c2
-rw-r--r--source4/lib/ldb/modules/paged_results.c2
-rw-r--r--source4/lib/ldb/modules/sort.c2
-rw-r--r--source4/libcli/smb2/connect.c7
-rw-r--r--source4/libcli/smb2/smb2_constants.h14
-rw-r--r--source4/scripting/python/samba/samdb.py4
-rw-r--r--source4/smb_server/smb/negprot.c1
-rw-r--r--source4/smb_server/smb2/negprot.c17
104 files changed, 2301 insertions, 1279 deletions
diff --git a/.gitignore b/.gitignore
index 45164d2985..5d18b2d6f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -232,7 +232,7 @@ source4/lib/tdb/bin/tdbbackup
source4/lib/tdb/bin/tdbdump
source4/lib/tdb/bin/tdbtool
source4/lib/tdb/bin/tdbtorture
-source4/lib/tdr/tdr_proto.h
+lib/tdr/tdr_proto.h
lib/util/apidocs
lib/util/asn1_proto.h
lib/util/pidfile.h
@@ -316,6 +316,8 @@ librpc/gen_ndr/cli_drsblobs.h
librpc/gen_ndr/srv_drsblobs.c
librpc/gen_ndr/srv_drsblobs.h
source3/setup
+librpc/gen_ndr/cli_dcerpc.[ch]
+librpc/gen_ndr/srv_dcerpc.[ch]
librpc/gen_ndr/*wzcsvc*
librpc/gen_ndr/*w32time*
librpc/gen_ndr/*wmi*
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 066f718999..fe8d541de8 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -14,6 +14,9 @@ Authentication Changes:
o Changed the way smbd handles untrusted domain names given during user
authentication
+net Command Changes:
+o parameter syntax made more consistent
+
Authentication Changes
======================
@@ -32,6 +35,38 @@ on smbd to always pass through bogus names to the DC for verification. A new
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
#######################################
diff --git a/docs-xml/Samba3-HOWTO/index.xml b/docs-xml/Samba3-HOWTO/index.xml
index 87b07951c7..8321714867 100644
--- a/docs-xml/Samba3-HOWTO/index.xml
+++ b/docs-xml/Samba3-HOWTO/index.xml
@@ -3,7 +3,7 @@
<book id="Samba-HOWTO-Collection"
xmlns:xi="http://www.w3.org/2003/XInclude">
-<title>The Official Samba 3.2.x HOWTO and Reference Guide</title>
+<title>The Official Samba 3.5.x HOWTO and Reference Guide</title>
<bookinfo>
<authorgroup>
diff --git a/docs-xml/manpages-3/idmap_rid.8.xml b/docs-xml/manpages-3/idmap_rid.8.xml
index 5449797441..55aed62f85 100644
--- a/docs-xml/manpages-3/idmap_rid.8.xml
+++ b/docs-xml/manpages-3/idmap_rid.8.xml
@@ -66,7 +66,7 @@
</programlisting>
</para>
<para>
- Correspondingly, the formula for calculationg the RID for a
+ Correspondingly, the formula for calculating the RID for a
given Unix ID is this:
<programlisting>
RID = ID + BASE_RID - LOW_RANGE_ID.
diff --git a/docs-xml/manpages-3/smbclient.1.xml b/docs-xml/manpages-3/smbclient.1.xml
index 7785d2c093..9840414e44 100644
--- a/docs-xml/manpages-3/smbclient.1.xml
+++ b/docs-xml/manpages-3/smbclient.1.xml
@@ -916,6 +916,14 @@
</varlistentry>
<varlistentry>
+ <term>readlink symlinkname</term>
+ <listitem><para>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. Print
+ the value of the symlink "symlinkname".
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>rd &lt;directory name&gt;</term>
<listitem><para>See the rmdir command. </para></listitem>
</varlistentry>
diff --git a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
new file mode 100644
index 0000000000..bcf65e6eb6
--- /dev/null
+++ b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
@@ -0,0 +1,33 @@
+<samba:parameter name="map untrusted to domain"
+ context="G"
+ type="boolean"
+ advanced="1"
+ developer="1"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+ <para>
+ If a client connects to smbd using an untrusted domain name, such as
+ BOGUS\user, smbd replaces the BOGUS domain with it's SAM name before
+ attempting to authenticate that user. In the case where smbd is acting as
+ a PDC this will be DOMAIN\user. In the case where smbd is acting as a
+ domain member server or a standalone server this will be WORKSTATION\user.
+ </para>
+
+ <para>
+ In previous versions of Samba (pre 3.4), if smbd was acting as a domain
+ member server, the BOGUS domain name would instead be replaced by the
+ primary domain which smbd was a member of. In this case authentication
+ would be deferred off to a DC using the credentials DOMAIN\user.
+ </para>
+
+ <para>
+ When this parameter is set to <constant>yes</constant> smbd provides the
+ legacy behavior of mapping untrusted domain names to the primary domain.
+ When smbd is not acting as a domain member server, this parameter has no
+ effect.
+ </para>
+
+</description>
+
+<value type="default">no</value>
+</samba:parameter>
diff --git a/docs-xml/smbdotconf/security/passdbbackend.xml b/docs-xml/smbdotconf/security/passdbbackend.xml
index 487d8b8a9d..b761f970c0 100644
--- a/docs-xml/smbdotconf/security/passdbbackend.xml
+++ b/docs-xml/smbdotconf/security/passdbbackend.xml
@@ -16,8 +16,10 @@
<para>Available backends can include:
<itemizedlist>
<listitem>
- <para><command moreinfo="none">smbpasswd</command> - The default smbpasswd
- backend. Takes a path to the smbpasswd file as an optional argument.
+ <para><command moreinfo="none">smbpasswd</command> - The old plaintext passdb
+ backend. Some Samba features will not work if this passdb
+ backend is used. Takes a path to the smbpasswd file as an
+ optional argument.
</para>
</listitem>
@@ -60,5 +62,5 @@ passdb backend = ldapsam:"ldap://ldap-1.example.com ldap-2.example.com"
</programlisting>
</description>
-<value type="default">smbpasswd</value>
+<value type="default">tdbsam</value>
</samba:parameter>
diff --git a/lib/tdb/tools/tdbtool.c b/lib/tdb/tools/tdbtool.c
index 3220e47b13..c0814e11de 100644
--- a/lib/tdb/tools/tdbtool.c
+++ b/lib/tdb/tools/tdbtool.c
@@ -401,8 +401,8 @@ static void speed_tdb(const char *tlimit)
do {
long int r = random();
TDB_DATA key, dbuf;
- key.dptr = "store test";
- key.dsize = strlen(key.dptr);
+ key.dptr = (unsigned char *)"store test";
+ key.dsize = strlen((char *)key.dptr);
dbuf.dptr = (unsigned char *)&r;
dbuf.dsize = sizeof(r);
tdb_store(tdb, key, dbuf, TDB_REPLACE);
@@ -417,8 +417,8 @@ static void speed_tdb(const char *tlimit)
do {
long int r = random();
TDB_DATA key, dbuf;
- key.dptr = "store test";
- key.dsize = strlen(key.dptr);
+ key.dptr = (unsigned char *)"store test";
+ key.dsize = strlen((char *)key.dptr);
dbuf.dptr = (unsigned char *)&r;
dbuf.dsize = sizeof(r);
tdb_fetch(tdb, key);
@@ -433,8 +433,8 @@ static void speed_tdb(const char *tlimit)
do {
long int r = random();
TDB_DATA key, dbuf;
- key.dptr = "transaction test";
- key.dsize = strlen(key.dptr);
+ key.dptr = (unsigned char *)"transaction test";
+ key.dsize = strlen((char *)key.dptr);
dbuf.dptr = (unsigned char *)&r;
dbuf.dsize = sizeof(r);
tdb_transaction_start(tdb);
diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h
index f90dd413a8..16635f0bb8 100644
--- a/librpc/gen_ndr/security.h
+++ b/librpc/gen_ndr/security.h
@@ -126,6 +126,7 @@
#define DOMAIN_RID_GUEST ( 501 )
#define DOMAIN_RID_ADMINS ( 512 )
#define DOMAIN_RID_USERS ( 513 )
+#define DOMAIN_RID_KRBTGT ( 514 )
#define DOMAIN_RID_DOMAIN_MEMBERS ( 515 )
#define DOMAIN_RID_DCS ( 516 )
#define DOMAIN_RID_CERT_ADMINS ( 517 )
diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index 825ce96d71..9e47ff45fc 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -226,6 +226,7 @@ interface security
const int DOMAIN_RID_GUEST = 501;
const int DOMAIN_RID_ADMINS = 512;
const int DOMAIN_RID_USERS = 513;
+ const int DOMAIN_RID_KRBTGT = 514;
const int DOMAIN_RID_DOMAIN_MEMBERS = 515;
const int DOMAIN_RID_DCS = 516;
const int DOMAIN_RID_CERT_ADMINS = 517;
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 1120092f90..2b30b4a5bd 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -359,7 +359,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \
../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \
- ../lib/crypto/md4.o
+ ../lib/crypto/md4.o \
+ ../lib/crypto/sha256.o ../lib/crypto/hmacsha256.o
LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \
@@ -750,7 +751,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/dnsregister.o smbd/globals.o \
smbd/smb2_server.o smbd/smb2_negprot.o \
smbd/smb2_sesssetup.o smbd/smb2_tcon.o \
- smbd/smb2_keepalive.o \
+ smbd/smb2_keepalive.o smbd/smb2_signing.o \
$(MANGLE_OBJ) @VFS_STATIC@
SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
diff --git a/source3/client/client.c b/source3/client/client.c
index 59e5c1ad72..2edeb1ae2b 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2725,7 +2725,7 @@ static int cmd_link(void)
return 1;
}
- if (!cli_unix_hardlink(targetcli, targetname, newname)) {
+ if (!NT_STATUS_IS_OK(cli_posix_hardlink(targetcli, targetname, newname))) {
d_printf("%s linking files (%s -> %s)\n", cli_errstr(targetcli), newname, oldname);
return 1;
}
@@ -2733,6 +2733,54 @@ static int cmd_link(void)
}
/****************************************************************************
+ UNIX readlink.
+****************************************************************************/
+
+static int cmd_readlink(void)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *name= NULL;
+ char *buf = NULL;
+ char *targetname = NULL;
+ char linkname[PATH_MAX+1];
+ struct cli_state *targetcli;
+
+ if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
+ d_printf("readlink <name>\n");
+ return 1;
+ }
+ name = talloc_asprintf(ctx,
+ "%s%s",
+ client_get_cur_dir(),
+ buf);
+ if (!name) {
+ return 1;
+ }
+
+ if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) {
+ d_printf("readlink %s: %s\n", name, cli_errstr(cli));
+ return 1;
+ }
+
+ if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
+ d_printf("Server doesn't support UNIX CIFS calls.\n");
+ return 1;
+ }
+
+ if (!NT_STATUS_IS_OK(cli_posix_readlink(targetcli, name,
+ linkname, PATH_MAX+1))) {
+ d_printf("%s readlink on file %s\n",
+ cli_errstr(targetcli), name);
+ return 1;
+ }
+
+ d_printf("%s -> %s\n", name, linkname);
+
+ return 0;
+}
+
+
+/****************************************************************************
UNIX symlink.
****************************************************************************/
@@ -2776,7 +2824,7 @@ static int cmd_symlink(void)
return 1;
}
- if (!cli_unix_symlink(targetcli, targetname, newname)) {
+ if (!NT_STATUS_IS_OK(cli_posix_symlink(targetcli, targetname, newname))) {
d_printf("%s symlinking files (%s -> %s)\n",
cli_errstr(targetcli), newname, targetname);
return 1;
@@ -3022,7 +3070,7 @@ static int cmd_getfacl(void)
}
d_printf("# file: %s\n", src);
- d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+ d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_ex_uid, (unsigned int)sbuf.st_ex_gid);
if (num_file_acls == 0 && num_dir_acls == 0) {
d_printf("No acls found.\n");
@@ -3120,6 +3168,7 @@ static int cmd_stat(void)
fstring mode_str;
SMB_STRUCT_STAT sbuf;
struct tm *lt;
+ time_t tmp_time;
if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
d_printf("stat file\n");
@@ -3152,30 +3201,31 @@ static int cmd_stat(void)
/* Print out the stat values. */
d_printf("File: %s\n", src);
d_printf("Size: %-12.0f\tBlocks: %u\t%s\n",
- (double)sbuf.st_size,
- (unsigned int)sbuf.st_blocks,
- filetype_to_str(sbuf.st_mode));
+ (double)sbuf.st_ex_size,
+ (unsigned int)sbuf.st_ex_blocks,
+ filetype_to_str(sbuf.st_ex_mode));
#if defined(S_ISCHR) && defined(S_ISBLK)
- if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) {
+ if (S_ISCHR(sbuf.st_ex_mode) || S_ISBLK(sbuf.st_ex_mode)) {
d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n",
- (double)sbuf.st_ino,
- (unsigned int)sbuf.st_nlink,
- unix_dev_major(sbuf.st_rdev),
- unix_dev_minor(sbuf.st_rdev));
+ (double)sbuf.st_ex_ino,
+ (unsigned int)sbuf.st_ex_nlink,
+ unix_dev_major(sbuf.st_ex_rdev),
+ unix_dev_minor(sbuf.st_ex_rdev));
} else
#endif
d_printf("Inode: %.0f\tLinks: %u\n",
- (double)sbuf.st_ino,
- (unsigned int)sbuf.st_nlink);
+ (double)sbuf.st_ex_ino,
+ (unsigned int)sbuf.st_ex_nlink);
d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n",
- ((int)sbuf.st_mode & 0777),
- unix_mode_to_str(mode_str, sbuf.st_mode),
- (unsigned int)sbuf.st_uid,
- (unsigned int)sbuf.st_gid);
+ ((int)sbuf.st_ex_mode & 0777),
+ unix_mode_to_str(mode_str, sbuf.st_ex_mode),
+ (unsigned int)sbuf.st_ex_uid,
+ (unsigned int)sbuf.st_ex_gid);
- lt = localtime(&sbuf.st_atime);
+ tmp_time = convert_timespec_to_time_t(sbuf.st_ex_atime);
+ lt = localtime(&tmp_time);
if (lt) {
strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
} else {
@@ -3183,7 +3233,8 @@ static int cmd_stat(void)
}
d_printf("Access: %s\n", mode_str);
- lt = localtime(&sbuf.st_mtime);
+ tmp_time = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ lt = localtime(&tmp_time);
if (lt) {
strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
} else {
@@ -3191,7 +3242,8 @@ static int cmd_stat(void)
}
d_printf("Modify: %s\n", mode_str);
- lt = localtime(&sbuf.st_ctime);
+ tmp_time = convert_timespec_to_time_t(sbuf.st_ex_ctime);
+ lt = localtime(&tmp_time);
if (lt) {
strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
} else {
@@ -3400,7 +3452,7 @@ static int cmd_newer(void)
ok = next_token_talloc(ctx, &cmd_ptr,&buf,NULL);
if (ok && (sys_stat(buf,&sbuf) == 0)) {
- newer_than = sbuf.st_mtime;
+ newer_than = convert_timespec_to_time_t(sbuf.st_ex_mtime);
DEBUG(1,("Getting files newer than %s",
time_to_asc(newer_than)));
} else {
@@ -3949,6 +4001,7 @@ static struct {
{"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
{"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+ {"readlink",cmd_readlink,"filename Do a UNIX extensions readlink call on a symlink",{COMPL_REMOTE,COMPL_REMOTE}},
{"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
{"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},
{"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index ff71924555..d973329427 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -412,7 +412,7 @@ static void dotareof(int f)
/* Could be a pipe, in which case S_ISREG should fail,
* and we should write out at full size */
if (tp > 0) {
- size_t towrite = S_ISREG(stbuf.st_mode) ? tp : tbufsiz;
+ size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz;
if (sys_write(f, tarbuf, towrite) != towrite) {
DEBUG(0,("dotareof: sys_write fail\n"));
}
@@ -1793,7 +1793,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
SMB_STRUCT_STAT stbuf;
if (sys_stat(argv[Optind], &stbuf) == 0) {
- newer_than = stbuf.st_mtime;
+ newer_than = convert_timespec_to_time_t(
+ stbuf.st_ex_mtime);
DEBUG(1,("Getting files newer than %s",
time_to_asc(newer_than)));
newOptind++;
diff --git a/source3/configure.in b/source3/configure.in
index 44374b989c..f980911666 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -2778,6 +2778,8 @@ if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then
AC_DEFINE(HAVE_STAT_ST_BLOCKS,1,[Whether the stat struct has a st_block property])
fi
+AC_CHECK_TYPES([blksize_t, blkcnt_t], [], [], [[#include <sys/stat.h>]])
+
AC_CACHE_CHECK([for st_blksize in struct stat],samba_cv_HAVE_STAT_ST_BLKSIZE,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/stat.h>
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 596c772d9e..e468bd5c38 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -431,17 +431,49 @@ typedef uint64_t br_off;
#define IVAL_TO_SMB_OFF_T(buf,off) ((SMB_OFF_T)(( ((uint32)(IVAL((buf),(off)))) & 0xFFFFFFFF )))
#endif
+#ifndef HAVE_BLKSIZE_T
+/* This is mainly for HP/UX which defines st_blksize as long */
+typedef long blksize_t;
+#endif
+
+#ifndef HAVE_BLKCNT_T
+/* This is mainly for HP/UX which doesn't have blkcnt_t */
+typedef long blkcnt_t;
+#endif
+
/*
* Type for stat structure.
*/
-#ifndef SMB_STRUCT_STAT
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
-# define SMB_STRUCT_STAT struct stat64
-# else
-# define SMB_STRUCT_STAT struct stat
-# endif
-#endif
+struct stat_ex {
+ dev_t st_ex_dev;
+ ino_t st_ex_ino;
+ mode_t st_ex_mode;
+ nlink_t st_ex_nlink;
+ uid_t st_ex_uid;
+ gid_t st_ex_gid;
+ dev_t st_ex_rdev;
+ off_t st_ex_size;
+ struct timespec st_ex_atime;
+ struct timespec st_ex_mtime;
+ struct timespec st_ex_ctime;
+ struct timespec st_ex_btime; /* birthtime */
+ blksize_t st_ex_blksize;
+ blkcnt_t st_ex_blocks;
+
+ uint32_t st_ex_flags;
+ uint32_t st_ex_mask;
+
+ /*
+ * Add space for VFS internal extensions. The initial user of this
+ * would be the onefs modules, passing the snapid from the stat calls
+ * to the file_id_create call. Maybe we'll have to expand this later,
+ * but the core of Samba should never look at this field.
+ */
+ uint64_t vfs_private;
+};
+
+typedef struct stat_ex SMB_STRUCT_STAT;
/*
* Type for dirent structure.
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e0b0e59700..342c1432eb 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1010,13 +1010,6 @@ void srv_put_dos_date2(char *buf,int offset, time_t unixdate);
void srv_put_dos_date3(char *buf,int offset,time_t unixdate);
void put_long_date_timespec(char *p, struct timespec ts);
void put_long_date(char *p, time_t t);
-struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,bool fake_dirs);
-struct timespec get_atimespec(const SMB_STRUCT_STAT *pst);
-void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst);
-void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst);
-void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
void dos_filetime_timespec(struct timespec *tsp);
time_t make_unix_date2(const void *date_ptr, int zone_offset);
time_t make_unix_date3(const void *date_ptr, int zone_offset);
@@ -1113,7 +1106,7 @@ char *clean_name(TALLOC_CTX *ctx, const char *s);
ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos);
int set_blocking(int fd, bool set);
void smb_msleep(unsigned int t);
-bool reinit_after_fork(struct messaging_context *msg_ctx,
+NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived);
bool yesno(const char *p);
@@ -2339,12 +2332,37 @@ void cli_reset_error(struct cli_state *cli);
/* The following definitions come from libsmb/clifile.c */
+struct tevent_req *cli_posix_symlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *oldname,
+ const char *newname);
+NTSTATUS cli_posix_symlink_recv(struct tevent_req *req);
+NTSTATUS cli_posix_symlink(struct cli_state *cli,
+ const char *oldname,
+ const char *newname);
+struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ size_t len);
+NTSTATUS cli_posix_readlink_recv(struct tevent_req *req, struct cli_state *cli,
+ char *retpath, size_t len);
+NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname,
+ char *linkpath, size_t len);
+struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *oldname,
+ const char *newname);
+NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req);
+NTSTATUS cli_posix_hardlink(struct cli_state *cli,
+ const char *oldname,
+ const char *newname);
uint32_t unix_perms_to_wire(mode_t perms);
mode_t wire_perms_to_unix(uint32_t perms);
bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf);
bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf);
-bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname);
-bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname);
bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid);
struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
@@ -4087,7 +4105,7 @@ bool lp_recursive_veto_delete(int );
bool lp_dos_filemode(int );
bool lp_dos_filetimes(int );
bool lp_dos_filetime_resolution(int );
-bool lp_fake_dir_create_times(int );
+bool lp_fake_dir_create_times(void);
bool lp_blocking_locks(int );
bool lp_inherit_perms(int );
bool lp_inherit_acls(int );
@@ -6174,7 +6192,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
char **pp_fname_out,
SMB_OFF_T *size,
uint32 *mode,
- time_t *date,
+ struct timespec *date,
bool check_descend,
bool ask_sharemode);
bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto);
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 22cfaaf581..7528883c2d 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -88,9 +88,9 @@
* stat structure is valid.
*/
-#define VALID_STAT(st) ((st).st_nlink != 0)
-#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
-#define SET_STAT_INVALID(st) ((st).st_nlink = 0)
+#define VALID_STAT(st) ((st).st_ex_nlink != 0)
+#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_ex_mode))
+#define SET_STAT_INVALID(st) ((st).st_ex_nlink = 0)
/* Macros to get at offsets within smb_lkrng and smb_unlkrng
structures. We cannot define these as actual structures
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 14aca3adad..419af61ef3 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -739,7 +739,7 @@ void check_log_size( void )
maxlog = lp_max_log_size() * 1024;
- if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
+ if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_ex_size > maxlog ) {
(void)reopen_logs();
if( dbf && get_file_size( debugf ) > maxlog ) {
char *name = NULL;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 517e347c0f..d9d3266fbc 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -290,6 +290,201 @@ int sys_fcntl_long(int fd, int cmd, long arg)
return ret;
}
+/****************************************************************************
+ Return the best approximation to a 'create time' under UNIX from a stat
+ structure.
+****************************************************************************/
+
+static time_t calc_create_time(const struct stat *st)
+{
+ time_t ret, ret1;
+
+ ret = MIN(st->st_ctime, st->st_mtime);
+ ret1 = MIN(ret, st->st_atime);
+
+ if(ret1 != (time_t)0) {
+ return ret1;
+ }
+
+ /*
+ * One of ctime, mtime or atime was zero (probably atime).
+ * Just return MIN(ctime, mtime).
+ */
+ return ret;
+}
+
+/****************************************************************************
+ Return the 'create time' from a stat struct if it exists (birthtime) or else
+ use the best approximation.
+****************************************************************************/
+
+static struct timespec get_create_timespec(const struct stat *pst)
+{
+ struct timespec ret;
+
+ if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
+ ret.tv_sec = 315493200L; /* 1/1/1980 */
+ ret.tv_nsec = 0;
+ return ret;
+ }
+
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
+ ret = pst->st_birthtimespec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
+ ret.tv_sec = pst->st_birthtime;
+ ret.tv_nsec = pst->st_birthtimenspec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+ ret.tv_sec = pst->st_birthtime;
+ ret.tv_nsec = 0;
+#else
+ ret.tv_sec = calc_create_time(pst);
+ ret.tv_nsec = 0;
+#endif
+
+ /* Deal with systems that don't initialize birthtime correctly.
+ * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
+ */
+ if (null_timespec(ret)) {
+ ret.tv_sec = calc_create_time(pst);
+ ret.tv_nsec = 0;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ Get/Set all the possible time fields from a stat struct as a timespec.
+****************************************************************************/
+
+static struct timespec get_atimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+ struct timespec ret;
+
+ /* Old system - no ns timestamp. */
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = 0;
+ return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ return pst->st_atim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ struct timespec ret;
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = pst->st_atimensec;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = pst->st_atime_n;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = pst->st_uatime * 1000;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+ return pst->st_atimespec;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_mtimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+ struct timespec ret;
+
+ /* Old system - no ns timestamp. */
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = 0;
+ return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ return pst->st_mtim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ struct timespec ret;
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = pst->st_mtimensec;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = pst->st_mtime_n;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = pst->st_umtime * 1000;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+ return pst->st_mtimespec;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_ctimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+ struct timespec ret;
+
+ /* Old system - no ns timestamp. */
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = 0;
+ return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ return pst->st_ctim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ struct timespec ret;
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = pst->st_ctimensec;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = pst->st_ctime_n;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = pst->st_uctime * 1000;
+ return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+ return pst->st_ctimespec;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static void init_stat_ex_from_stat (struct stat_ex *dst,
+ const struct stat *src)
+{
+ dst->st_ex_dev = src->st_dev;
+ dst->st_ex_ino = src->st_ino;
+ dst->st_ex_mode = src->st_mode;
+ dst->st_ex_nlink = src->st_nlink;
+ dst->st_ex_uid = src->st_uid;
+ dst->st_ex_gid = src->st_gid;
+ dst->st_ex_rdev = src->st_rdev;
+ dst->st_ex_size = src->st_size;
+ dst->st_ex_atime = get_atimespec(src);
+ dst->st_ex_mtime = get_mtimespec(src);
+ dst->st_ex_ctime = get_ctimespec(src);
+ dst->st_ex_btime = get_create_timespec(src);
+ dst->st_ex_blksize = src->st_blksize;
+ dst->st_ex_blocks = src->st_blocks;
+
+#ifdef HAVE_STAT_ST_FLAGS
+ dst->st_ex_flags = src->st_flags;
+#else
+ dst->st_ex_flags = 0;
+#endif
+}
+
/*******************************************************************
A stat() wrapper that will deal with 64 bit filesizes.
********************************************************************/
@@ -300,10 +495,16 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
ret = stat64(fname, sbuf);
#else
- ret = stat(fname, sbuf);
+ struct stat statbuf;
+ ret = stat(fname, &statbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(statbuf.st_mode)) {
+ statbuf.st_size = 0;
+ }
+ init_stat_ex_from_stat(sbuf, &statbuf);
+ }
return ret;
}
@@ -317,10 +518,16 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
ret = fstat64(fd, sbuf);
#else
- ret = fstat(fd, sbuf);
+ struct stat statbuf;
+ ret = fstat(fd, &statbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(statbuf.st_mode)) {
+ statbuf.st_size = 0;
+ }
+ init_stat_ex_from_stat(sbuf, &statbuf);
+ }
return ret;
}
@@ -334,10 +541,16 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
ret = lstat64(fname, sbuf);
#else
- ret = lstat(fname, sbuf);
+ struct stat statbuf;
+ ret = lstat(fname, &statbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(statbuf.st_mode)) {
+ statbuf.st_size = 0;
+ }
+ init_stat_ex_from_stat(sbuf, &statbuf);
+ }
return ret;
}
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 611debe366..a2e615acc5 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -322,251 +322,6 @@ void put_long_date(char *p, time_t t)
put_long_date_timespec(p, ts);
}
-/****************************************************************************
- Return the best approximation to a 'create time' under UNIX from a stat
- structure.
-****************************************************************************/
-
-static time_t calc_create_time(const SMB_STRUCT_STAT *st)
-{
- time_t ret, ret1;
-
- ret = MIN(st->st_ctime, st->st_mtime);
- ret1 = MIN(ret, st->st_atime);
-
- if(ret1 != (time_t)0) {
- return ret1;
- }
-
- /*
- * One of ctime, mtime or atime was zero (probably atime).
- * Just return MIN(ctime, mtime).
- */
- return ret;
-}
-
-/****************************************************************************
- Return the 'create time' from a stat struct if it exists (birthtime) or else
- use the best approximation.
-****************************************************************************/
-
-struct timespec get_create_timespec(const SMB_STRUCT_STAT *pst,bool fake_dirs)
-{
- struct timespec ret;
-
- if(S_ISDIR(pst->st_mode) && fake_dirs) {
- ret.tv_sec = 315493200L; /* 1/1/1980 */
- ret.tv_nsec = 0;
- return ret;
- }
-
-#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
- ret = pst->st_birthtimespec;
-#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
- ret.tv_sec = pst->st_birthtime;
- ret.tv_nsec = pst->st_birthtimenspec;
-#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
- ret.tv_sec = pst->st_birthtime;
- ret.tv_nsec = 0;
-#else
- ret.tv_sec = calc_create_time(pst);
- ret.tv_nsec = 0;
-#endif
-
- /* Deal with systems that don't initialize birthtime correctly.
- * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
- */
- if (null_timespec(ret)) {
- ret.tv_sec = calc_create_time(pst);
- ret.tv_nsec = 0;
- }
- return ret;
-}
-
-/****************************************************************************
- Get/Set all the possible time fields from a stat struct as a timespec.
-****************************************************************************/
-
-struct timespec get_atimespec(const SMB_STRUCT_STAT *pst)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- struct timespec ret;
-
- /* Old system - no ns timestamp. */
- ret.tv_sec = pst->st_atime;
- ret.tv_nsec = 0;
- return ret;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- return pst->st_atim;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- struct timespec ret;
- ret.tv_sec = pst->st_atime;
- ret.tv_nsec = pst->st_atimensec;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- struct timespec ret;
- ret.tv_sec = pst->st_atime;
- ret.tv_nsec = pst->st_atime_n;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- struct timespec ret;
- ret.tv_sec = pst->st_atime;
- ret.tv_nsec = pst->st_uatime * 1000;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- return pst->st_atimespec;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
-void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- /* Old system - no ns timestamp. */
- pst->st_atime = ts.tv_sec;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- pst->st_atim = ts;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- pst->st_atime = ts.tv_sec;
- pst->st_atimensec = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- pst->st_atime = ts.tv_sec;
- pst->st_atime_n = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- pst->st_atime = ts.tv_sec;
- pst->st_uatime = ts.tv_nsec / 1000;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- pst->st_atimespec = ts;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
-struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- struct timespec ret;
-
- /* Old system - no ns timestamp. */
- ret.tv_sec = pst->st_mtime;
- ret.tv_nsec = 0;
- return ret;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- return pst->st_mtim;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- struct timespec ret;
- ret.tv_sec = pst->st_mtime;
- ret.tv_nsec = pst->st_mtimensec;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- struct timespec ret;
- ret.tv_sec = pst->st_mtime;
- ret.tv_nsec = pst->st_mtime_n;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- struct timespec ret;
- ret.tv_sec = pst->st_mtime;
- ret.tv_nsec = pst->st_umtime * 1000;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- return pst->st_mtimespec;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
-void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- /* Old system - no ns timestamp. */
- pst->st_mtime = ts.tv_sec;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- pst->st_mtim = ts;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- pst->st_mtime = ts.tv_sec;
- pst->st_mtimensec = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- pst->st_mtime = ts.tv_sec;
- pst->st_mtime_n = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- pst->st_mtime = ts.tv_sec;
- pst->st_umtime = ts.tv_nsec / 1000;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- pst->st_mtimespec = ts;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
-struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- struct timespec ret;
-
- /* Old system - no ns timestamp. */
- ret.tv_sec = pst->st_ctime;
- ret.tv_nsec = 0;
- return ret;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- return pst->st_ctim;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- struct timespec ret;
- ret.tv_sec = pst->st_ctime;
- ret.tv_nsec = pst->st_ctimensec;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- struct timespec ret;
- ret.tv_sec = pst->st_ctime;
- ret.tv_nsec = pst->st_ctime_n;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- struct timespec ret;
- ret.tv_sec = pst->st_ctime;
- ret.tv_nsec = pst->st_uctime * 1000;
- return ret;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- return pst->st_ctimespec;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
-void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
-{
-#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
- /* Old system - no ns timestamp. */
- pst->st_ctime = ts.tv_sec;
-#else
-#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
- pst->st_ctim = ts;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
- pst->st_ctime = ts.tv_sec;
- pst->st_ctimensec = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
- pst->st_ctime = ts.tv_sec;
- pst->st_ctime_n = ts.tv_nsec;
-#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
- pst->st_ctime = ts.tv_sec;
- pst->st_uctime = ts.tv_nsec / 1000;
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
- pst->st_ctimespec = ts;
-#else
-#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
-#endif
-#endif
-}
-
void dos_filetime_timespec(struct timespec *tsp)
{
tsp->tv_sec &= ~1;
diff --git a/source3/lib/util.c b/source3/lib/util.c
index c86f259ce3..8e67edeae6 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -541,7 +541,7 @@ bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
if (sys_stat(fname,sbuf) != 0)
return(False);
- return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
+ return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
}
/*******************************************************************
@@ -554,7 +554,7 @@ bool socket_exist(const char *fname)
if (sys_stat(fname,&st) != 0)
return(False);
- return S_ISSOCK(st.st_mode);
+ return S_ISSOCK(st.st_ex_mode);
}
/*******************************************************************
@@ -572,7 +572,7 @@ bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st)
if (sys_stat(dname,st) != 0)
return(False);
- ret = S_ISDIR(st->st_mode);
+ ret = S_ISDIR(st->st_ex_mode);
if(!ret)
errno = ENOTDIR;
return ret;
@@ -584,7 +584,7 @@ bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st)
uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
{
- return sbuf->st_size;
+ return sbuf->st_ex_size;
}
/*******************************************************************
@@ -594,7 +594,7 @@ uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
SMB_OFF_T get_file_size(char *file_name)
{
SMB_STRUCT_STAT buf;
- buf.st_size = 0;
+ buf.st_ex_size = 0;
if(sys_stat(file_name,&buf) != 0)
return (SMB_OFF_T)-1;
return get_file_size_stat(&buf);
@@ -927,11 +927,11 @@ void smb_msleep(unsigned int t)
#endif
}
-bool reinit_after_fork(struct messaging_context *msg_ctx,
+NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived)
{
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
/* Reset the state of the random
* number generation system, so
@@ -942,7 +942,8 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
/* tdb needs special fork handling */
if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
- return false;
+ status = NT_STATUS_OPEN_FAILED;
+ goto done;
}
if (ev_ctx) {
@@ -958,11 +959,10 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("messaging_reinit() failed: %s\n",
nt_errstr(status)));
- return false;
}
}
-
- return true;
+ done:
+ return status;
}
/****************************************************************************
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 2c80f1dd1a..187fcdf625 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -20,74 +20,510 @@
#include "includes.h"
+/***********************************************************
+ Common function for pushing stings, used by smb_bytes_push_str()
+ and trans_bytes_push_str(). Only difference is the align_odd
+ parameter setting.
+***********************************************************/
+
+static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2,
+ const char *str, size_t str_len,
+ bool align_odd,
+ size_t *pconverted_size)
+{
+ size_t buflen;
+ char *converted;
+ size_t converted_size;
+
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ buflen = talloc_get_size(buf);
+
+ if (align_odd && ucs2 && (buflen % 2 == 0)) {
+ /*
+ * We're pushing into an SMB buffer, align odd
+ */
+ buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1);
+ if (buf == NULL) {
+ return NULL;
+ }
+ buf[buflen] = '\0';
+ buflen += 1;
+ }
+
+ if (!convert_string_talloc(talloc_tos(), CH_UNIX,
+ ucs2 ? CH_UTF16LE : CH_DOS,
+ str, str_len, &converted,
+ &converted_size, true)) {
+ return NULL;
+ }
+
+ buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t,
+ buflen + converted_size);
+ if (buf == NULL) {
+ TALLOC_FREE(converted);
+ return NULL;
+ }
+
+ memcpy(buf + buflen, converted, converted_size);
+
+ TALLOC_FREE(converted);
+
+ if (pconverted_size) {
+ *pconverted_size = converted_size;
+ }
+
+ return buf;
+}
+
+/***********************************************************
+ Push a string into an SMB buffer, with odd byte alignment
+ if it's a UCS2 string.
+***********************************************************/
+
+uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
+ const char *str, size_t str_len,
+ size_t *pconverted_size)
+{
+ return internal_bytes_push_str(buf, ucs2, str, str_len,
+ true, pconverted_size);
+}
+
+/***********************************************************
+ Same as smb_bytes_push_str(), but without the odd byte
+ align for ucs2 (we're pushing into a param or data block).
+ static for now, although this will probably change when
+ other modules use async trans calls.
+***********************************************************/
+
+static uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2,
+ const char *str, size_t str_len,
+ size_t *pconverted_size)
+{
+ return internal_bytes_push_str(buf, ucs2, str, str_len,
+ false, pconverted_size);
+}
+
/****************************************************************************
Hard/Symlink a file (UNIX extensions).
Creates new name (sym)linked to oldname.
****************************************************************************/
-static bool cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, bool hard_link)
+struct link_state {
+ uint16_t setup;
+ uint8_t *param;
+ uint8_t *data;
+};
+
+static void cli_posix_link_internal_done(struct tevent_req *subreq)
{
- unsigned int data_len = 0;
- unsigned int param_len = 0;
- uint16_t setup = TRANSACT2_SETPATHINFO;
- char *param;
- char *data;
- char *rparam=NULL, *rdata=NULL;
- char *p;
- size_t oldlen = 2*(strlen(oldname)+1);
- size_t newlen = 2*(strlen(newname)+1);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct link_state *state = tevent_req_data(req, struct link_state);
+ NTSTATUS status;
- param = SMB_MALLOC_ARRAY(char, 6+newlen+2);
+ 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);
+}
- if (!param) {
- return false;
+static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *oldname,
+ const char *newname,
+ bool hardlink)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct link_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct link_state);
+ if (req == NULL) {
+ return NULL;
}
- data = SMB_MALLOC_ARRAY(char, oldlen+2);
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
- if (!data) {
- SAFE_FREE(param);
- return false;
+ /* Setup param array. */
+ state->param = talloc_array(state, uint8_t, 6);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
+ memset(state->param, '\0', 6);
+ SSVAL(state->param,0,hardlink ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
- SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
- SIVAL(param,2,0);
- p = &param[6];
+ state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), newname,
+ strlen(newname)+1, NULL);
- p += clistr_push(cli, p, newname, newlen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
+ }
- p = data;
- p += clistr_push(cli, p, oldname, oldlen, STR_TERMINATE);
- data_len = PTR_DIFF(p, data);
+ /* Setup data array. */
+ state->data = talloc_array(state, uint8_t, 0);
+ if (tevent_req_nomem(state->data, req)) {
+ return tevent_req_post(req, ev);
+ }
+ state->data = trans2_bytes_push_str(state->data, cli_ucs2(cli), oldname,
+ strlen(oldname)+1, NULL);
- 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 */
- data, data_len, cli->max_xmit /* data, length, max */
- )) {
- SAFE_FREE(data);
- SAFE_FREE(param);
- return false;
+ 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. */
+ talloc_get_size(state->param), /* num param. */
+ 2, /* max returned param. */
+ state->data, /* data. */
+ talloc_get_size(state->data), /* num data. */
+ 0); /* max returned data. */
+
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq, cli_posix_link_internal_done, req);
+ return req;
+}
- SAFE_FREE(data);
- SAFE_FREE(param);
+/****************************************************************************
+ Symlink a file (UNIX extensions).
+****************************************************************************/
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return false;
+struct tevent_req *cli_posix_symlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *oldname,
+ const char *newname)
+{
+ return cli_posix_link_internal_send(mem_ctx, ev, cli,
+ oldname, newname, false);
+}
+
+NTSTATUS cli_posix_symlink_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
}
+ return NT_STATUS_OK;
+}
- SAFE_FREE(data);
- SAFE_FREE(param);
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
+NTSTATUS cli_posix_symlink(struct cli_state *cli,
+ const char *oldname,
+ const char *newname)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
- 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_posix_symlink_send(frame,
+ ev,
+ cli,
+ oldname,
+ newname);
+ 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_symlink_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
+}
+
+/****************************************************************************
+ Read a POSIX symlink.
+****************************************************************************/
+
+struct readlink_state {
+ uint16_t setup;
+ uint8_t *param;
+ uint8_t *data;
+ uint32_t num_data;
+};
+
+static void cli_posix_readlink_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct readlink_state *state = tevent_req_data(req, struct readlink_state);
+ NTSTATUS status;
+
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+ &state->data, &state->num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ if (state->num_data == 0) {
+ tevent_req_nterror(req, NT_STATUS_DATA_ERROR);
+ return;
+ }
+ if (state->data[state->num_data-1] != '\0') {
+ tevent_req_nterror(req, NT_STATUS_DATA_ERROR);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ size_t len)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct readlink_state *state = NULL;
+ uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len);
+
+ if (maxbytelen < len) {
+ return NULL;
+ }
+
+ req = tevent_req_create(mem_ctx, &state, struct readlink_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
+
+ /* Setup param array. */
+ state->param = talloc_array(state, uint8_t, 6);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
+ }
+ memset(state->param, '\0', 6);
+ SSVAL(state->param,0,SMB_QUERY_FILE_UNIX_LINK);
+
+ state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+ strlen(fname)+1, NULL);
+
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ 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. */
+ talloc_get_size(state->param), /* num param. */
+ 2, /* max returned param. */
+ NULL, /* data. */
+ 0, /* num data. */
+ maxbytelen); /* max returned data. */
+
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_posix_readlink_done, req);
+ return req;
+}
+
+NTSTATUS cli_posix_readlink_recv(struct tevent_req *req, struct cli_state *cli,
+ char *retpath, size_t len)
+{
+ NTSTATUS status;
+ char *converted = NULL;
+ size_t converted_size = 0;
+ struct readlink_state *state = tevent_req_data(req, struct readlink_state);
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ /* The returned data is a pushed string, not raw data. */
+ if (!convert_string_talloc(state,
+ cli_ucs2(cli) ? CH_UTF16LE : CH_DOS,
+ CH_UNIX,
+ state->data,
+ state->num_data,
+ &converted,
+ &converted_size,
+ true)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ len = MIN(len,converted_size);
+ if (len == 0) {
+ return NT_STATUS_DATA_ERROR;
+ }
+ memcpy(retpath, converted, len);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname,
+ char *linkpath, size_t len)
+{
+ 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;
+ }
+
+ /* Len is in bytes, we need it in UCS2 units. */
+ if (2*len < len) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ req = cli_posix_readlink_send(frame,
+ ev,
+ cli,
+ fname,
+ 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_readlink_recv(req, cli, linkpath, len);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
+}
+
+
+/****************************************************************************
+ Hard link a file (UNIX extensions).
+****************************************************************************/
+
+struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *oldname,
+ const char *newname)
+{
+ return cli_posix_link_internal_send(mem_ctx, ev, cli,
+ oldname, newname, true);
+}
+
+NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_hardlink(struct cli_state *cli,
+ const char *oldname,
+ const char *newname)
+{
+ 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_hardlink_send(frame,
+ ev,
+ cli,
+ oldname,
+ newname);
+ 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_hardlink_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -294,56 +730,37 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu
return false;
}
- sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */
- sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */
+ sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */
+ sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */
#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- sbuf->st_blocks /= STAT_ST_BLOCKSIZE;
+ sbuf->st_ex_blocks /= STAT_ST_BLOCKSIZE;
#else
/* assume 512 byte blocks */
- sbuf->st_blocks /= 512;
+ sbuf->st_ex_blocks /= 512;
#endif
- set_ctimespec(sbuf, interpret_long_date(rdata + 16)); /* time of last change */
- set_atimespec(sbuf, interpret_long_date(rdata + 24)); /* time of last access */
- set_mtimespec(sbuf, interpret_long_date(rdata + 32)); /* time of last modification */
+ sbuf->st_ex_ctime = interpret_long_date(rdata + 16); /* time of last change */
+ sbuf->st_ex_atime = interpret_long_date(rdata + 24); /* time of last access */
+ sbuf->st_ex_mtime = interpret_long_date(rdata + 32); /* time of last modification */
- sbuf->st_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */
- sbuf->st_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */
- sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
+ sbuf->st_ex_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */
+ sbuf->st_ex_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */
+ sbuf->st_ex_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
#if defined(HAVE_MAKEDEV)
{
uint32_t dev_major = IVAL(rdata,60);
uint32_t dev_minor = IVAL(rdata,68);
- sbuf->st_rdev = makedev(dev_major, dev_minor);
+ sbuf->st_ex_rdev = makedev(dev_major, dev_minor);
}
#endif
- sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */
- sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */
- sbuf->st_nlink = IVAL(rdata,92); /* number of hard links */
+ sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */
+ sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */
+ sbuf->st_ex_nlink = IVAL(rdata,92); /* number of hard links */
SAFE_FREE(rdata);
SAFE_FREE(rparam);
return true;
}
-
-/****************************************************************************
- Symlink a file (UNIX extensions).
-****************************************************************************/
-
-bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname)
-{
- return cli_link_internal(cli, oldname, newname, False);
-}
-
-/****************************************************************************
- Hard a file (UNIX extensions).
-****************************************************************************/
-
-bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname)
-{
- return cli_link_internal(cli, oldname, newname, True);
-}
-
/****************************************************************************
Chmod or chown a file internal (UNIX extensions).
****************************************************************************/
@@ -1288,92 +1705,6 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
return status;
}
-/***********************************************************
- Common function for pushing stings, used by smb_bytes_push_str()
- and trans_bytes_push_str(). Only difference is the align_odd
- parameter setting.
-***********************************************************/
-
-static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2,
- const char *str, size_t str_len,
- bool align_odd,
- size_t *pconverted_size)
-{
- size_t buflen;
- char *converted;
- size_t converted_size;
-
- if (buf == NULL) {
- return NULL;
- }
-
- buflen = talloc_get_size(buf);
-
- if (align_odd && ucs2 && (buflen % 2 == 0)) {
- /*
- * We're pushing into an SMB buffer, align odd
- */
- buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1);
- if (buf == NULL) {
- return NULL;
- }
- buf[buflen] = '\0';
- buflen += 1;
- }
-
- if (!convert_string_talloc(talloc_tos(), CH_UNIX,
- ucs2 ? CH_UTF16LE : CH_DOS,
- str, str_len, &converted,
- &converted_size, true)) {
- return NULL;
- }
-
- buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t,
- buflen + converted_size);
- if (buf == NULL) {
- TALLOC_FREE(converted);
- return NULL;
- }
-
- memcpy(buf + buflen, converted, converted_size);
-
- TALLOC_FREE(converted);
-
- if (pconverted_size) {
- *pconverted_size = converted_size;
- }
-
- return buf;
-}
-
-/***********************************************************
- Push a string into an SMB buffer, with odd byte alignment
- if it's a UCS2 string.
-***********************************************************/
-
-uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
- const char *str, size_t str_len,
- size_t *pconverted_size)
-{
- return internal_bytes_push_str(buf, ucs2, str, str_len,
- true, pconverted_size);
-}
-
-/***********************************************************
- Same as smb_bytes_push_str(), but without the odd byte
- align for ucs2 (we're pushing into a param or data block).
- static for now, although this will probably change when
- other modules use async trans calls.
-***********************************************************/
-
-static uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2,
- const char *str, size_t str_len,
- size_t *pconverted_size)
-{
- return internal_bytes_push_str(buf, ucs2, str, str_len,
- false, pconverted_size);
-}
-
/****************************************************************************
Open a file
WARNING: if you open with O_WRONLY then getattrE won't work!
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index 1771e8fd25..c3ec82bd3e 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -1105,9 +1105,9 @@ bool cli_qpathinfo_basic( struct cli_state *cli, const char *name,
return False;
}
- set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */
- set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */
- set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */
+ sbuf->st_ex_atime = interpret_long_date( rdata+8 ); /* Access time. */
+ sbuf->st_ex_mtime = interpret_long_date( rdata+16 ); /* Write time. */
+ sbuf->st_ex_ctime = interpret_long_date( rdata+24 ); /* Change time. */
*attributes = IVAL( rdata, 32 );
diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c
index af7800ba32..4349b0a700 100644
--- a/source3/libsmb/libsmb_stat.c
+++ b/source3/libsmb/libsmb_stat.c
@@ -188,9 +188,9 @@ SMBC_stat_ctx(SMBCCTX *context,
setup_stat(context, st, (char *) fname, size, mode);
- set_atimespec(st, access_time_ts);
- set_ctimespec(st, change_time_ts);
- set_mtimespec(st, write_time_ts);
+ st->st_atime = convert_timespec_to_time_t(access_time_ts);
+ st->st_ctime = convert_timespec_to_time_t(change_time_ts);
+ st->st_mtime = convert_timespec_to_time_t(write_time_ts);
st->st_dev = srv->dev;
TALLOC_FREE(frame);
@@ -293,9 +293,9 @@ SMBC_fstat_ctx(SMBCCTX *context,
setup_stat(context, st, file->fname, size, mode);
- set_atimespec(st, access_time_ts);
- set_ctimespec(st, change_time_ts);
- set_mtimespec(st, write_time_ts);
+ st->st_atime = convert_timespec_to_time_t(access_time_ts);
+ st->st_ctime = convert_timespec_to_time_t(change_time_ts);
+ st->st_mtime = convert_timespec_to_time_t(write_time_ts);
st->st_dev = file->srv->dev;
TALLOC_FREE(frame);
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 462e59313a..10a3733c14 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -289,10 +289,11 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
* shouldn't alloc 0 for
* win */
- uid_to_sid(&sid_owner, sbuf->st_uid);
- gid_to_sid(&sid_group, sbuf->st_gid);
+ uid_to_sid(&sid_owner, sbuf->st_ex_uid);
+ gid_to_sid(&sid_group, sbuf->st_ex_gid);
- if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode),
+ if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group,
+ S_ISDIR(sbuf->st_ex_mode),
&nt_ace_list, &good_aces)==False) {
DEBUG(8,("smbacl4_nfs42win failed\n"));
return map_nt_error_from_unix(errno);
@@ -315,7 +316,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
}
DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with sd_size %d\n",
- ndr_size_security_descriptor(*ppdesc, NULL, 0)));
+ (int)ndr_size_security_descriptor(*ppdesc, NULL, 0)));
return NT_STATUS_OK;
}
@@ -733,8 +734,8 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
DEBUG(8, ("unpack_nt_owners failed"));
return status;
}
- if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
- ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
+ if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
+ ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
@@ -759,7 +760,8 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
return NT_STATUS_OK;
}
- theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
+ theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params,
+ sbuf.st_ex_uid, sbuf.st_ex_gid);
if (!theacl)
return map_nt_error_from_unix(errno);
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index a77f6d60f4..463250a9ed 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -414,8 +414,8 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
struct security_ace *pace = NULL;
struct security_acl *pacl = NULL;
- uid_to_sid(&owner_sid, psbuf->st_uid);
- gid_to_sid(&group_sid, psbuf->st_gid);
+ uid_to_sid(&owner_sid, psbuf->st_ex_uid);
+ gid_to_sid(&group_sid, psbuf->st_ex_gid);
pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
if (!pace) {
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 49e4899879..05156f8456 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -282,8 +282,8 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
struct security_ace *pace = NULL;
struct security_acl *pacl = NULL;
- uid_to_sid(&owner_sid, psbuf->st_uid);
- gid_to_sid(&group_sid, psbuf->st_gid);
+ uid_to_sid(&owner_sid, psbuf->st_ex_uid);
+ gid_to_sid(&group_sid, psbuf->st_ex_gid);
pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
if (!pace) {
diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
index 8c89d2fd9f..e537f01b03 100644
--- a/source3/modules/vfs_afsacl.c
+++ b/source3/modules/vfs_afsacl.c
@@ -599,8 +599,8 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
struct afs_ace *afs_ace;
- uid_to_sid(&owner_sid, psbuf->st_uid);
- gid_to_sid(&group_sid, psbuf->st_gid);
+ uid_to_sid(&owner_sid, psbuf->st_ex_uid);
+ gid_to_sid(&group_sid, psbuf->st_ex_gid);
if (afs_acl->num_aces) {
nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces);
@@ -626,7 +626,7 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
continue;
}
- if (S_ISDIR(psbuf->st_mode))
+ if (S_ISDIR(psbuf->st_ex_mode))
afs_to_nt_dir_rights(afs_ace->rights, &nt_rights,
&flag);
else
diff --git a/source3/modules/vfs_commit.c b/source3/modules/vfs_commit.c
index a8105e021e..c22e8161d7 100644
--- a/source3/modules/vfs_commit.c
+++ b/source3/modules/vfs_commit.c
@@ -220,7 +220,7 @@ static int commit_open(
if (SMB_VFS_FSTAT(fsp, &st) == -1) {
return -1;
}
- c->eof = st.st_size;
+ c->eof = st.st_ex_size;
}
return 0;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index aa207056b3..fe63d5001a 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -430,7 +430,7 @@ static int copy_reg(const char *source, const char *dest)
if (sys_lstat (source, &source_stats) == -1)
return -1;
- if (!S_ISREG (source_stats.st_mode))
+ if (!S_ISREG (source_stats.st_ex_mode))
return -1;
if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
@@ -455,9 +455,9 @@ static int copy_reg(const char *source, const char *dest)
*/
#ifdef HAVE_FCHOWN
- if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+ if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
#else
- if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+ if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
#endif
goto err;
@@ -467,9 +467,9 @@ static int copy_reg(const char *source, const char *dest)
*/
#if defined(HAVE_FCHMOD)
- if (fchmod (ofd, source_stats.st_mode & 07777))
+ if (fchmod (ofd, source_stats.st_ex_mode & 07777))
#else
- if (chmod (dest, source_stats.st_mode & 07777))
+ if (chmod (dest, source_stats.st_ex_mode & 07777))
#endif
goto err;
@@ -483,8 +483,8 @@ static int copy_reg(const char *source, const char *dest)
{
struct utimbuf tv;
- tv.actime = source_stats.st_atime;
- tv.modtime = source_stats.st_mtime;
+ tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
+ tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
utime(dest, &tv);
}
@@ -575,13 +575,13 @@ static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
START_PROFILE(syscall_get_alloc_size);
- if(S_ISDIR(sbuf->st_mode)) {
+ if(S_ISDIR(sbuf->st_ex_mode)) {
result = 0;
goto out;
}
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
+ result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
#else
result = get_file_size_stat(sbuf);
#endif
@@ -777,18 +777,18 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
if (SMB_VFS_FSTAT(fsp, &st) == -1)
return -1;
- space_to_write = len - st.st_size;
+ space_to_write = len - st.st_ex_size;
#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode))
+ if (S_ISFIFO(st.st_ex_mode))
return 0;
#endif
- if (st.st_size == len)
+ if (st.st_ex_size == len)
return 0;
/* Shrink - just ftruncate. */
- if (st.st_size > len)
+ if (st.st_ex_size > len)
return sys_ftruncate(fsp->fh->fd, len);
/* available disk space is enough or not? */
@@ -806,10 +806,10 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
}
/* Write out the real space on disk. */
- if (SMB_VFS_LSEEK(fsp, st.st_size, SEEK_SET) != st.st_size)
+ if (SMB_VFS_LSEEK(fsp, st.st_ex_size, SEEK_SET) != st.st_ex_size)
return -1;
- space_to_write = len - st.st_size;
+ space_to_write = len - st.st_ex_size;
memset(zero_space, '\0', sizeof(zero_space));
while ( space_to_write > 0) {
@@ -872,18 +872,18 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O
}
#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode)) {
+ if (S_ISFIFO(st.st_ex_mode)) {
result = 0;
goto done;
}
#endif
- if (st.st_size == len) {
+ if (st.st_ex_size == len) {
result = 0;
goto done;
}
- if (st.st_size > len) {
+ if (st.st_ex_size > len) {
/* the sys_ftruncate should have worked */
goto done;
}
@@ -1051,8 +1051,8 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
* blob */
ZERO_STRUCT(key);
- key.devid = sbuf->st_dev;
- key.inode = sbuf->st_ino;
+ key.devid = sbuf->st_ex_dev;
+ key.inode = sbuf->st_ex_ino;
/* key.extid is unused by default. */
return key;
@@ -1088,7 +1088,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
return map_nt_error_from_unix(errno);
}
- if (S_ISDIR(sbuf.st_mode)) {
+ if (S_ISDIR(sbuf.st_ex_mode)) {
goto done;
}
@@ -1098,7 +1098,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
return NT_STATUS_NO_MEMORY;
}
- streams->size = sbuf.st_size;
+ streams->size = sbuf.st_ex_size;
streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
streams->name = talloc_strdup(streams, "::$DATA");
diff --git a/source3/modules/vfs_fake_perms.c b/source3/modules/vfs_fake_perms.c
index 2989322147..cc3ab6220d 100644
--- a/source3/modules/vfs_fake_perms.c
+++ b/source3/modules/vfs_fake_perms.c
@@ -32,13 +32,13 @@ static int fake_perms_stat(vfs_handle_struct *handle, const char *fname, SMB_STR
ret = SMB_VFS_NEXT_STAT(handle, fname, sbuf);
if (ret == 0) {
- if (S_ISDIR(sbuf->st_mode)) {
- sbuf->st_mode = S_IFDIR | S_IRWXU;
+ if (S_ISDIR(sbuf->st_ex_mode)) {
+ sbuf->st_ex_mode = S_IFDIR | S_IRWXU;
} else {
- sbuf->st_mode = S_IRWXU;
+ sbuf->st_ex_mode = S_IRWXU;
}
- sbuf->st_uid = handle->conn->server_info->utok.uid;
- sbuf->st_gid = handle->conn->server_info->utok.gid;
+ sbuf->st_ex_uid = handle->conn->server_info->utok.uid;
+ sbuf->st_ex_gid = handle->conn->server_info->utok.gid;
}
return ret;
@@ -50,13 +50,13 @@ static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_ST
ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
if (ret == 0) {
- if (S_ISDIR(sbuf->st_mode)) {
- sbuf->st_mode = S_IFDIR | S_IRWXU;
+ if (S_ISDIR(sbuf->st_ex_mode)) {
+ sbuf->st_ex_mode = S_IFDIR | S_IRWXU;
} else {
- sbuf->st_mode = S_IRWXU;
+ sbuf->st_ex_mode = S_IRWXU;
}
- sbuf->st_uid = handle->conn->server_info->utok.uid;
- sbuf->st_gid = handle->conn->server_info->utok.gid;
+ sbuf->st_ex_uid = handle->conn->server_info->utok.uid;
+ sbuf->st_ex_gid = handle->conn->server_info->utok.gid;
}
return ret;
}
diff --git a/source3/modules/vfs_fileid.c b/source3/modules/vfs_fileid.c
index 8152c5477e..93b71a4dc0 100644
--- a/source3/modules/vfs_fileid.c
+++ b/source3/modules/vfs_fileid.c
@@ -237,8 +237,8 @@ static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle,
struct fileid_handle_data,
return id);
- id.devid = data->device_mapping_fn(data, sbuf->st_dev);
- id.inode = sbuf->st_ino;
+ id.devid = data->device_mapping_fn(data, sbuf->st_ex_dev);
+ id.inode = sbuf->st_ex_ino;
return id;
}
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 7ef969d04b..2e4e7ede55 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -846,7 +846,7 @@ static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mo
}
/* avoid chmod() if possible, to preserve acls */
- if ((st.st_mode & ~S_IFMT) == mode) {
+ if ((st.st_ex_mode & ~S_IFMT) == mode) {
return 0;
}
@@ -866,7 +866,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t
}
/* avoid chmod() if possible, to preserve acls */
- if ((st.st_mode & ~S_IFMT) == mode) {
+ if ((st.st_ex_mode & ~S_IFMT) == mode) {
return 0;
}
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index f9293405fb..7d20a73d7b 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -252,7 +252,7 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
goto done;
}
- if (S_ISDIR(s.st_mode)) {
+ if (S_ISDIR(s.st_ex_mode)) {
HPUX_ACL_T other_acl;
int other_count;
SMB_ACL_TYPE_T other_type;
diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c
index e2fa0fb88a..ed35922359 100644
--- a/source3/modules/vfs_netatalk.c
+++ b/source3/modules/vfs_netatalk.c
@@ -82,7 +82,7 @@ static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, const char *fnam
sys_lstat(*orig_path, orig_info);
- if (S_ISDIR(orig_info->st_mode)) {
+ if (S_ISDIR(orig_info->st_ex_mode)) {
*adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
path, &fname[ptr0], APPLEDOUBLE);
} else {
@@ -242,7 +242,7 @@ static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, c
&adbl_info, &orig_info) != 0)
goto exit_rename;
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
+ if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
goto exit_rename;
}
@@ -298,7 +298,7 @@ static int atalk_unlink(struct vfs_handle_struct *handle, const char *path)
&adbl_info, &orig_info) != 0)
goto exit_unlink;
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
+ if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
goto exit_unlink;
}
@@ -330,7 +330,7 @@ static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_
&adbl_info, &orig_info) != 0)
goto exit_chmod;
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
+ if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_chmod;
}
@@ -362,7 +362,7 @@ static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t
&adbl_info, &orig_info) != 0)
goto exit_chown;
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
+ if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_chown;
}
@@ -396,7 +396,7 @@ static int atalk_lchown(struct vfs_handle_struct *handle, const char *path, uid_
&adbl_info, &orig_info) != 0)
goto exit_lchown;
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
+ if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_lchown;
}
diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
index 2b0edcdb4a..f1791aa6b1 100644
--- a/source3/modules/vfs_recycle.c
+++ b/source3/modules/vfs_recycle.c
@@ -215,7 +215,7 @@ static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname
SMB_STRUCT_STAT st;
if (SMB_VFS_NEXT_STAT(handle, dname, &st) == 0) {
- if (S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st.st_ex_mode)) {
return True;
}
}
@@ -228,7 +228,7 @@ static bool recycle_file_exist(vfs_handle_struct *handle, const char *fname)
SMB_STRUCT_STAT st;
if (SMB_VFS_NEXT_STAT(handle, fname, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
+ if (S_ISREG(st.st_ex_mode)) {
return True;
}
}
@@ -251,7 +251,7 @@ static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fn
return (SMB_OFF_T)0;
}
- return(st.st_size);
+ return(st.st_ex_size);
}
/**
@@ -402,7 +402,7 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname,
return;
}
ft.atime = timespec_current(); /* atime */
- ft.mtime = touch_mtime ? ft.atime : get_mtimespec(&st); /* mtime */
+ ft.mtime = touch_mtime ? ft.atime : st.st_ex_mtime; /* mtime */
become_root();
ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft);
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 9543af32b9..acfac57b51 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -314,7 +314,7 @@ static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUC
if (shash == 0) {
shash = 1;
}
- sbuf->st_ino ^= shash;
+ sbuf->st_ex_ino ^= shash;
}
}
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index e5a70b1a49..72affe402a 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -182,7 +182,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
if (SMB_VFS_NEXT_STAT(handle, result, &sbuf) == 0) {
char *newname;
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
errno = EINVAL;
goto fail;
}
@@ -504,7 +504,7 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname)
return -1;
}
- if (sbuf.st_nlink == 1) {
+ if (sbuf.st_ex_nlink == 1) {
char *dirname = stream_dir(handle, fname, &sbuf, false);
if (dirname != NULL) {
@@ -652,7 +652,7 @@ static bool collect_one_stream(const char *dirname,
if (!add_one_stream(state->mem_ctx,
&state->num_streams, &state->streams,
- dirent, sbuf.st_size,
+ dirent, sbuf.st_ex_size,
SMB_VFS_GET_ALLOC_SIZE(state->handle->conn, NULL,
&sbuf))) {
state->status = NT_STATUS_NO_MEMORY;
@@ -698,10 +698,10 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
state.streams = NULL;
state.num_streams = 0;
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
- "::$DATA", sbuf.st_size,
+ "::$DATA", sbuf.st_ex_size,
SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
&sbuf))) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 3d5478d7a2..ebc51e79e3 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -42,17 +42,17 @@ static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname)
char *upper_sname;
DEBUG(10, ("stream_inode called for %lu/%lu [%s]\n",
- (unsigned long)sbuf->st_dev,
- (unsigned long)sbuf->st_ino, sname));
+ (unsigned long)sbuf->st_ex_dev,
+ (unsigned long)sbuf->st_ex_ino, sname));
upper_sname = talloc_strdup_upper(talloc_tos(), sname);
SMB_ASSERT(upper_sname != NULL);
MD5Init(&ctx);
- MD5Update(&ctx, (unsigned char *)&(sbuf->st_dev),
- sizeof(sbuf->st_dev));
- MD5Update(&ctx, (unsigned char *)&(sbuf->st_ino),
- sizeof(sbuf->st_ino));
+ MD5Update(&ctx, (unsigned char *)&(sbuf->st_ex_dev),
+ sizeof(sbuf->st_ex_dev));
+ MD5Update(&ctx, (unsigned char *)&(sbuf->st_ex_ino),
+ sizeof(sbuf->st_ex_ino));
MD5Update(&ctx, (unsigned char *)upper_sname,
talloc_get_size(upper_sname)-1);
MD5Final(hash, &ctx);
@@ -159,18 +159,18 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
return -1;
}
- sbuf->st_size = get_xattr_size(handle->conn, fsp->base_fsp,
+ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp,
io->base, io->xattr_name);
- if (sbuf->st_size == -1) {
+ if (sbuf->st_ex_size == -1) {
return -1;
}
- DEBUG(10, ("sbuf->st_size = %d\n", (int)sbuf->st_size));
+ DEBUG(10, ("sbuf->st_ex_size = %d\n", (int)sbuf->st_ex_size));
- sbuf->st_ino = stream_inode(sbuf, io->xattr_name);
- sbuf->st_mode &= ~S_IFMT;
- sbuf->st_mode |= S_IFREG;
- sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1;
+ sbuf->st_ex_ino = stream_inode(sbuf, io->xattr_name);
+ sbuf->st_ex_mode &= ~S_IFMT;
+ sbuf->st_ex_mode |= S_IFREG;
+ sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1;
return 0;
}
@@ -208,16 +208,16 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
- if (sbuf->st_size == -1) {
+ sbuf->st_ex_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
+ if (sbuf->st_ex_size == -1) {
errno = ENOENT;
goto fail;
}
- sbuf->st_ino = stream_inode(sbuf, xattr_name);
- sbuf->st_mode &= ~S_IFMT;
- sbuf->st_mode |= S_IFREG;
- sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1;
+ sbuf->st_ex_ino = stream_inode(sbuf, xattr_name);
+ sbuf->st_ex_mode &= ~S_IFMT;
+ sbuf->st_ex_mode |= S_IFREG;
+ sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1;
result = 0;
fail:
@@ -259,16 +259,16 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
- if (sbuf->st_size == -1) {
+ sbuf->st_ex_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
+ if (sbuf->st_ex_size == -1) {
errno = ENOENT;
goto fail;
}
- sbuf->st_ino = stream_inode(sbuf, xattr_name);
- sbuf->st_mode &= ~S_IFMT;
- sbuf->st_mode |= S_IFREG;
- sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1;
+ sbuf->st_ex_ino = stream_inode(sbuf, xattr_name);
+ sbuf->st_ex_mode &= ~S_IFMT;
+ sbuf->st_ex_mode |= S_IFREG;
+ sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1;
result = 0;
fail:
@@ -740,10 +740,10 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
state.streams = NULL;
state.num_streams = 0;
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
- "::$DATA", sbuf.st_size,
+ "::$DATA", sbuf.st_ex_size,
SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
&sbuf))) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index 6fb1d1d2d4..57807105f6 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -153,10 +153,12 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
/* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
then assume it is not offline (it may not be 100%, as it could be sparse) */
- if (512 * (off_t)stbuf->st_blocks >= stbuf->st_size * tsmd->online_ratio) {
+ if (512 * (off_t)stbuf->st_ex_blocks >=
+ stbuf->st_ex_size * tsmd->online_ratio) {
DEBUG(10,("%s not offline: st_blocks=%ld st_size=%ld "
- "online_ratio=%.2f\n", path, (long)stbuf->st_blocks,
- (long)stbuf->st_size, tsmd->online_ratio));
+ "online_ratio=%.2f\n", path,
+ (long)stbuf->st_ex_blocks,
+ (long)stbuf->st_ex_size, tsmd->online_ratio));
return false;
}
@@ -254,9 +256,10 @@ static bool tsmsm_aio_force(struct vfs_handle_struct *handle, struct files_struc
*/
if(SMB_VFS_FSTAT(fsp, &sbuf) == 0) {
DEBUG(10,("tsmsm_aio_force st_blocks=%ld st_size=%ld "
- "online_ratio=%.2f\n", (long)sbuf.st_blocks,
- (long)sbuf.st_size, tsmd->online_ratio));
- return !(512 * (off_t)sbuf.st_blocks >= sbuf.st_size * tsmd->online_ratio);
+ "online_ratio=%.2f\n", (long)sbuf.st_ex_blocks,
+ (long)sbuf.st_ex_size, tsmd->online_ratio));
+ return !(512 * (off_t)sbuf.st_ex_blocks >=
+ sbuf.st_ex_size * tsmd->online_ratio);
}
return false;
}
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index 0736a66fb8..85729ae7ac 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -164,8 +164,8 @@ void start_async_dns(void)
CatchSignal(SIGHUP, SIG_IGN);
CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
- if (!reinit_after_fork(nmbd_messaging_context(),
- nmbd_event_context(), true)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(),
+ nmbd_event_context(), true))) {
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index daf4c295a6..903dc36d53 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -913,8 +913,8 @@ static bool open_sockets(bool isdaemon, int port)
pidfile_create("nmbd");
- if (!reinit_after_fork(nmbd_messaging_context(),
- nmbd_event_context(), false)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(),
+ nmbd_event_context(), false))) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
diff --git a/source3/pam_smbpass/pam_smb_acct.c b/source3/pam_smbpass/pam_smb_acct.c
index 2a8bd26597..9ad74788f0 100644
--- a/source3/pam_smbpass/pam_smb_acct.c
+++ b/source3/pam_smbpass/pam_smb_acct.c
@@ -58,26 +58,25 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
/* Samba initialization. */
load_case_tables();
- setup_logging( "pam_smbpass", False );
lp_set_in_client(True);
- ctrl = set_ctrl( flags, argc, argv );
+ ctrl = set_ctrl(pamh, flags, argc, argv );
/* get the username */
retval = pam_get_user( pamh, &name, "Username: " );
if (retval != PAM_SUCCESS) {
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "acct: could not identify user" );
+ _log_err(pamh, LOG_DEBUG, "acct: could not identify user" );
}
return retval;
}
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
+ _log_err(pamh, LOG_DEBUG, "acct: username [%s] obtained", name );
}
if (geteuid() != 0) {
- _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
return PAM_AUTHINFO_UNAVAIL;
}
@@ -85,7 +84,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
from a SIGPIPE it's not expecting */
oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
if (!initialize_password_db(True, NULL)) {
- _log_err( LOG_ALERT, "Cannot access samba password database" );
+ _log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_AUTHINFO_UNAVAIL;
}
@@ -99,7 +98,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
}
if (!pdb_getsampwnam(sampass, name )) {
- _log_err( LOG_DEBUG, "acct: could not identify user" );
+ _log_err(pamh, LOG_DEBUG, "acct: could not identify user");
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_USER_UNKNOWN;
}
@@ -112,8 +111,8 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG
- , "acct: account %s is administratively disabled", name );
+ _log_err(pamh, LOG_DEBUG,
+ "acct: account %s is administratively disabled", name);
}
make_remark( pamh, ctrl, PAM_ERROR_MSG
, "Your account has been disabled; "
diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c
index b5a6a473b6..88ff9851f5 100644
--- a/source3/pam_smbpass/pam_smb_auth.c
+++ b/source3/pam_smbpass/pam_smb_auth.c
@@ -81,10 +81,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
/* Samba initialization. */
load_case_tables();
- setup_logging("pam_smbpass",False);
lp_set_in_client(True);
- ctrl = set_ctrl(flags, argc, argv);
+ ctrl = set_ctrl(pamh, flags, argc, argv);
/* Get a few bytes so we can pass our return value to
pam_sm_setcred(). */
@@ -99,29 +98,29 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
retval = pam_get_user( pamh, &name, "Username: " );
if ( retval != PAM_SUCCESS ) {
if (on( SMB_DEBUG, ctrl )) {
- _log_err(LOG_DEBUG, "auth: could not identify user");
+ _log_err(pamh, LOG_DEBUG, "auth: could not identify user");
}
AUTH_RETURN;
}
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "username [%s] obtained", name );
+ _log_err(pamh, LOG_DEBUG, "username [%s] obtained", name );
}
if (geteuid() != 0) {
- _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
retval = PAM_AUTHINFO_UNAVAIL;
AUTH_RETURN;
}
if (!initialize_password_db(True, NULL)) {
- _log_err( LOG_ALERT, "Cannot access samba password database" );
+ _log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
retval = PAM_AUTHINFO_UNAVAIL;
AUTH_RETURN;
}
sampass = samu_new( NULL );
if (!sampass) {
- _log_err( LOG_ALERT, "Cannot talloc a samu struct" );
+ _log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" );
retval = nt_status_to_pam(NT_STATUS_NO_MEMORY);
AUTH_RETURN;
}
@@ -135,7 +134,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
}
if (!found) {
- _log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
+ _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name);
retval = PAM_USER_UNKNOWN;
TALLOC_FREE(sampass);
sampass = NULL;
@@ -154,7 +153,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL, _SMB_AUTHTOK, &p);
if (retval != PAM_SUCCESS ) {
- _log_err(LOG_CRIT, "auth: no password provided for [%s]", name);
+ _log_err(pamh,LOG_CRIT, "auth: no password provided for [%s]", name);
TALLOC_FREE(sampass);
AUTH_RETURN;
}
@@ -202,7 +201,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
retval = _pam_get_item( pamh, PAM_AUTHTOK, &pass );
if (retval != PAM_SUCCESS) {
- _log_err( LOG_ALERT
+ _log_err(pamh, LOG_ALERT
, "pam_get_item returned error to pam_sm_authenticate" );
return PAM_AUTHTOK_RECOVER_ERR;
} else if (pass == NULL) {
diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c
index dce6e01ae9..9504e4d53c 100644
--- a/source3/pam_smbpass/pam_smb_passwd.c
+++ b/source3/pam_smbpass/pam_smb_passwd.c
@@ -106,10 +106,9 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* Samba initialization. */
load_case_tables();
- setup_logging( "pam_smbpass", False );
lp_set_in_client(True);
- ctrl = set_ctrl(flags, argc, argv);
+ ctrl = set_ctrl(pamh, flags, argc, argv);
/*
* First get the name of a user. No need to do anything if we can't
@@ -119,16 +118,16 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = pam_get_user( pamh, &user, "Username: " );
if (retval != PAM_SUCCESS) {
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "password: could not identify user" );
+ _log_err(pamh, LOG_DEBUG, "password: could not identify user");
}
return retval;
}
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "username [%s] obtained", user );
+ _log_err(pamh, LOG_DEBUG, "username [%s] obtained", user);
}
if (geteuid() != 0) {
- _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
return PAM_AUTHINFO_UNAVAIL;
}
@@ -137,7 +136,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
if (!initialize_password_db(False, NULL)) {
- _log_err( LOG_ALERT, "Cannot access samba password database" );
+ _log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_AUTHINFO_UNAVAIL;
}
@@ -149,12 +148,12 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
if (!pdb_getsampwnam(sampass,user)) {
- _log_err( LOG_ALERT, "Failed to find entry for user %s.", user );
+ _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", user);
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_USER_UNKNOWN;
}
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_DEBUG, "Located account for %s", user );
+ _log_err(pamh, LOG_DEBUG, "Located account for %s", user);
}
if (flags & PAM_PRELIM_CHECK) {
@@ -180,7 +179,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
#define greeting "Changing password for "
Announce = SMB_MALLOC_ARRAY(char, sizeof(greeting)+strlen(user));
if (Announce == NULL) {
- _log_err(LOG_CRIT, "password: out of memory");
+ _log_err(pamh, LOG_CRIT, "password: out of memory");
TALLOC_FREE(sampass);
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_BUF_ERR;
@@ -195,8 +194,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
SAFE_FREE( Announce );
if (retval != PAM_SUCCESS) {
- _log_err( LOG_NOTICE
- , "password - (old) token not obtained" );
+ _log_err(pamh, LOG_NOTICE,
+ "password - (old) token not obtained");
TALLOC_FREE(sampass);
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return retval;
@@ -241,7 +240,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
if (retval != PAM_SUCCESS) {
- _log_err( LOG_NOTICE, "password: user not authenticated" );
+ _log_err(pamh, LOG_NOTICE, "password: user not authenticated");
TALLOC_FREE(sampass);
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return retval;
@@ -266,8 +265,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
if (on( SMB_DEBUG, ctrl )) {
- _log_err( LOG_ALERT
- , "password: new password not obtained" );
+ _log_err(pamh, LOG_ALERT,
+ "password: new password not obtained");
}
pass_old = NULL; /* tidy up */
TALLOC_FREE(sampass);
@@ -288,7 +287,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = _pam_smb_approve_pass(pamh, ctrl, pass_old, pass_new);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, "new password not acceptable");
+ _log_err(pamh, LOG_NOTICE, "new password not acceptable");
pass_new = pass_old = NULL; /* tidy up */
TALLOC_FREE(sampass);
CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
@@ -308,16 +307,17 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* password updated */
if (!sid_to_uid(pdb_get_user_sid(sampass), &uid)) {
- _log_err( LOG_NOTICE, "Unable to get uid for user %s",
+ _log_err(pamh, LOG_NOTICE,
+ "Unable to get uid for user %s",
pdb_get_username(sampass));
- _log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)",
+ _log_err(pamh, LOG_NOTICE, "password for (%s) changed by (%s/%d)",
user, uidtoname(getuid()), getuid());
} else {
- _log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)",
+ _log_err(pamh, LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)",
user, uid, uidtoname(getuid()), getuid());
}
} else {
- _log_err( LOG_ERR, "password change failed for user %s", user);
+ _log_err(pamh, LOG_ERR, "password change failed for user %s", user);
}
pass_old = pass_new = NULL;
@@ -328,7 +328,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
} else { /* something has broken with the library */
- _log_err( LOG_ALERT, "password received unknown request" );
+ _log_err(pamh, LOG_ALERT, "password received unknown request");
retval = PAM_ABORT;
}
diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c
index b6cf3a886d..855885a6d7 100644
--- a/source3/pam_smbpass/support.c
+++ b/source3/pam_smbpass/support.c
@@ -14,6 +14,7 @@
* this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
#include "includes.h"
#include "general.h"
@@ -64,17 +65,42 @@ void _cleanup(pam_handle_t *, void *, int);
char *_pam_delete(register char *);
/* syslogging function for errors and other information */
+#ifdef HAVE_PAM_VSYSLOG
+void _log_err( pam_handle_t *pamh, int err, const char *format, ... )
+{
+ va_list args;
-void _log_err( int err, const char *format, ... )
+ va_start(args, format);
+ pam_vsyslog(pamh, err, format, args);
+ va_end(args);
+}
+#else
+void _log_err( pam_handle_t *pamh, int err, const char *format, ... )
{
- va_list args;
+ va_list args;
+ const char tag[] = "(pam_smbpass) ";
+ char *mod_format;
+
+ mod_format = SMB_MALLOC_ARRAY(char, sizeof(tag) + strlen(format));
+ /* try really, really hard to log something, since this may have
+ been a message about a malloc() failure... */
+ if (mod_format == NULL) {
+ va_start(args, format);
+ vsyslog(err | LOG_AUTH, format, args);
+ va_end(args);
+ return;
+ }
- va_start( args, format );
- openlog( "PAM_smbpass", LOG_CONS | LOG_PID, LOG_AUTH );
- vsyslog( err, format, args );
- va_end( args );
- closelog();
+ strncpy(mod_format, tag, strlen(tag)+1);
+ strncat(mod_format, format, strlen(format));
+
+ va_start(args, format);
+ vsyslog(err | LOG_AUTH, mod_format, args);
+ va_end(args);
+
+ free(mod_format);
}
+#endif
/* this is a front-end for module-application conversations */
@@ -92,11 +118,11 @@ int converse( pam_handle_t * pamh, int ctrl, int nargs
,response, conv->appdata_ptr);
if (retval != PAM_SUCCESS && on(SMB_DEBUG, ctrl)) {
- _log_err(LOG_DEBUG, "conversation failure [%s]"
+ _log_err(pamh, LOG_DEBUG, "conversation failure [%s]"
,pam_strerror(pamh, retval));
}
} else {
- _log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
+ _log_err(pamh, LOG_ERR, "couldn't obtain coversation function [%s]"
,pam_strerror(pamh, retval));
}
@@ -123,7 +149,7 @@ int make_remark( pam_handle_t * pamh, unsigned int ctrl
/* set the control flags for the SMB module. */
-int set_ctrl( int flags, int argc, const char **argv )
+int set_ctrl( pam_handle_t *pamh, int flags, int argc, const char **argv )
{
int i = 0;
const char *service_file = NULL;
@@ -165,7 +191,7 @@ int set_ctrl( int flags, int argc, const char **argv )
/* Read some options from the Samba config. Can be overridden by
the PAM config. */
if(lp_load(service_file,True,False,False,True) == False) {
- _log_err( LOG_ERR, "Error loading service file %s", service_file );
+ _log_err(pamh, LOG_ERR, "Error loading service file %s", service_file);
}
secrets_init();
@@ -188,7 +214,7 @@ int set_ctrl( int flags, int argc, const char **argv )
}
if (j >= SMB_CTRLS_) {
- _log_err( LOG_ERR, "unrecognized option [%s]", *argv );
+ _log_err(pamh, LOG_ERR, "unrecognized option [%s]", *argv);
} else {
ctrl &= smb_args[j].mask; /* for turning things off */
ctrl |= smb_args[j].flag; /* for turning things on */
@@ -227,7 +253,7 @@ void _cleanup( pam_handle_t * pamh, void *x, int error_status )
* evidence of old token around for later stack analysis.
*
*/
-char * smbpXstrDup( const char *x )
+char * smbpXstrDup( pam_handle_t *pamh, const char *x )
{
register char *newstr = NULL;
@@ -237,7 +263,7 @@ char * smbpXstrDup( const char *x )
for (i = 0; x[i]; ++i); /* length of string */
if ((newstr = SMB_MALLOC_ARRAY(char, ++i)) == NULL) {
i = 0;
- _log_err( LOG_CRIT, "out of memory in smbpXstrDup" );
+ _log_err(pamh, LOG_CRIT, "out of memory in smbpXstrDup");
} else {
while (i-- > 0) {
newstr[i] = x[i];
@@ -279,7 +305,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err )
/* log the number of authentication failures */
if (failure->count != 0) {
_pam_get_item( pamh, PAM_SERVICE, &service );
- _log_err( LOG_NOTICE
+ _log_err(pamh, LOG_NOTICE
, "%d authentication %s "
"from %s for service %s as %s(%d)"
, failure->count
@@ -288,7 +314,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err )
, service == NULL ? "**unknown**" : service
, failure->user, failure->id );
if (failure->count > SMB_MAX_RETRIES) {
- _log_err( LOG_ALERT
+ _log_err(pamh, LOG_ALERT
, "service(%s) ignoring max retries; %d > %d"
, service == NULL ? "**unknown**" : service
, failure->count
@@ -324,8 +350,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass,
if (!pdb_get_nt_passwd(sampass))
{
- _log_err( LOG_DEBUG, "user %s has null SMB password"
- , name );
+ _log_err(pamh, LOG_DEBUG, "user %s has null SMB password", name);
if (off( SMB__NONULL, ctrl )
&& (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
@@ -335,7 +360,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass,
const char *service;
_pam_get_item( pamh, PAM_SERVICE, &service );
- _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s",
+ _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s",
uidtoname(getuid()), service ? service : "**unknown**", name);
return PAM_AUTH_ERR;
}
@@ -343,7 +368,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass,
data_name = SMB_MALLOC_ARRAY(char, sizeof(FAIL_PREFIX) + strlen( name ));
if (data_name == NULL) {
- _log_err( LOG_CRIT, "no memory for data-name" );
+ _log_err(pamh, LOG_CRIT, "no memory for data-name" );
return PAM_AUTH_ERR;
}
strncpy( data_name, FAIL_PREFIX, sizeof(FAIL_PREFIX) );
@@ -390,31 +415,31 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass,
retval = PAM_MAXTRIES;
}
} else {
- _log_err(LOG_NOTICE,
+ _log_err(pamh, LOG_NOTICE,
"failed auth request by %s for service %s as %s",
uidtoname(getuid()),
service ? service : "**unknown**", name);
newauth->count = 1;
}
if (!sid_to_uid(pdb_get_user_sid(sampass), &(newauth->id))) {
- _log_err(LOG_NOTICE,
+ _log_err(pamh, LOG_NOTICE,
"failed auth request by %s for service %s as %s",
uidtoname(getuid()),
service ? service : "**unknown**", name);
}
- newauth->user = smbpXstrDup( name );
- newauth->agent = smbpXstrDup( uidtoname( getuid() ) );
+ newauth->user = smbpXstrDup( pamh, name );
+ newauth->agent = smbpXstrDup( pamh, uidtoname( getuid() ) );
pam_set_data( pamh, data_name, newauth, _cleanup_failures );
} else {
- _log_err( LOG_CRIT, "no memory for failure recorder" );
- _log_err(LOG_NOTICE,
+ _log_err(pamh, LOG_CRIT, "no memory for failure recorder" );
+ _log_err(pamh, LOG_NOTICE,
"failed auth request by %s for service %s as %s(%d)",
uidtoname(getuid()),
service ? service : "**unknown**", name);
}
}
- _log_err(LOG_NOTICE,
+ _log_err(pamh, LOG_NOTICE,
"failed auth request by %s for service %s as %s(%d)",
uidtoname(getuid()),
service ? service : "**unknown**", name);
@@ -422,7 +447,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass,
}
_pam_delete( data_name );
-
+
return retval;
}
@@ -490,8 +515,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
retval = _pam_get_item( pamh, authtok_flag, &item );
if (retval != PAM_SUCCESS) {
/* very strange. */
- _log_err( LOG_ALERT
- , "pam_get_item returned error to smb_read_password" );
+ _log_err(pamh, LOG_ALERT,
+ "pam_get_item returned error to smb_read_password");
return retval;
} else if (item != NULL) { /* we have a password! */
*pass = item;
@@ -543,7 +568,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
if (retval == PAM_SUCCESS) { /* a good conversation */
- token = smbpXstrDup(resp[j++].resp);
+ token = smbpXstrDup(pamh, resp[j++].resp);
if (token != NULL) {
if (expect == 2) {
/* verify that password entered correctly */
@@ -555,7 +580,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
}
}
} else {
- _log_err(LOG_NOTICE, "could not recover authentication token");
+ _log_err(pamh, LOG_NOTICE,
+ "could not recover authentication token");
}
}
@@ -568,7 +594,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
if (retval != PAM_SUCCESS) {
if (on( SMB_DEBUG, ctrl ))
- _log_err( LOG_DEBUG, "unable to obtain a password" );
+ _log_err(pamh, LOG_DEBUG, "unable to obtain a password");
return retval;
}
/* 'token' is the entered password */
@@ -583,7 +609,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
|| (retval = _pam_get_item( pamh, authtok_flag
,&item )) != PAM_SUCCESS)
{
- _log_err( LOG_CRIT, "error manipulating password" );
+ _log_err(pamh, LOG_CRIT, "error manipulating password");
return retval;
}
} else {
@@ -597,8 +623,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
|| (retval = _pam_get_data( pamh, data_name, &item ))
!= PAM_SUCCESS)
{
- _log_err( LOG_CRIT, "error manipulating password data [%s]"
- , pam_strerror( pamh, retval ));
+ _log_err(pamh, LOG_CRIT, "error manipulating password data [%s]",
+ pam_strerror( pamh, retval ));
_pam_delete( token );
item = NULL;
return retval;
@@ -622,8 +648,8 @@ int _pam_smb_approve_pass(pam_handle_t * pamh,
if (pass_new == NULL || (pass_old && !strcmp( pass_old, pass_new )))
{
if (on(SMB_DEBUG, ctrl)) {
- _log_err( LOG_DEBUG,
- "passwd: bad authentication token (null or unchanged)" );
+ _log_err(pamh, LOG_DEBUG,
+ "passwd: bad authentication token (null or unchanged)");
}
make_remark( pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
"No password supplied" : "Password unchanged" );
diff --git a/source3/pam_smbpass/support.h b/source3/pam_smbpass/support.h
index 87f1690a60..7ee77042d7 100644
--- a/source3/pam_smbpass/support.h
+++ b/source3/pam_smbpass/support.h
@@ -1,8 +1,8 @@
/* syslogging function for errors and other information */
-extern void _log_err(int, const char *, ...);
+extern void _log_err(pam_handle_t *, int, const char *, ...);
/* set the control flags for the UNIX module. */
-extern int set_ctrl(int, int, const char **);
+extern int set_ctrl(pam_handle_t *, int, int, const char **);
/* generic function for freeing pam data segments */
extern void _cleanup(pam_handle_t *, void *, int);
@@ -12,7 +12,7 @@ extern void _cleanup(pam_handle_t *, void *, int);
* evidence of old token around for later stack analysis.
*/
-extern char *smbpXstrDup(const char *);
+extern char *smbpXstrDup(pam_handle_t *,const char *);
/* ************************************************************** *
* Useful non-trivial functions *
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 6da792a8d7..57fdb6e044 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -351,6 +351,7 @@ struct global {
int cups_connection_timeout;
char *szSMBPerfcountModule;
bool bMapUntrustedToDomain;
+ bool bFakeDirCreateTimes;
};
static struct global Globals;
@@ -362,7 +363,7 @@ struct service {
bool valid;
bool autoloaded;
int usershare;
- time_t usershare_last_mod;
+ struct timespec usershare_last_mod;
char *szService;
char *szPath;
char *szUsername;
@@ -468,7 +469,6 @@ struct service {
bool bDosFilemode;
bool bDosFiletimes;
bool bDosFiletimeResolution;
- bool bFakeDirCreateTimes;
bool bBlockingLocks;
bool bInheritPerms;
bool bInheritACLS;
@@ -506,7 +506,7 @@ static struct service sDefault = {
True, /* valid */
False, /* not autoloaded */
0, /* not a usershare */
- (time_t)0, /* No last mod time */
+ {0, }, /* No last mod time */
NULL, /* szService */
NULL, /* szPath */
NULL, /* szUsername */
@@ -612,7 +612,6 @@ static struct service sDefault = {
False, /* bDosFilemode */
True, /* bDosFiletimes */
False, /* bDosFiletimeResolution */
- False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
False, /* bInheritPerms */
False, /* bInheritACLS */
@@ -4274,11 +4273,11 @@ static struct parm_struct parm_table[] = {
{
.label = "fake directory create times",
.type = P_BOOL,
- .p_class = P_LOCAL,
- .ptr = &sDefault.bFakeDirCreateTimes,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.bFakeDirCreateTimes,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+ .flags = FLAG_ADVANCED | FLAG_GLOBAL,
},
{
.label = "panic action",
@@ -5000,7 +4999,7 @@ static void init_globals(bool first_time_only)
a large number of sites (tridge) */
Globals.bHostnameLookups = False;
- string_set(&Globals.szPassdbBackend, "smbpasswd");
+ string_set(&Globals.szPassdbBackend, "tdbsam");
string_set(&Globals.szLdapSuffix, "");
string_set(&Globals.szLdapMachineSuffix, "");
string_set(&Globals.szLdapUserSuffix, "");
@@ -5584,7 +5583,7 @@ FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
-FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
+FN_GLOBAL_BOOL(lp_fake_dir_create_times, &Globals.bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
@@ -8330,27 +8329,27 @@ static void set_allowed_client_auth(void)
static bool check_usershare_stat(const char *fname,
const SMB_STRUCT_STAT *psbuf)
{
- if (!S_ISREG(psbuf->st_mode)) {
+ if (!S_ISREG(psbuf->st_ex_mode)) {
DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
"not a regular file\n",
- fname, (unsigned int)psbuf->st_uid ));
+ fname, (unsigned int)psbuf->st_ex_uid ));
return False;
}
/* Ensure this doesn't have the other write bit set. */
- if (psbuf->st_mode & S_IWOTH) {
+ if (psbuf->st_ex_mode & S_IWOTH) {
DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
"public write. Refusing to allow as a usershare file.\n",
- fname, (unsigned int)psbuf->st_uid ));
+ fname, (unsigned int)psbuf->st_ex_uid ));
return False;
}
/* Should be 10k or less. */
- if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
+ if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
"too large (%u) to be a user share file.\n",
- fname, (unsigned int)psbuf->st_uid,
- (unsigned int)psbuf->st_size ));
+ fname, (unsigned int)psbuf->st_ex_uid,
+ (unsigned int)psbuf->st_ex_size ));
return False;
}
@@ -8509,7 +8508,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
sys_closedir(dp);
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
servicename, sharepath ));
return USERSHARE_PATH_NOT_DIRECTORY;
@@ -8521,7 +8520,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
if (lp_usershare_owner_only()) {
/* root can share anything. */
- if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
+ if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
return USERSHARE_PATH_NOT_ALLOWED;
}
}
@@ -8599,7 +8598,9 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
TALLOC_FREE(canon_name);
}
- if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
+ if (iService != -1 &&
+ timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
+ &lsbuf.st_ex_mtime) == 0) {
/* Nothing changed - Mark valid and return. */
DEBUG(10,("process_usershare_file: service %s not changed.\n",
service_name ));
@@ -8632,7 +8633,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
}
/* Is it the same dev/inode as was lstated ? */
- if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
+ if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
close(fd);
DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
"Symlink spoofing going on ?\n", fname ));
@@ -8652,7 +8653,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
close(fd);
if (lines == NULL) {
DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
- fname, (unsigned int)sbuf.st_uid ));
+ fname, (unsigned int)sbuf.st_ex_uid ));
SAFE_FREE(fname);
return -1;
}
@@ -8716,7 +8717,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
}
/* And note when it was loaded. */
- ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
+ ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
string_set(&ServicePtrs[iService]->szPath, sharepath);
string_set(&ServicePtrs[iService]->comment, comment);
@@ -8729,7 +8730,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
Checks if a usershare entry has been modified since last load.
***************************************************************************/
-static bool usershare_exists(int iService, time_t *last_mod)
+static bool usershare_exists(int iService, struct timespec *last_mod)
{
SMB_STRUCT_STAT lsbuf;
const char *usersharepath = Globals.szUsersharePath;
@@ -8746,13 +8747,13 @@ static bool usershare_exists(int iService, time_t *last_mod)
return false;
}
- if (!S_ISREG(lsbuf.st_mode)) {
+ if (!S_ISREG(lsbuf.st_ex_mode)) {
SAFE_FREE(fname);
return false;
}
SAFE_FREE(fname);
- *last_mod = lsbuf.st_mtime;
+ *last_mod = lsbuf.st_ex_mtime;
return true;
}
@@ -8777,7 +8778,7 @@ int load_usershare_service(const char *servicename)
return -1;
}
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
DEBUG(0,("load_usershare_service: %s is not a directory.\n",
usersharepath ));
return -1;
@@ -8789,9 +8790,9 @@ int load_usershare_service(const char *servicename)
*/
#ifdef S_ISVTX
- if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
#else
- if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
#endif
DEBUG(0,("load_usershare_service: directory %s is not owned by root "
"or does not have the sticky bit 't' set or is writable by anyone.\n",
@@ -8860,9 +8861,9 @@ int load_usershare_shares(void)
*/
#ifdef S_ISVTX
- if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
#else
- if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
#endif
DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
"or does not have the sticky bit 't' set or is writable by anyone.\n",
@@ -9263,7 +9264,7 @@ int lp_servicenumber(const char *pszServiceName)
}
if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
- time_t last_mod;
+ struct timespec last_mod;
if (!usershare_exists(iService, &last_mod)) {
/* Remove the share security tdb entry for it. */
@@ -9275,7 +9276,8 @@ int lp_servicenumber(const char *pszServiceName)
}
/* Has it been modified ? If so delete and reload. */
- if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
+ if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
+ &last_mod) < 0) {
/* Remove it from the array. */
free_service_byindex(iService);
/* and now reload it. */
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index b45000e77e..3a03cfe081 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -468,12 +468,15 @@ static bool lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
sid_string_dbg(domain_sid)));
if (num_rids) {
- *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
+ *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
if ((*names == NULL) || (*types == NULL)) {
return false;
}
+
+ for (i = 0; i < num_rids; i++)
+ (*types)[i] = SID_NAME_UNKNOWN;
} else {
*names = NULL;
*types = NULL;
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index d663c7f0b2..8074b2e3a1 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -292,7 +292,7 @@ Error was %s\n", pfile, strerror(errno)));
return NULL;
}
- if( sbuf1.st_ino == sbuf2.st_ino) {
+ if( sbuf1.st_ex_ino == sbuf2.st_ex_ino) {
/* No race. */
break;
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 39e9661bd6..a05e0def7b 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1352,7 +1352,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
if (SMB_VFS_FSTAT(fsp, &st) == -1) {
goto error_exit;
}
- old_create_time = st.st_mtime;
+ old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
(long)old_create_time));
}
@@ -1404,7 +1404,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
if (SMB_VFS_FSTAT(fsp, &st) == -1) {
goto error_exit;
}
- new_create_time = st.st_mtime;
+ new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
(long)new_create_time));
}
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 7edfb5edbe..18f42138c9 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -433,8 +433,8 @@ static bool cups_pcap_load_async(int *pfd)
close_all_print_db();
- if (!reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), true)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), true))) {
DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n"));
smb_panic("cups_pcap_load_async: reinit_after_fork() failed");
}
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index 243b8ea03b..a8e175a684 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -75,7 +75,7 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
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_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
return NT_STATUS_OK;
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index ce98792096..e73669fef5 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -1436,8 +1436,9 @@ void start_background_queue(void)
close(pause_pipe[0]);
pause_pipe[0] = -1;
- if (!reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), true)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(),
+ true))) {
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}
@@ -2563,7 +2564,7 @@ bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
(sys_fstat(pjob->fd, &sbuf) == 0)) {
- pjob->size = sbuf.st_size;
+ pjob->size = sbuf.st_ex_size;
close(pjob->fd);
pjob->fd = -1;
} else {
diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c
index cc6a6f4103..38411d8556 100644
--- a/source3/registry/regfio.c
+++ b/source3/registry/regfio.c
@@ -84,7 +84,7 @@ static int read_block( REGF_FILE *file, prs_struct *ps, uint32 file_offset, uint
return -1;
}
- if ( (size_t)file_offset >= sbuf.st_size )
+ if ( (size_t)file_offset >= sbuf.st_ex_size )
return -1;
/* if block_size == 0, we are parsing HBIN records and need
@@ -1434,7 +1434,7 @@ static REGF_HBIN* regf_hbin_allocate( REGF_FILE *file, uint32 block_size )
return NULL;
}
- hbin->file_off = sbuf.st_size;
+ hbin->file_off = sbuf.st_ex_size;
hbin->free_off = HBIN_HEADER_REC_SIZE;
hbin->free_size = block_size - hbin->free_off + sizeof(uint32);;
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d23b509af2..9aab3a7405 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -103,7 +103,7 @@ static void check_magic(struct files_struct *fsp)
return;
}
- transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size);
close(tmp_fd);
close(outfd);
TALLOC_FREE(ctx);
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index ab4a0d27e3..f5a9e22d14 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -824,7 +824,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
char **pp_fname_out,
SMB_OFF_T *size,
uint32 *mode,
- time_t *date,
+ struct timespec *date,
bool check_descend,
bool ask_sharemode)
{
@@ -910,8 +910,8 @@ bool get_dir_entry(TALLOC_CTX *ctx,
continue;
}
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ *size = sbuf.st_ex_size;
+ *date = sbuf.st_ex_mtime;
if (ask_sharemode) {
struct timespec write_time_ts;
@@ -920,7 +920,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
get_file_infos(fileid, NULL, &write_time_ts);
if (!null_timespec(write_time_ts)) {
- *date = convert_timespec_to_time_t(write_time_ts);
+ *date = write_time_ts;
}
}
@@ -989,7 +989,7 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
/* Pseudo-open the file */
- if(S_ISDIR(pst->st_mode)) {
+ if(S_ISDIR(pst->st_ex_mode)) {
return True;
}
@@ -1012,7 +1012,7 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT
SMB_ASSERT(VALID_STAT(*pst));
- if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
+ if (S_ISREG(pst->st_ex_mode) || S_ISDIR(pst->st_ex_mode) || S_ISLNK(pst->st_ex_mode))
return False;
return True;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 5ae7151303..6468544748 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -3,17 +3,17 @@
dos mode handling functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) James Peach 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 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/>.
*/
@@ -23,7 +23,7 @@
static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
{
#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
+ if (sbuf->st_ex_size > sbuf->st_ex_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
return FILE_ATTRIBUTE_SPARSE;
}
#endif
@@ -88,7 +88,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
}
/* Save for later - but explicitly remove setuid bit for safety. */
- dir_mode = sbuf.st_mode & ~S_ISUID;
+ dir_mode = sbuf.st_ex_mode & ~S_ISUID;
DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
/* Clear "result" */
result = 0;
@@ -117,7 +117,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
result |= S_IXGRP;
-
+
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
@@ -147,7 +147,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
if (ro_opts == MAP_READONLY_YES) {
/* Original Samba method - map inverse of user "w" bit. */
- if ((sbuf->st_mode & S_IWUSR) == 0) {
+ if ((sbuf->st_ex_mode & S_IWUSR) == 0) {
result |= aRONLY;
}
} else if (ro_opts == MAP_READONLY_PERMISSIONS) {
@@ -157,16 +157,16 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
}
} /* Else never set the readonly bit. */
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0))
result |= aARCH;
- if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
+ if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0))
result |= aSYSTEM;
-
- if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
+
+ if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0))
result |= aHIDDEN;
-
- if (S_ISDIR(sbuf->st_mode))
+
+ if (S_ISDIR(sbuf->st_ex_mode))
result = aDIR | (result & aRONLY);
result |= set_sparse_flag(sbuf);
@@ -179,7 +179,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
if (result & aSYSTEM) DEBUG(8, ("s"));
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
-
+
DEBUG(8,("\n"));
return result;
}
@@ -225,7 +225,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S
return False;
}
- if (S_ISDIR(sbuf->st_mode)) {
+ if (S_ISDIR(sbuf->st_ex_mode)) {
dosattr |= aDIR;
}
*pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
@@ -237,7 +237,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S
if (dosattr & aSYSTEM) DEBUG(8, ("s"));
if (dosattr & aDIR ) DEBUG(8, ("d"));
if (dosattr & aARCH ) DEBUG(8, ("a"));
-
+
DEBUG(8,("\n"));
return True;
@@ -332,7 +332,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
result |= aHIDDEN;
}
}
-
+
result |= dos_mode_from_sbuf(conn, path, sbuf);
/* Optimization : Only call is_hidden_path if it's not already
@@ -349,7 +349,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
-
+
DEBUG(8,("\n"));
return(result);
@@ -406,7 +406,7 @@ static bool get_stat_dos_flags(connection_struct *conn,
*dosmode |= aSYSTEM;
if (sbuf->st_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
- if (S_ISDIR(sbuf->st_mode))
+ if (S_ISDIR(sbuf->st_ex_mode))
*dosmode |= aDIR;
*dosmode |= set_sparse_flag(sbuf);
@@ -493,7 +493,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
result |= aHIDDEN;
}
}
-
+
#ifdef HAVE_STAT_DOS_FLAGS
used_stat_dos_flags = get_stat_dos_flags(conn, path, sbuf, &result);
#endif
@@ -506,9 +506,8 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
}
}
-
offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf);
- if (S_ISREG(sbuf->st_mode) && offline) {
+ if (S_ISREG(sbuf->st_ex_mode) && offline) {
result |= FILE_ATTRIBUTE_OFFLINE;
}
@@ -526,7 +525,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
-
+
DEBUG(8,("\n"));
return(result);
@@ -563,17 +562,17 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
return(-1);
}
- unixmode = st->st_mode;
+ unixmode = st->st_ex_mode;
- get_acl_group_bits(conn, fname, &st->st_mode);
+ get_acl_group_bits(conn, fname, &st->st_ex_mode);
- if (S_ISDIR(st->st_mode))
+ if (S_ISDIR(st->st_ex_mode))
dosmode |= aDIR;
else
dosmode &= ~aDIR;
old_mode = dos_mode(conn,fname,st);
-
+
if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
lret = SMB_VFS_SET_OFFLINE(conn, fname);
@@ -590,7 +589,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
old_mode &= ~FILE_ATTRIBUTE_OFFLINE;
if (old_mode == dosmode) {
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return(0);
}
@@ -605,7 +604,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
}
@@ -617,7 +616,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
@@ -639,10 +638,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
if (!MAP_HIDDEN(conn))
mask |= S_IXOTH;
- unixmode |= (st->st_mode & mask);
+ unixmode |= (st->st_ex_mode & mask);
/* if we previously had any r bits set then leave them alone */
- if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
+ if ((tmp = st->st_ex_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
unixmode |= tmp;
}
@@ -650,7 +649,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
/* if we previously had any w bits set then leave them alone
whilst adding in the new w bits, if the new mode is not rdonly */
if (!IS_DOS_READONLY(dosmode)) {
- unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
+ unixmode |= (st->st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
ret = SMB_VFS_CHMOD(conn, fname, unixmode);
@@ -659,7 +658,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
@@ -696,7 +695,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
if (ret == 0) {
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
}
}
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index abffcd2f4f..a248dd9f3b 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -80,7 +80,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
/* fast paths first */
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
return False;
}
if (conn->server_info->utok.uid == 0 || conn->admin_user) {
@@ -90,7 +90,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
#ifdef S_ISVTX
/* sticky bit means delete only by owner or root. */
- if (sbuf.st_mode & S_ISVTX) {
+ if (sbuf.st_ex_mode & S_ISVTX) {
SMB_STRUCT_STAT sbuf_file;
if(SMB_VFS_STAT(conn, fname, &sbuf_file) != 0) {
if (errno == ENOENT) {
@@ -105,7 +105,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
* for bug #3348. Don't assume owning sticky bit
* directory means write access allowed.
*/
- if (conn->server_info->utok.uid != sbuf_file.st_uid) {
+ if (conn->server_info->utok.uid != sbuf_file.st_ex_uid) {
return False;
}
}
@@ -156,17 +156,17 @@ bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT
}
/* Check primary owner access. */
- if (conn->server_info->utok.uid == psbuf->st_uid) {
+ if (conn->server_info->utok.uid == psbuf->st_ex_uid) {
switch (access_mask) {
case FILE_READ_DATA:
- return (psbuf->st_mode & S_IRUSR) ? True : False;
+ return (psbuf->st_ex_mode & S_IRUSR) ? True : False;
case FILE_WRITE_DATA:
- return (psbuf->st_mode & S_IWUSR) ? True : False;
+ return (psbuf->st_ex_mode & S_IWUSR) ? True : False;
default: /* FILE_READ_DATA|FILE_WRITE_DATA */
- if ((psbuf->st_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) {
+ if ((psbuf->st_ex_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) {
return True;
} else {
return False;
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index adf664b396..de5f83c868 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -296,7 +296,7 @@ ssize_t write_file(struct smb_request *req,
*/
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
- setup_write_cache(fsp, st.st_size);
+ setup_write_cache(fsp, st.st_ex_size);
wcp = fsp->wcp;
}
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 36503483a8..72b4ab7aa6 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -424,7 +424,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* 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 && !(st.st_mode & S_IFDIR)) {
+ if (end && !S_ISDIR(st.st_ex_mode)) {
/*
* An intermediate part of the name isn't
* a directory.
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 9e7d103562..3dc057e18d 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -127,7 +127,6 @@ int max_send = BUFFER_SIZE;
int max_recv = BUFFER_SIZE;
uint16 last_session_tag = UID_FIELD_INVALID;
int trans_num = 0;
-char *orig_inbuf = NULL;
pid_t mypid = 0;
time_t last_smb_conf_reload_time = 0;
time_t last_printer_reload_time = 0;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 9d5eead939..2f9f7afd65 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -125,7 +125,6 @@ extern int max_send;
extern int max_recv;
extern uint16 last_session_tag;
extern int trans_num;
-extern char *orig_inbuf;
extern pid_t mypid;
extern time_t last_smb_conf_reload_time;
@@ -206,6 +205,13 @@ struct smbd_smb2_tcon;
DATA_BLOB negprot_spnego(void);
+NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key,
+ struct iovec *vector,
+ int count);
+NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
+ const struct iovec *vector,
+ int count);
+
bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
void reply_smb2002(struct smb_request *req, uint16_t choice);
@@ -244,6 +250,7 @@ struct smbd_smb2_request {
struct smbd_smb2_tcon *tcon;
int current_idx;
+ bool do_signing;
struct {
/* the NBT header is not allocated */
@@ -299,6 +306,9 @@ struct smbd_smb2_session {
NTSTATUS status;
uint64_t vuid;
AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
+ struct auth_serversupplied_info *server_info;
+ DATA_BLOB session_key;
+ bool do_signing;
struct {
/* an id tree used to allocate tids */
@@ -319,11 +329,13 @@ struct smbd_smb2_tcon {
};
struct smbd_server_connection {
- struct fd_event *fde;
- uint64_t num_requests;
- struct smb_signing_state *signing_state;
bool allow_smb2;
struct {
+ struct fd_event *fde;
+ uint64_t num_requests;
+ struct smb_signing_state *signing_state;
+ } smb1;
+ struct {
struct tevent_context *event_ctx;
struct tevent_queue *recv_queue;
struct tevent_queue *send_queue;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 7f99a186aa..e2f31f077c 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -443,7 +443,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
goto err;
}
- if (!S_ISLNK(sbufp->st_mode)) {
+ if (!S_ISLNK(sbufp->st_ex_mode)) {
DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
path));
goto err;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 204cdf9e31..d6be35d29b 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -570,7 +570,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_size;
+ file_len = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
@@ -604,10 +604,9 @@ void reply_ntcreate_and_X(struct smb_request *req)
p += 4;
/* Create time. */
- c_timespec = get_create_timespec(
- &sbuf,lp_fake_dir_create_times(SNUM(conn)));
- a_timespec = get_atimespec(&sbuf);
- m_timespec = get_mtimespec(&sbuf);
+ c_timespec = sbuf.st_ex_btime;
+ a_timespec = sbuf.st_ex_atime;
+ m_timespec = sbuf.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -1037,7 +1036,7 @@ static void call_nt_transact_create(connection_struct *conn,
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_size;
+ file_len = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
@@ -1071,10 +1070,9 @@ static void call_nt_transact_create(connection_struct *conn,
p += 8;
/* Create time. */
- c_timespec = get_create_timespec(
- &sbuf,lp_fake_dir_create_times(SNUM(conn)));
- a_timespec = get_atimespec(&sbuf);
- m_timespec = get_mtimespec(&sbuf);
+ c_timespec = sbuf.st_ex_btime;
+ a_timespec = sbuf.st_ex_atime;
+ m_timespec = sbuf.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -1220,7 +1218,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
}
/* No links from a directory. */
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
status = NT_STATUS_FILE_IS_A_DIRECTORY;
goto out;
}
@@ -1283,8 +1281,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
goto out;
}
- if (smb_fname->st.st_size) {
- ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_size);
+ if (smb_fname->st.st_ex_size) {
+ ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_ex_size);
}
/*
@@ -1296,7 +1294,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
close_file(NULL, fsp1, NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- set_close_write_time(fsp2, get_mtimespec(&smb_fname->st));
+ set_close_write_time(fsp2, smb_fname->st.st_ex_mtime);
status = close_file(NULL, fsp2, NORMAL_CLOSE);
@@ -1311,7 +1309,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
false);
TALLOC_FREE(parent);
- if (ret < (SMB_OFF_T)smb_fname->st.st_size) {
+ if (ret < (SMB_OFF_T)smb_fname->st.st_ex_size) {
status = NT_STATUS_DISK_FULL;
goto out;
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index e6f523a162..c1b29f68f3 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -206,19 +206,19 @@ void change_file_owner_to_parent(connection_struct *conn,
}
become_root();
- ret = SMB_VFS_FCHOWN(fsp, parent_st.st_uid, (gid_t)-1);
+ ret = SMB_VFS_FCHOWN(fsp, parent_st.st_ex_uid, (gid_t)-1);
unbecome_root();
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,
- (unsigned int)parent_st.st_uid,
+ (unsigned int)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,
- (unsigned int)parent_st.st_uid ));
+ (unsigned int)parent_st.st_ex_uid ));
}
NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
@@ -276,9 +276,9 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
}
/* Ensure we're pointing at the same place. */
- if (sbuf.st_dev != psbuf->st_dev ||
- sbuf.st_ino != psbuf->st_ino ||
- sbuf.st_mode != psbuf->st_mode ) {
+ if (sbuf.st_ex_dev != psbuf->st_ex_dev ||
+ sbuf.st_ex_ino != psbuf->st_ex_ino ||
+ sbuf.st_ex_mode != psbuf->st_ex_mode ) {
DEBUG(0,("change_dir_owner_to_parent: "
"device/inode/mode on directory %s changed. "
"Refusing to chown !\n", fname ));
@@ -287,20 +287,20 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
}
become_root();
- ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
+ ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_ex_uid, (gid_t)-1);
unbecome_root();
if (ret == -1) {
status = map_nt_error_from_unix(errno);
DEBUG(10,("change_dir_owner_to_parent: failed to chown "
"directory %s to parent directory uid %u. "
"Error was %s\n", fname,
- (unsigned int)parent_st.st_uid, strerror(errno) ));
+ (unsigned int)parent_st.st_ex_uid, strerror(errno) ));
goto out;
}
DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
"directory %s to parent directory uid %u.\n",
- fname, (unsigned int)parent_st.st_uid ));
+ fname, (unsigned int)parent_st.st_ex_uid ));
out:
@@ -396,7 +396,7 @@ static NTSTATUS open_file(files_struct *fsp,
* open flags. JRA.
*/
- if (file_existed && S_ISFIFO(psbuf->st_mode)) {
+ if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) {
local_flags |= O_NONBLOCK;
}
#endif
@@ -498,7 +498,7 @@ static NTSTATUS open_file(files_struct *fsp,
}
} else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
fsp->posix_open &&
- S_ISLNK(psbuf->st_mode)) {
+ S_ISLNK(psbuf->st_ex_mode)) {
/* This is a POSIX stat open for delete
* or rename on a symlink that points
* nowhere. Allow. */
@@ -543,13 +543,13 @@ static NTSTATUS open_file(files_struct *fsp,
* so catch a directory open and return an EISDIR. JRA.
*/
- if(S_ISDIR(psbuf->st_mode)) {
+ if(S_ISDIR(psbuf->st_ex_mode)) {
fd_close(fsp);
errno = EISDIR;
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -1583,7 +1583,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_CREATE "
"requested for file %s and file "
"already exists.\n", fname ));
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
errno = EISDIR;
} else {
errno = EEXIST;
@@ -1610,13 +1610,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
(create_disposition == FILE_OVERWRITE_IF))) {
if (!open_match_attributes(conn, fname,
existing_dos_attributes,
- new_dos_attributes, psbuf->st_mode,
+ new_dos_attributes, psbuf->st_ex_mode,
unx_mode, &new_unx_mode)) {
DEBUG(5,("open_file_ntcreate: attributes missmatch "
"for file %s (%x %x) (0%o, 0%o)\n",
fname, existing_dos_attributes,
new_dos_attributes,
- (unsigned int)psbuf->st_mode,
+ (unsigned int)psbuf->st_ex_mode,
(unsigned int)unx_mode ));
errno = EACCES;
return NT_STATUS_ACCESS_DENIED;
@@ -1715,7 +1715,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
if (file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
id = vfs_file_id_from_sbuf(conn, psbuf);
lck = get_share_mode_lock(talloc_tos(), id,
@@ -1919,7 +1919,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
if (!file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
/*
* Deal with the race condition where two smbd's detect the
* file doesn't exist and do the create at the same time. One
@@ -2134,7 +2134,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
new_dos_attributes | aARCH,
&tmp_sbuf, parent_dir,
true) == 0) {
- unx_mode = tmp_sbuf.st_mode;
+ unx_mode = tmp_sbuf.st_ex_mode;
}
}
}
@@ -2305,7 +2305,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
return map_nt_error_from_unix(errno);
}
- if (!S_ISDIR(psbuf->st_mode)) {
+ if (!S_ISDIR(psbuf->st_ex_mode)) {
DEBUG(0, ("Directory just '%s' created is not a directory\n",
name));
return NT_STATUS_ACCESS_DENIED;
@@ -2331,9 +2331,9 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
* Consider bits automagically set by UNIX, i.e. SGID bit from parent
* dir.
*/
- if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
+ if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_ex_mode)) {
SMB_VFS_CHMOD(conn, name,
- psbuf->st_mode | (mode & ~psbuf->st_mode));
+ psbuf->st_ex_mode | (mode & ~psbuf->st_ex_mode));
}
}
@@ -2475,7 +2475,7 @@ static NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_INVALID_PARAMETER;
}
- if(!S_ISDIR(psbuf->st_mode)) {
+ if(!S_ISDIR(psbuf->st_ex_mode)) {
DEBUG(5,("open_directory: %s is not a directory !\n",
fname ));
return NT_STATUS_NOT_A_DIRECTORY;
@@ -2524,7 +2524,7 @@ static NTSTATUS open_directory(connection_struct *conn,
* Setup the files_struct for it.
*/
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -2547,7 +2547,7 @@ static NTSTATUS open_directory(connection_struct *conn,
string_set(&fsp->fsp_name,fname);
- mtimespec = get_mtimespec(psbuf);
+ mtimespec = psbuf->st_ex_mtime;
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
conn->connectpath,
@@ -3161,7 +3161,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
}
}
- if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
+ if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) {
status = NT_STATUS_ACCESS_DENIED;
goto fail;
}
@@ -3169,7 +3169,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (allocation_size
- && (allocation_size > sbuf.st_size)) {
+ && (allocation_size > sbuf.st_ex_size)) {
fsp->initial_allocation_size = smb_roundup(
fsp->conn, allocation_size);
if (fsp->is_directory) {
@@ -3184,7 +3184,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
}
} else {
fsp->initial_allocation_size = smb_roundup(
- fsp->conn, (uint64_t)sbuf.st_size);
+ fsp->conn, (uint64_t)sbuf.st_ex_size);
}
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 8d172e17bd..08b1c8c41a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -884,8 +884,8 @@ static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_AC
void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
{
- uid_to_sid( powner_sid, psbuf->st_uid );
- gid_to_sid( pgroup_sid, psbuf->st_gid );
+ uid_to_sid( powner_sid, psbuf->st_ex_uid );
+ gid_to_sid( pgroup_sid, psbuf->st_ex_gid );
}
/****************************************************************************
@@ -1369,7 +1369,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
ZERO_STRUCTP(pace);
pace->type = SMB_ACL_USER_OBJ;
pace->owner_type = UID_ACE;
- pace->unix_ug.uid = pst->st_uid;
+ pace->unix_ug.uid = pst->st_ex_uid;
pace->trustee = *pfile_owner_sid;
pace->attr = ALLOW_ACE;
@@ -1399,7 +1399,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
apply_default_perms(params, is_directory, pace, S_IRUSR);
} else {
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
}
DLIST_ADD(*pp_ace, pace);
@@ -1414,7 +1414,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
ZERO_STRUCTP(pace);
pace->type = SMB_ACL_GROUP_OBJ;
pace->owner_type = GID_ACE;
- pace->unix_ug.uid = pst->st_gid;
+ pace->unix_ug.uid = pst->st_ex_gid;
pace->trustee = *pfile_grp_sid;
pace->attr = ALLOW_ACE;
if (setting_acl) {
@@ -1425,7 +1425,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
pace->perms = 0;
apply_default_perms(params, is_directory, pace, S_IRGRP);
} else {
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
}
DLIST_ADD(*pp_ace, pace);
@@ -1447,7 +1447,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
pace->perms = 0;
apply_default_perms(params, is_directory, pace, S_IROTH);
} else
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
DLIST_ADD(*pp_ace, pace);
}
@@ -1625,7 +1625,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->type = SMB_ACL_OTHER;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
current_ace->owner_type = UID_ACE;
- current_ace->unix_ug.uid = pst->st_uid;
+ current_ace->unix_ug.uid = pst->st_ex_uid;
current_ace->type = SMB_ACL_USER_OBJ;
/*
@@ -1638,7 +1638,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
current_ace->owner_type = GID_ACE;
- current_ace->unix_ug.gid = pst->st_gid;
+ current_ace->unix_ug.gid = pst->st_ex_gid;
current_ace->type = SMB_ACL_GROUP_OBJ;
/*
@@ -1653,7 +1653,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->owner_type = UID_ACE;
/* If it's the owning user, this is a user_obj, not
* a user. */
- if (current_ace->unix_ug.uid == pst->st_uid) {
+ if (current_ace->unix_ug.uid == pst->st_ex_uid) {
current_ace->type = SMB_ACL_USER_OBJ;
} else {
current_ace->type = SMB_ACL_USER;
@@ -1662,7 +1662,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->owner_type = GID_ACE;
/* If it's the primary group, this is a group_obj, not
* a group. */
- if (current_ace->unix_ug.gid == pst->st_gid) {
+ if (current_ace->unix_ug.gid == pst->st_ex_gid) {
current_ace->type = SMB_ACL_GROUP_OBJ;
} else {
current_ace->type = SMB_ACL_GROUP;
@@ -2272,7 +2272,7 @@ static bool unpack_canon_ace(files_struct *fsp,
* A default 3 element mode entry for a directory should be rwx --- ---.
*/
- pst->st_mode = create_default_mode(fsp, False);
+ pst->st_ex_mode = create_default_mode(fsp, False);
if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
free_canon_ace_list(file_ace);
@@ -2288,7 +2288,7 @@ static bool unpack_canon_ace(files_struct *fsp,
* it's a directory.
*/
- pst->st_mode = create_default_mode(fsp, True);
+ pst->st_ex_mode = create_default_mode(fsp, True);
if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
free_canon_ace_list(file_ace);
@@ -2402,7 +2402,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
case SMB_ACL_USER_OBJ:
/* Get the SID from the owner. */
sid_copy(&sid, powner);
- unix_ug.uid = psbuf->st_uid;
+ unix_ug.uid = psbuf->st_ex_uid;
owner_type = UID_ACE;
break;
case SMB_ACL_USER:
@@ -2419,7 +2419,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
* entries out of the blue when setting ACLs, so a get/set
* cycle will drop them.
*/
- if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_uid) {
+ if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_ex_uid) {
SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
continue;
}
@@ -2432,7 +2432,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
case SMB_ACL_GROUP_OBJ:
/* Get the SID from the owning group. */
sid_copy(&sid, pgroup);
- unix_ug.gid = psbuf->st_gid;
+ unix_ug.gid = psbuf->st_ex_gid;
owner_type = GID_ACE;
break;
case SMB_ACL_GROUP:
@@ -2486,7 +2486,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
*/
if (!ensure_canon_entry_valid(&l_head, conn->params,
- S_ISDIR(psbuf->st_mode), powner, pgroup,
+ S_ISDIR(psbuf->st_ex_mode), powner, pgroup,
psbuf, False))
goto fail;
@@ -3097,7 +3097,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
goto done;
}
- if (S_ISDIR(sbuf->st_mode) && def_acl) {
+ if (S_ISDIR(sbuf->st_ex_mode) && def_acl) {
dir_ace = canonicalise_acl(conn, name, def_acl,
sbuf,
&global_sid_Creator_Owner,
@@ -3181,7 +3181,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
uint32_t acc = map_canon_ace_perms(SNUM(conn),
&nt_acl_type,
ace->perms,
- S_ISDIR(sbuf->st_mode));
+ S_ISDIR(sbuf->st_ex_mode));
init_sec_ace(&nt_ace_list[num_aces++],
&ace->trustee,
nt_acl_type,
@@ -3202,7 +3202,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
uint32_t acc = map_canon_ace_perms(SNUM(conn),
&nt_acl_type,
ace->perms,
- S_ISDIR(sbuf->st_mode));
+ S_ISDIR(sbuf->st_ex_mode));
init_sec_ace(&nt_ace_list[num_aces++],
&ace->trustee,
nt_acl_type,
@@ -3357,7 +3357,7 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
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_mode)) {
+ if(S_ISDIR(sbuf.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);
}
@@ -3687,7 +3687,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
}
/* Save the original element we check against. */
- orig_mode = sbuf.st_mode;
+ orig_mode = sbuf.st_ex_mode;
/*
* Unpack the user/group/world id's.
@@ -3704,7 +3704,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
* Noticed by Simo.
*/
- if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
+ if (((user != (uid_t)-1) && (sbuf.st_ex_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_ex_gid != grp))) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
@@ -3741,7 +3741,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
}
/* Save the original element we check against. */
- orig_mode = sbuf.st_mode;
+ orig_mode = sbuf.st_ex_mode;
/* If we successfully chowned, we know we must
* be able to set the acl, so do it as root.
@@ -3785,7 +3785,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (set_acl_as_root) {
become_root();
}
- ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support);
+ ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_ex_gid, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
@@ -3802,7 +3802,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (set_acl_as_root) {
become_root();
}
- ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support);
+ ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_ex_gid, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
@@ -3827,7 +3827,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
unbecome_root();
}
if (sret == -1) {
- if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, 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",
fsp->fsp_name ));
@@ -3889,7 +3889,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
unbecome_root();
}
if(sret == -1) {
- if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override chmod\n",
fsp->fsp_name ));
@@ -4285,7 +4285,7 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_
{
SMB_ACL_T def_acl = NULL;
- if (!S_ISDIR(psbuf->st_mode)) {
+ if (!S_ISDIR(psbuf->st_ex_mode)) {
if (num_def_acls) {
DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
errno = EISDIR;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 5cad8bfc9a..e014965147 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1462,7 +1462,7 @@ static void process_smb(struct smbd_server_connection *conn,
trans_num++;
done:
- conn->num_requests++;
+ conn->smb1.num_requests++;
/* The timeout_processing function isn't run nearly
often enough to implement 'max log size' without
@@ -1471,7 +1471,7 @@ done:
level 10. Checking every 50 SMBs is a nice
tradeoff of performance vs log file size overrun. */
- if ((conn->num_requests % 50) == 0 &&
+ if ((conn->smb1.num_requests % 50) == 0 &&
need_to_check_log_size()) {
change_to_root_user();
check_log_size();
@@ -2158,13 +2158,13 @@ void smbd_process(void)
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
- smbd_server_conn->fde = event_add_fd(smbd_event_context(),
- smbd_server_conn,
- smbd_server_fd(),
- EVENT_FD_READ,
- smbd_server_connection_handler,
- smbd_server_conn);
- if (!smbd_server_conn->fde) {
+ smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
+ smbd_server_conn,
+ smbd_server_fd(),
+ EVENT_FD_READ,
+ smbd_server_connection_handler,
+ smbd_server_conn);
+ if (!smbd_server_conn->smb1.fde) {
exit_server("failed to create smbd_server_connection fde");
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index d5ee918b82..8657bd6e18 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1022,7 +1022,7 @@ void reply_checkpath(struct smb_request *req)
goto path_err;
}
- if (!S_ISDIR(smb_fname->st.st_mode)) {
+ if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERRbadpath);
goto out;
@@ -1135,8 +1135,8 @@ void reply_getatr(struct smb_request *req)
}
mode = dos_mode(conn, fname, &smb_fname->st);
- size = smb_fname->st.st_size;
- mtime = smb_fname->st.st_mtime;
+ size = smb_fname->st.st_ex_size;
+ mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (mode & aDIR) {
size = 0;
}
@@ -1336,7 +1336,7 @@ void reply_search(struct smb_request *req)
char *fname = NULL;
SMB_OFF_T size;
uint32 mode;
- time_t date;
+ struct timespec date;
uint32 dirtype;
unsigned int numentries = 0;
unsigned int maxentries = 0;
@@ -1555,7 +1555,7 @@ void reply_search(struct smb_request *req)
fname,
size,
mode,
- date,
+ convert_timespec_to_time_t(date),
!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsearch);
@@ -1775,9 +1775,9 @@ void reply_open(struct smb_request *req)
return;
}
- size = sbuf.st_size;
+ size = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
if (fattr & aDIR) {
DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
@@ -1939,11 +1939,11 @@ void reply_open_and_X(struct smb_request *req)
END_PROFILE(SMBopenX);
return;
}
- sbuf.st_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
+ sbuf.st_ex_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
}
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS, ERRnoaccess);
@@ -1992,7 +1992,7 @@ void reply_open_and_X(struct smb_request *req)
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
}
- SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
+ SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_ex_size);
SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
SSVAL(req->outbuf,smb_vwv11,smb_action);
@@ -2124,7 +2124,7 @@ void reply_mknew(struct smb_request *req)
return;
}
- ft.atime = get_atimespec(&sbuf); /* atime. */
+ ft.atime = sbuf.st_ex_atime; /* atime. */
status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
@@ -2306,7 +2306,7 @@ void reply_ctemp(struct smb_request *req)
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,
- fsp->fh->fd, (unsigned int)smb_fname->st.st_mode));
+ fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
out:
TALLOC_FREE(smb_fname);
END_PROFILE(SMBctemp);
@@ -2331,7 +2331,7 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
return NT_STATUS_NO_SUCH_FILE;
}
- if (S_ISDIR(pst->st_mode)) {
+ if (S_ISDIR(pst->st_ex_mode)) {
if (fsp->posix_open) {
return NT_STATUS_OK;
}
@@ -2893,7 +2893,7 @@ static void send_file_readbraw(connection_struct *conn,
if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) &&
- lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) {
ssize_t sendfile_read = -1;
char header[4];
DATA_BLOB header_blob;
@@ -3104,7 +3104,7 @@ void reply_readbraw(struct smb_request *req)
}
if (SMB_VFS_FSTAT(fsp, &st) == 0) {
- size = st.st_size;
+ size = st.st_ex_size;
}
if (startpos >= size) {
@@ -3393,8 +3393,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
return;
}
- if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size)
- || (smb_maxcnt > (sbuf.st_size - startpos))) {
+ if (!S_ISREG(sbuf.st_ex_mode) || (startpos > sbuf.st_ex_size)
+ || (smb_maxcnt > (sbuf.st_ex_size - startpos))) {
/*
* We already know that we would do a short read, so don't
* try the sendfile() path.
@@ -3412,7 +3412,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
if (!req_is_in_chain(req) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) &&
- lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
@@ -4442,7 +4442,7 @@ void reply_lseek(struct smb_request *req)
return;
}
- current_pos += sbuf.st_size;
+ current_pos += sbuf.st_ex_size;
if(current_pos < 0)
res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
}
@@ -5287,7 +5287,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx,
break;
}
- if(st.st_mode & S_IFDIR) {
+ if(st.st_ex_mode & S_IFDIR) {
if(!recursive_rmdir(ctx, conn, fullname)) {
ret = False;
break;
@@ -5322,12 +5322,12 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
return map_nt_error_from_unix(errno);
}
- if (S_ISLNK(st.st_mode)) {
+ if (S_ISLNK(st.st_ex_mode)) {
/* Is what it points to a directory ? */
if(SMB_VFS_STAT(conn, directory, &st) != 0) {
return map_nt_error_from_unix(errno);
}
- if (!(S_ISDIR(st.st_mode))) {
+ if (!(S_ISDIR(st.st_ex_mode))) {
return NT_STATUS_NOT_A_DIRECTORY;
}
ret = SMB_VFS_UNLINK(conn,directory);
@@ -5404,7 +5404,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
break;
}
- if(st.st_mode & S_IFDIR) {
+ if(st.st_ex_mode & S_IFDIR) {
if(!recursive_rmdir(ctx, conn, fullname)) {
break;
}
@@ -6103,7 +6103,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
SMB_VFS_STAT(conn, directory, &smb_fname->st);
}
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
@@ -6229,7 +6229,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
create_options = 0;
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
@@ -6510,18 +6510,18 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
* Stop the copy from occurring.
*/
ret = -1;
- src_sbuf.st_size = 0;
+ src_sbuf.st_ex_size = 0;
}
}
- if (src_sbuf.st_size) {
- ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
+ if (src_sbuf.st_ex_size) {
+ ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_ex_size);
}
close_file(NULL, fsp1, NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
+ set_close_write_time(fsp2, src_sbuf.st_ex_mtime);
/*
* As we are opening fsp1 read-only we only expect
@@ -6535,7 +6535,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
return status;
}
- if (ret != (SMB_OFF_T)src_sbuf.st_size) {
+ if (ret != (SMB_OFF_T)src_sbuf.st_ex_size) {
return NT_STATUS_DISK_FULL;
}
@@ -7551,19 +7551,20 @@ void reply_getattrE(struct smb_request *req)
reply_outbuf(req, 11, 0);
- create_ts = get_create_timespec(&sbuf,
- lp_fake_dir_create_times(SNUM(conn)));
+ create_ts = sbuf.st_ex_btime;
srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
- srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
+ srv_put_dos_date2((char *)req->outbuf, smb_vwv2,
+ convert_timespec_to_time_t(sbuf.st_ex_atime));
/* Should we check pending modtime here ? JRA */
- srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
+ srv_put_dos_date2((char *)req->outbuf, smb_vwv4,
+ convert_timespec_to_time_t(sbuf.st_ex_mtime));
if (mode & aDIR) {
SIVAL(req->outbuf, smb_vwv6, 0);
SIVAL(req->outbuf, smb_vwv8, 0);
} else {
uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &sbuf);
- SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
+ SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_ex_size);
SIVAL(req->outbuf, smb_vwv8, allocation_size);
}
SSVAL(req->outbuf,smb_vwv10, mode);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 67836f785b..685b26fa1a 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -356,6 +356,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
pid = sys_fork();
if (pid == 0) {
+ NTSTATUS status = NT_STATUS_OK;
/* Child code ... */
am_parent = 0;
@@ -374,10 +375,15 @@ static void smbd_accept_connection(struct tevent_context *ev,
talloc_free(s->parent);
s = NULL;
- if (!reinit_after_fork(
- smbd_messaging_context(),
- smbd_event_context(),
- true)) {
+ status = reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), true);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_TOO_MANY_OPENED_FILES)) {
+ DEBUG(0,("child process cannot initialize "
+ "because too many files are open\n"));
+ goto exit;
+ }
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}
@@ -386,6 +392,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
smbd_setup_sig_hup_handler();
smbd_process();
+ exit:
exit_server_cleanly("end of child");
return;
} else if (pid < 0) {
@@ -1122,8 +1129,8 @@ extern void build_options(bool screen);
if (is_daemon)
pidfile_create("smbd");
- if (!reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), false)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), false))) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index bc07f0b90d..75c19ce131 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -993,8 +993,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
I have disabled this chdir check (tridge) */
/* the alternative is just to check the directory exists */
if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
- !S_ISDIR(st.st_mode)) {
- if (ret == 0 && !S_ISDIR(st.st_mode)) {
+ !S_ISDIR(st.st_ex_mode)) {
+ if (ret == 0 && !S_ISDIR(st.st_ex_mode)) {
DEBUG(0,("'%s' is not a directory, when connecting to "
"[%s]\n", conn->connectpath,
lp_servicename(snum)));
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
index b56eb71f45..9b5e3452f9 100644
--- a/source3/smbd/signing.c
+++ b/source3/smbd/signing.c
@@ -35,8 +35,8 @@ bool srv_check_sign_mac(struct smbd_server_connection *conn,
return true;
}
- *seqnum = smb_signing_next_seqnum(conn->signing_state, false);
- return smb_signing_check_pdu(conn->signing_state,
+ *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
+ return smb_signing_check_pdu(conn->smb1.signing_state,
(const uint8_t *)inbuf,
*seqnum);
}
@@ -53,7 +53,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
return;
}
- smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum);
+ smb_signing_sign_pdu(conn->smb1.signing_state, (uint8_t *)outbuf, seqnum);
}
@@ -62,7 +62,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
************************************************************/
void srv_cancel_sign_response(struct smbd_server_connection *conn)
{
- smb_signing_cancel_reply(conn->signing_state, true);
+ smb_signing_cancel_reply(conn->smb1.signing_state, true);
}
/***********************************************************
@@ -87,9 +87,9 @@ bool srv_init_signing(struct smbd_server_connection *conn)
break;
}
- conn->signing_state = smb_signing_init(smbd_event_context(),
- allowed, mandatory);
- if (!conn->signing_state) {
+ conn->smb1.signing_state = smb_signing_init(smbd_event_context(),
+ allowed, mandatory);
+ if (!conn->smb1.signing_state) {
return false;
}
@@ -98,7 +98,7 @@ bool srv_init_signing(struct smbd_server_connection *conn)
void srv_set_signing_negotiated(struct smbd_server_connection *conn)
{
- smb_signing_set_negotiated(conn->signing_state);
+ smb_signing_set_negotiated(conn->smb1.signing_state);
}
/***********************************************************
@@ -108,7 +108,7 @@ void srv_set_signing_negotiated(struct smbd_server_connection *conn)
bool srv_is_signing_active(struct smbd_server_connection *conn)
{
- return smb_signing_is_active(conn->signing_state);
+ return smb_signing_is_active(conn->smb1.signing_state);
}
@@ -119,7 +119,7 @@ bool srv_is_signing_active(struct smbd_server_connection *conn)
bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
{
- return smb_signing_is_negotiated(conn->signing_state);
+ return smb_signing_is_negotiated(conn->smb1.signing_state);
}
/***********************************************************
@@ -136,8 +136,8 @@ void srv_set_signing(struct smbd_server_connection *conn,
if (!user_session_key.length)
return;
- negotiated = smb_signing_is_negotiated(conn->signing_state);
- mandatory = smb_signing_is_mandatory(conn->signing_state);
+ negotiated = smb_signing_is_negotiated(conn->smb1.signing_state);
+ mandatory = smb_signing_is_mandatory(conn->smb1.signing_state);
if (!negotiated && !mandatory) {
DEBUG(5,("srv_set_signing: signing negotiated = %u, "
@@ -146,7 +146,7 @@ void srv_set_signing(struct smbd_server_connection *conn,
return;
}
- if (!smb_signing_activate(conn->signing_state,
+ if (!smb_signing_activate(conn->smb1.signing_state,
user_session_key, response)) {
return;
}
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index b976ea2399..e9464900f2 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -74,8 +74,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
size_t body_size;
size_t expected_dyn_size = 0;
size_t c;
+ uint16_t security_mode;
uint16_t dialect_count;
uint16_t dialect;
+ uint32_t capabilities;
/* TODO: drop the connection with INVALI_PARAMETER */
@@ -103,12 +105,12 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
for (c=0; c < dialect_count; c++) {
dialect = SVAL(indyn, c*2);
- if (dialect == 0x0202) {
+ if (dialect == SMB2_DIALECT_REVISION_202) {
break;
}
}
- if (dialect != 0x0202) {
+ if (dialect != SMB2_DIALECT_REVISION_202) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
@@ -129,6 +131,16 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
}
+ security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
+ if (lp_server_signing() == Required) {
+ security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ }
+
+ capabilities = 0;
+ if (lp_host_msdfs()) {
+ capabilities |= SMB2_CAP_DFS;
+ }
+
security_offset = SMB2_HDR_BODY + 0x40;
security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
negprot_spnego_blob.length - 16);
@@ -142,13 +154,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
}
SSVAL(outbody.data, 0x00, 0x40 + 1); /* struct size */
-/*TODO: indicate signing enabled */
- SSVAL(outbody.data, 0x02, 0); /* security mode */
+ SSVAL(outbody.data, 0x02,
+ security_mode); /* security mode */
SSVAL(outbody.data, 0x04, dialect); /* dialect revision */
SSVAL(outbody.data, 0x06, 0); /* reserved */
memcpy(outbody.data + 0x08,
negprot_spnego_blob.data, 16); /* server guid */
- SIVAL(outbody.data, 0x18, 0); /* capabilities */
+ SIVAL(outbody.data, 0x18,
+ capabilities); /* capabilities */
SIVAL(outbody.data, 0x1C, 0x00010000); /* max transact size */
SIVAL(outbody.data, 0x20, 0x00010000); /* max read size */
SIVAL(outbody.data, 0x24, 0x00010000); /* max write size */
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 32bb5543ae..0d901714e0 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -41,7 +41,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn)
NTSTATUS status;
int ret;
- TALLOC_FREE(conn->fde);
+ TALLOC_FREE(conn->smb1.fde);
conn->smb2.event_ctx = smbd_event_context();
@@ -288,14 +288,45 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
const uint8_t *inhdr;
int i = req->current_idx;
uint16_t opcode;
+ uint32_t flags;
NTSTATUS status;
+ NTSTATUS session_status;
inhdr = (const uint8_t *)req->in.vector[i].iov_base;
/* TODO: verify more things */
+ flags = IVAL(inhdr, SMB2_HDR_FLAGS);
opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode));
+
+#define TMP_SMB2_ALLOWED_FLAGS ( \
+ SMB2_HDR_FLAG_CHAINED | \
+ SMB2_HDR_FLAG_SIGNED | \
+ SMB2_HDR_FLAG_DFS)
+ if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+#undef TMP_SMB2_ALLOWED_FLAGS
+
+ session_status = smbd_smb2_request_check_session(req);
+
+ req->do_signing = false;
+ if (flags & SMB2_HDR_FLAG_SIGNED) {
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+
+ req->do_signing = true;
+ status = smb2_signing_check_pdu(req->session->session_key,
+ &req->in.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ } else if (req->session && req->session->do_signing) {
+ return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
+ }
+
switch (opcode) {
case SMB2_OP_NEGPROT:
return smbd_smb2_request_process_negprot(req);
@@ -304,13 +335,15 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_sesssetup(req);
case SMB2_OP_LOGOFF:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
return smbd_smb2_request_process_logoff(req);
case SMB2_OP_TCON:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
status = smbd_smb2_request_check_session(req);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
@@ -318,9 +351,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_tcon(req);
case SMB2_OP_TDIS:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -329,9 +361,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_tdis(req);
case SMB2_OP_CREATE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -340,9 +371,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CLOSE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -351,9 +381,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_FLUSH:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -362,9 +391,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_READ:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -373,9 +401,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_WRITE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -384,9 +411,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_LOCK:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -395,9 +421,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_IOCTL:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -412,9 +437,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_keepalive(req);
case SMB2_OP_FIND:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -423,9 +447,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_NOTIFY:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -434,9 +457,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_GETINFO:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -445,9 +467,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_SETINFO:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -456,9 +477,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_BREAK:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -481,6 +501,16 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
+ if (req->do_signing) {
+ int i = req->current_idx;
+ NTSTATUS status;
+ status = smb2_signing_sign_pdu(req->session->session_key,
+ &req->out.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
req->current_idx += 3;
if (req->current_idx > req->in.vector_count) {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index fafda24ca4..be37aec04d 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -24,7 +24,9 @@
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id,
+ uint8_t in_security_mode,
DATA_BLOB in_security_buffer,
+ uint16_t *out_session_flags,
DATA_BLOB *out_security_buffer,
uint64_t *out_session_id);
@@ -39,9 +41,11 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
size_t expected_body_size = 0x19;
size_t body_size;
uint64_t in_session_id;
+ uint8_t in_security_mode;
uint16_t in_security_offset;
uint16_t in_security_length;
DATA_BLOB in_security_buffer;
+ uint16_t out_session_flags;
uint64_t out_session_id;
uint16_t out_security_offset;
DATA_BLOB out_security_buffer;
@@ -72,12 +76,15 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
}
in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
+ in_security_mode = CVAL(inbody, 0x03);
in_security_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
in_security_buffer.length = in_security_length;
status = smbd_smb2_session_setup(req,
in_session_id,
+ in_security_mode,
in_security_buffer,
+ &out_session_flags,
&out_security_buffer,
&out_session_id);
if (!NT_STATUS_IS_OK(status) &&
@@ -98,7 +105,8 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
- SSVAL(outbody.data, 0x02, 0); /* session flags */
+ SSVAL(outbody.data, 0x02,
+ out_session_flags); /* session flags */
SSVAL(outbody.data, 0x04,
out_security_offset); /* security buffer offset */
SSVAL(outbody.data, 0x06,
@@ -132,13 +140,17 @@ static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id,
+ uint8_t in_security_mode,
DATA_BLOB in_security_buffer,
+ uint16_t *out_session_flags,
DATA_BLOB *out_security_buffer,
uint64_t *out_session_id)
{
struct smbd_smb2_session *session;
NTSTATUS status;
+ *out_session_flags = 0;
+
if (in_session_id == 0) {
int id;
@@ -185,6 +197,7 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
if (session->auth_ntlmssp_state == NULL) {
status = auth_ntlmssp_start(&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
return status;
}
}
@@ -193,19 +206,54 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
in_security_buffer,
out_security_buffer);
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- /* nothing to do */
- } else if (NT_STATUS_IS_OK(status)) {
- /* TODO: setup session key for signing */
- session->status = NT_STATUS_OK;
- /*
- * we attach the session to the request
- * so that the response can be signed
- */
- req->session = session;
- } else {
+ *out_session_id = session->vuid;
+ return status;
+ } else if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
return status;
}
+ /* TODO: setup session key for signing */
+
+ if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
+ lp_server_signing() == Required) {
+ session->do_signing = true;
+ }
+
+ if (session->auth_ntlmssp_state->server_info->guest) {
+ /* we map anonymous to guest internally */
+ *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
+ *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
+ /* force no signing */
+ session->do_signing = false;
+ }
+
+ session->server_info = session->auth_ntlmssp_state->server_info;
+ data_blob_free(&session->server_info->user_session_key);
+ session->server_info->user_session_key =
+ data_blob_talloc(
+ session->server_info,
+ session->auth_ntlmssp_state->ntlmssp_state->session_key.data,
+ session->auth_ntlmssp_state->ntlmssp_state->session_key.length);
+ if (session->auth_ntlmssp_state->ntlmssp_state->session_key.length > 0) {
+ if (session->server_info->user_session_key.data == NULL) {
+ TALLOC_FREE(session);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ session->session_key = session->server_info->user_session_key;
+
+ session->status = NT_STATUS_OK;
+
+ /*
+ * we attach the session to the request
+ * so that the response can be signed
+ */
+ req->session = session;
+ if (session->do_signing) {
+ req->do_signing = true;
+ }
+
*out_session_id = session->vuid;
return status;
}
diff --git a/source3/smbd/smb2_signing.c b/source3/smbd/smb2_signing.c
new file mode 100644
index 0000000000..55ed4f6d1c
--- /dev/null
+++ b/source3/smbd/smb2_signing.c
@@ -0,0 +1,135 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB2 signing
+
+ Copyright (C) Stefan 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 "smbd/globals.h"
+#include "../source4/libcli/smb2/smb2_constants.h"
+#include "../lib/crypto/crypto.h"
+
+NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key,
+ struct iovec *vector,
+ int count)
+{
+ uint8_t *hdr;
+ uint64_t session_id;
+ struct HMACSHA256Context m;
+ uint8_t res[SHA256_DIGEST_LENGTH];
+ int i;
+
+ if (count < 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_HDR_BODY) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr = (uint8_t *)vector[0].iov_base;
+
+ session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /*
+ * do not sign messages with a zero session_id.
+ * See MS-SMB2 3.2.4.1.1
+ */
+ return NT_STATUS_OK;
+ }
+
+ if (session_key.length == 0) {
+ DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ (unsigned)session_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memset(hdr + SMB2_HDR_SIGNATURE, 0, 16);
+
+ SIVAL(hdr, SMB2_HDR_FLAGS, IVAL(hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
+
+ ZERO_STRUCT(m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
+ for (i=0; i < count; i++) {
+ hmac_sha256_update((const uint8_t *)vector[i].iov_base,
+ vector[i].iov_len, &m);
+ }
+ hmac_sha256_final(res, &m);
+ DEBUG(5,("signed SMB2 message\n"));
+
+ memcpy(hdr + SMB2_HDR_SIGNATURE, res, 16);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
+ const struct iovec *vector,
+ int count)
+{
+ const uint8_t *hdr;
+ const uint8_t *sig;
+ uint64_t session_id;
+ struct HMACSHA256Context m;
+ uint8_t res[SHA256_DIGEST_LENGTH];
+ static const uint8_t zero_sig[16];
+ int i;
+
+ if (count < 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_HDR_BODY) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr = (const uint8_t *)vector[0].iov_base;
+
+ session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /*
+ * do not sign messages with a zero session_id.
+ * See MS-SMB2 3.2.4.1.1
+ */
+ return NT_STATUS_OK;
+ }
+
+ if (session_key.length == 0) {
+ /* we don't have the session key yet */
+ return NT_STATUS_OK;
+ }
+
+ sig = hdr+SMB2_HDR_SIGNATURE;
+
+ ZERO_STRUCT(m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
+ hmac_sha256_update(hdr, SMB2_HDR_SIGNATURE, &m);
+ hmac_sha256_update(zero_sig, 16, &m);
+ for (i=1; i < count; i++) {
+ hmac_sha256_update((const uint8_t *)vector[i].iov_base,
+ vector[i].iov_len, &m);
+ }
+ hmac_sha256_final(res, &m);
+
+ if (memcmp(res, sig, 16) != 0) {
+ DEBUG(0,("Bad SMB2 signature for message\n"));
+ dump_data(0, sig, 16);
+ dump_data(0, res, 16);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
+}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1748cfa0b8..1d95c207ba 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1015,8 +1015,8 @@ static void call_trans2open(connection_struct *conn,
size = get_file_size_stat(&sbuf);
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
- inode = sbuf.st_ino;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ inode = sbuf.st_ex_ino;
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
@@ -1136,7 +1136,7 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
if (!VALID_STAT(*psbuf)) {
return NT_STATUS_INVALID_PARAMETER;
} else {
- *ret_perms = psbuf->st_mode;
+ *ret_perms = psbuf->st_ex_mode;
return NT_STATUS_OK;
}
}
@@ -1207,7 +1207,7 @@ static bool check_msdfs_link(connection_struct *conn,
DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
"as a directory\n",
pathname));
- psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR;
+ psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
errno = saved_errno;
return true;
}
@@ -1417,10 +1417,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
- mdate_ts = get_mtimespec(&sbuf);
- adate_ts = get_atimespec(&sbuf);
- create_date_ts = get_create_timespec(&sbuf,
- lp_fake_dir_create_times(SNUM(conn)));
+ mdate_ts = sbuf.st_ex_mtime;
+ adate_ts = sbuf.st_ex_atime;
+ create_date_ts = sbuf.st_ex_btime;
if (ask_sharemode) {
struct timespec write_time_ts;
@@ -1737,8 +1736,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
p +=4;
}
SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
@@ -1793,8 +1792,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
p += 26;
SSVAL(p,0,0); p += 2; /* Reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
@@ -2579,7 +2578,7 @@ static void call_trans2qfsinfo(connection_struct *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;
@@ -2654,10 +2653,10 @@ static void call_trans2qfsinfo(connection_struct *conn,
sectors_per_unit = bsize/bytes_per_sector;
DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
-cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
+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));
- SIVAL(pdata,l1_idFileSystem,st.st_dev);
+ SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
SIVAL(pdata,l1_cUnit,dsize);
SIVAL(pdata,l1_cUnitAvail,dfree);
@@ -2686,7 +2685,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
- (unsigned)st.st_ctime, len, vname));
+ (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
+ len, vname));
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
@@ -2849,13 +2849,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
*/
files_struct fsp;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(fsp);
ZERO_STRUCT(quotas);
-
+
fsp.conn = conn;
fsp.fnum = -1;
-
+
/* access check */
if (conn->server_info->utok.uid != 0) {
DEBUG(0,("set_user_quota: access_denied "
@@ -2865,7 +2865,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
+
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, ERRSRV, ERRerror);
@@ -2875,25 +2875,25 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
data_len = 48;
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);
SBIG_UINT(pdata,8,(uint64_t)0);
SBIG_UINT(pdata,16,(uint64_t)0);
-
+
/* Default Soft Quota 8 bytes */
SBIG_UINT(pdata,24,quotas.softlim);
/* Default Hard Quota 8 bytes */
SBIG_UINT(pdata,32,quotas.hardlim);
-
+
/* Quota flag 2 bytes */
SSVAL(pdata,40,quotas.qflags);
-
+
/* Unknown3 6 NULL bytes */
SSVAL(pdata,42,0);
SIVAL(pdata,44,0);
-
+
break;
}
#endif /* HAVE_SYS_QUOTAS */
@@ -3300,7 +3300,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
{
files_struct *fsp = NULL;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(quotas);
/* access check */
@@ -3335,9 +3335,9 @@ cap_low = 0x%x, cap_high = 0x%x\n",
NT_STATUS_INVALID_PARAMETER);
return;
}
-
+
/* unknown_1 24 NULL bytes in pdata*/
-
+
/* the soft quotas 8 bytes (uint64_t)*/
quotas.softlim = (uint64_t)IVAL(pdata,24);
#ifdef LARGE_SMB_OFF_T
@@ -3353,7 +3353,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
/* the hard quotas 8 bytes (uint64_t)*/
quotas.hardlim = (uint64_t)IVAL(pdata,32);
#ifdef LARGE_SMB_OFF_T
@@ -3369,19 +3369,19 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
/* quota_flags 2 bytes **/
quotas.qflags = SVAL(pdata,40);
-
+
/* unknown_2 6 NULL bytes follow*/
-
+
/* now set the quotas */
if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, ERRSRV, ERRerror);
return;
}
-
+
break;
}
default:
@@ -3461,7 +3461,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
switch (tagtype) {
case SMB_ACL_USER_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
- own_grp = (unsigned int)pst->st_uid;
+ own_grp = (unsigned int)pst->st_ex_uid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
@@ -3481,7 +3481,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
}
case SMB_ACL_GROUP_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
- own_grp = (unsigned int)pst->st_gid;
+ own_grp = (unsigned int)pst->st_ex_gid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
@@ -3530,7 +3530,7 @@ static char *store_file_unix_basic(connection_struct *conn,
const SMB_STRUCT_STAT *psbuf)
{
DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
- DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
+ DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */
pdata += 8;
@@ -3538,38 +3538,38 @@ static char *store_file_unix_basic(connection_struct *conn,
SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
- put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */
- put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */
- put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */
+ put_long_date_timespec(pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
+ put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
+ put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
pdata += 24;
- SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */
+ SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */
+ SIVAL(pdata,0,psbuf->st_ex_gid); /* group id of owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_filetype(psbuf->st_mode));
+ SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
pdata += 4;
- SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */
+ SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */
+ SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */
pdata += 8;
-
- SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */
+
+ SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */
+ SIVAL(pdata,0,psbuf->st_ex_nlink); /* number of hard links */
SIVAL(pdata,4,0);
pdata += 8;
@@ -3613,16 +3613,14 @@ static const struct {unsigned stat_fflag; unsigned smb_fflag;}
static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
uint32 *smb_fflags, uint32 *smb_fmask)
{
-#ifdef HAVE_STAT_ST_FLAGS
int i;
for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
*smb_fmask |= info2_flags_map[i].smb_fflag;
- if (psbuf->st_flags & info2_flags_map[i].stat_fflag) {
+ if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
*smb_fflags |= info2_flags_map[i].smb_fflag;
}
}
-#endif /* HAVE_STAT_ST_FLAGS */
}
static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
@@ -3630,11 +3628,10 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
const uint32 smb_fmask,
int *stat_fflags)
{
-#ifdef HAVE_STAT_ST_FLAGS
uint32 max_fmask = 0;
int i;
- *stat_fflags = psbuf->st_flags;
+ *stat_fflags = psbuf->st_ex_flags;
/* For each flags requested in smb_fmask, check the state of the
* corresponding flag in smb_fflags and set or clear the matching
@@ -3660,9 +3657,6 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
}
return True;
-#else
- return False;
-#endif /* HAVE_STAT_ST_FLAGS */
}
@@ -3680,7 +3674,7 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
/* Create (birth) time 64 bit */
- put_long_date_timespec(pdata, get_create_timespec(psbuf, False));
+ put_long_date_timespec(pdata, psbuf->st_ex_btime);
pdata += 8;
map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
@@ -4101,7 +4095,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
if (!mode)
mode = FILE_ATTRIBUTE_NORMAL;
- nlink = sbuf.st_nlink;
+ nlink = sbuf.st_ex_nlink;
if (nlink && (mode&aDIR)) {
nlink = 1;
@@ -4195,9 +4189,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
dstart = pdata;
dend = dstart + data_size - 1;
- create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
- mtime_ts = get_mtimespec(&sbuf);
- atime_ts = get_atimespec(&sbuf);
+ create_time_ts = sbuf.st_ex_btime;
+ mtime_ts = sbuf.st_ex_mtime;
+ atime_ts = sbuf.st_ex_atime;
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
@@ -4454,8 +4448,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
BasicFileInformationTest. -tpot */
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
+ SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
+ SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
data_size = 8;
break;
@@ -4624,7 +4618,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_mode)) {
+ if(!S_ISLNK(sbuf.st_ex_mode)) {
reply_unixerror(req, ERRSRV,
ERRbadlink);
return;
@@ -4674,7 +4668,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- if (S_ISDIR(sbuf.st_mode)) {
+ 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);
} else {
@@ -4890,7 +4884,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
}
/* No links from a directory. */
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
status = NT_STATUS_FILE_IS_A_DIRECTORY;
goto out;
}
@@ -4935,12 +4929,12 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
/* get some defaults (no modifications) if any info is zero or -1. */
if (null_timespec(ft->atime)) {
- ft->atime= get_atimespec(psbuf);
+ ft->atime= psbuf->st_ex_atime;
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (null_timespec(ft->mtime)) {
- ft->mtime = get_mtimespec(psbuf);
+ ft->mtime = psbuf->st_ex_mtime;
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
@@ -4964,8 +4958,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
*/
{
- struct timespec mts = get_mtimespec(psbuf);
- struct timespec ats = get_atimespec(psbuf);
+ struct timespec mts = psbuf->st_ex_mtime;
+ struct timespec ats = psbuf->st_ex_atime;
if ((timespec_compare(&ft->atime, &ats) == 0) &&
(timespec_compare(&ft->mtime, &mts) == 0)) {
return NT_STATUS_OK;
@@ -5035,9 +5029,9 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
fname = fsp->fsp_name;
}
}
-
+
if (dosmode) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
dosmode |= aDIR;
} else {
dosmode &= ~aDIR;
@@ -6099,7 +6093,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
raw_unixmode = IVAL(pdata,84);
if (VALID_STAT(*psbuf)) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
ptype = PERM_EXISTING_DIR;
} else {
ptype = PERM_EXISTING_FILE;
@@ -6136,8 +6130,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
/* Ensure we don't try and change anything else. */
raw_unixmode = SMB_MODE_NO_CHANGE;
size = get_file_size_stat(psbuf);
- ft.atime = get_atimespec(psbuf);
- ft.mtime = get_mtimespec(psbuf);
+ ft.atime = psbuf->st_ex_atime;
+ ft.mtime = psbuf->st_ex_mtime;
/*
* We continue here as we might want to change the
* owner uid/gid.
@@ -6171,13 +6165,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* Deal with the UNIX specific uid set.
*/
- if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
+ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_ex_uid != set_owner)) {
int ret;
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for path %s\n",
(unsigned int)set_owner, fname ));
- if (S_ISLNK(psbuf->st_mode)) {
+ if (S_ISLNK(psbuf->st_ex_mode)) {
ret = SMB_VFS_LCHOWN(conn, fname, set_owner, (gid_t)-1);
} else {
ret = SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1);
@@ -6196,7 +6190,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* Deal with the UNIX specific gid set.
*/
- if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
+ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_ex_gid != set_grp)) {
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) {
@@ -7123,7 +7117,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
-
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
@@ -7150,7 +7143,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
-
+
return;
}
@@ -7253,7 +7246,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
reply_nterror(req, status);
return;
}
-
+
/* Try and set any given EA. */
if (ea_list) {
status = set_ea(conn, NULL, directory, ea_list);
@@ -7274,7 +7267,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7327,7 +7320,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn,
fnf_handle = 257;
send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7358,7 +7351,7 @@ static void call_trans2findnotifynext(connection_struct *conn,
SSVAL(params,2,0); /* No EA errors */
send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7508,7 +7501,7 @@ void reply_findnclose(struct smb_request *req)
END_PROFILE(SMBfindnclose);
return;
}
-
+
dptr_num = SVAL(req->vwv+0, 0);
DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
@@ -7928,7 +7921,7 @@ void reply_transs2(struct smb_request *req)
state->received_param += pcnt;
state->received_data += dcnt;
-
+
if ((state->received_data > state->total_data) ||
(state->received_param > state->total_param))
goto bad_param;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index f219e5554c..0f70669772 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -353,7 +353,7 @@ bool vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
if (SMB_VFS_STAT(conn,dname,st) != 0)
return(False);
- ret = S_ISDIR(st->st_mode);
+ ret = S_ISDIR(st->st_ex_mode);
if(!ret)
errno = ENOTDIR;
@@ -393,7 +393,7 @@ bool vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *
if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
return False;
- return(S_ISREG(sbuf->st_mode));
+ return(S_ISREG(sbuf->st_ex_mode));
}
/****************************************************************************
@@ -542,14 +542,14 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
if (ret == -1)
return ret;
- if (len == (uint64_t)st.st_size)
+ if (len == (uint64_t)st.st_ex_size)
return 0;
- if (len < (uint64_t)st.st_size) {
+ 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_size ));
+ fsp->fsp_name, (double)st.st_ex_size ));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
@@ -571,7 +571,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
if (!lp_strict_allocate(SNUM(fsp->conn)))
return 0;
- len -= st.st_size;
+ 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);
if (space_avail == (uint64_t)-1) {
@@ -579,7 +579,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
}
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_size, (double)len, (double)space_avail ));
+ fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail ));
if (len > space_avail) {
errno = ENOSPC;
@@ -639,12 +639,12 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
return ret;
}
- if (len <= st.st_size) {
+ if (len <= st.st_ex_size) {
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_size, (double)len, (double)(len - st.st_size)));
+ fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size)));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
@@ -659,8 +659,8 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
}
}
- offset = st.st_size;
- num_to_write = len - st.st_size;
+ offset = st.st_ex_size;
+ num_to_write = len - st.st_ex_size;
total = 0;
while (total < num_to_write) {
@@ -816,8 +816,8 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
&& (cache_value.data[cache_value.length-1] == '\0'));
if ((SMB_VFS_STAT(conn, (char *)cache_value.data, &st2) == 0)
- && (st.st_dev == st2.st_dev) && (st.st_ino == st2.st_ino)
- && (S_ISDIR(st.st_mode))) {
+ && (st.st_ex_dev == st2.st_ex_dev) && (st.st_ex_ino == st2.st_ex_ino)
+ && (S_ISDIR(st.st_ex_mode))) {
/*
* Ok, we're done
*/
@@ -973,7 +973,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
if (!lp_symlinks(SNUM(conn))) {
SMB_STRUCT_STAT statbuf;
if ( (SMB_VFS_LSTAT(conn,fname,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_mode)) ) {
+ (S_ISLNK(statbuf.st_ex_mode)) ) {
if (free_resolved_name) {
SAFE_FREE(resolved_name);
}
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 80ee3ec0e8..1664f9a94d 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -157,31 +157,35 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
printf("readdir: %s\n", dent->d_name);
if (VALID_STAT(st)) {
+ time_t tmp_time;
printf(" stat available");
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
+ if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n");
+ else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n");
+ else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n");
+ else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n");
+ else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n");
+ else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n");
+ else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n");
+ printf(" Size: %10u", (unsigned int)st.st_ex_size);
#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+ printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
#endif
#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+ printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (int)((st.st_mode) & 007777));
+ printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev);
+ printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+ printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+ printf(" Access: %05o", (int)((st.st_ex_mode) & 007777));
printf(" Uid: %5lu Gid: %5lu\n",
- (unsigned long)st.st_uid,
- (unsigned long)st.st_gid);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
+ (unsigned long)st.st_ex_uid,
+ (unsigned long)st.st_ex_gid);
+ tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+ printf(" Access: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+ printf(" Modify: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+ printf(" Change: %s", ctime(&tmp_time));
}
return NT_STATUS_OK;
@@ -540,6 +544,7 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
struct passwd *pwd = NULL;
struct group *grp = NULL;
SMB_STRUCT_STAT st;
+ time_t tmp_time;
if (argc != 2) {
printf("Usage: stat <fname>\n");
@@ -552,38 +557,41 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
return NT_STATUS_UNSUCCESSFUL;
}
- pwd = sys_getpwuid(st.st_uid);
+ pwd = sys_getpwuid(st.st_ex_uid);
if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
- grp = sys_getgrgid(st.st_gid);
+ grp = sys_getgrgid(st.st_ex_gid);
if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("stat: ok\n");
printf(" File: %s", argv[1]);
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
+ if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n");
+ else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n");
+ else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n");
+ else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n");
+ else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n");
+ else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n");
+ else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n");
+ printf(" Size: %10u", (unsigned int)st.st_ex_size);
#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+ printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
#endif
#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+ printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (int)((st.st_mode) & 007777));
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
+ printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev);
+ printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+ printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+ printf(" Access: %05o", (int)((st.st_ex_mode) & 007777));
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+ (unsigned long)st.st_ex_gid, group);
+ tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+ printf(" Access: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+ printf(" Modify: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+ printf(" Change: %s", ctime(&tmp_time));
return NT_STATUS_OK;
}
@@ -597,6 +605,7 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
struct passwd *pwd = NULL;
struct group *grp = NULL;
SMB_STRUCT_STAT st;
+ time_t tmp_time;
if (argc != 2) {
printf("Usage: fstat <fd>\n");
@@ -619,37 +628,40 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- pwd = sys_getpwuid(st.st_uid);
+ pwd = sys_getpwuid(st.st_ex_uid);
if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
- grp = sys_getgrgid(st.st_gid);
+ grp = sys_getgrgid(st.st_ex_gid);
if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("fstat: ok\n");
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
+ if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n");
+ else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n");
+ else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n");
+ else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n");
+ else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n");
+ else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n");
+ else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n");
+ printf(" Size: %10u", (unsigned int)st.st_ex_size);
#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+ printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
#endif
#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+ printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (int)((st.st_mode) & 007777));
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
+ printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev);
+ printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+ printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+ printf(" Access: %05o", (int)((st.st_ex_mode) & 007777));
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+ (unsigned long)st.st_ex_gid, group);
+ tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+ printf(" Access: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+ printf(" Modify: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+ printf(" Change: %s", ctime(&tmp_time));
return NT_STATUS_OK;
}
@@ -662,6 +674,7 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
struct passwd *pwd = NULL;
struct group *grp = NULL;
SMB_STRUCT_STAT st;
+ time_t tmp_time;
if (argc != 2) {
printf("Usage: lstat <path>\n");
@@ -673,37 +686,40 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- pwd = sys_getpwuid(st.st_uid);
+ pwd = sys_getpwuid(st.st_ex_uid);
if (pwd != NULL) user = pwd->pw_name;
else user = null_string;
- grp = sys_getgrgid(st.st_gid);
+ grp = sys_getgrgid(st.st_ex_gid);
if (grp != NULL) group = grp->gr_name;
else group = null_string;
printf("lstat: ok\n");
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
+ if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n");
+ else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n");
+ else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n");
+ else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n");
+ else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n");
+ else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n");
+ else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n");
+ printf(" Size: %10u", (unsigned int)st.st_ex_size);
#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+ printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
#endif
#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+ printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (int)((st.st_mode) & 007777));
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
+ printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev);
+ printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+ printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+ printf(" Access: %05o", (int)((st.st_ex_mode) & 007777));
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+ (unsigned long)st.st_ex_gid, group);
+ tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+ printf(" Access: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+ printf(" Modify: %s", ctime(&tmp_time));
+ tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+ printf(" Change: %s", ctime(&tmp_time));
return NT_STATUS_OK;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 41343cab87..b05ca44f0e 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -4135,8 +4135,12 @@ static bool run_opentest(int dummy)
static bool run_simple_posix_open_test(int dummy)
{
static struct cli_state *cli1;
- const char *fname = "\\posix:file";
- const char *dname = "\\posix:dir";
+ const char *fname = "posix:file";
+ const char *hname = "posix:hlink";
+ const char *sname = "posix:symlink";
+ const char *dname = "posix:dir";
+ char buf[10];
+ char namebuf[11];
uint16 major, minor;
uint32 caplow, caphigh;
uint16_t fnum1 = (uint16_t)-1;
@@ -4171,6 +4175,10 @@ static bool run_simple_posix_open_test(int dummy)
cli_posix_unlink(cli1, fname);
cli_setatr(cli1, dname, 0, 0);
cli_posix_rmdir(cli1, dname);
+ cli_setatr(cli1, hname, 0, 0);
+ cli_posix_unlink(cli1, hname);
+ cli_setatr(cli1, sname, 0, 0);
+ cli_posix_unlink(cli1, sname);
/* Create a directory. */
if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
@@ -4222,6 +4230,77 @@ static bool run_simple_posix_open_test(int dummy)
}
}
+ /* Create the file. */
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
+ printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Write some data into it. */
+ if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
+ printf("cli_write failed: %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ cli_close(cli1, fnum1);
+
+ /* Now create a hardlink. */
+ if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
+ printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Now create a symlink. */
+ if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
+ printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Open the hardlink for read. */
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
+ printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
+ printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (memcmp(buf, "TEST DATA\n", 10)) {
+ printf("invalid data read from hardlink\n");
+ goto out;
+ }
+
+ cli_close(cli1, fnum1);
+
+ /* Open the symlink for read - this should fail. A POSIX
+ client should not be doing opens on a symlink. */
+ if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
+ printf("POSIX open of %s succeeded (should have failed)\n", sname);
+ goto out;
+ } else {
+ if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
+ NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
+ printf("POSIX open of %s should have failed "
+ "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
+ "failed with %s instead.\n",
+ sname, cli_errstr(cli1));
+ goto out;
+ }
+ }
+
+ if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
+ printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (strcmp(namebuf, fname) != 0) {
+ printf("POSIX readlink on %s failed to match name %s (read %s)\n",
+ sname, fname, namebuf);
+ goto out;
+ }
+
if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
goto out;
@@ -4237,6 +4316,10 @@ static bool run_simple_posix_open_test(int dummy)
fnum1 = (uint16_t)-1;
}
+ cli_setatr(cli1, sname, 0, 0);
+ cli_posix_unlink(cli1, sname);
+ cli_setatr(cli1, hname, 0, 0);
+ cli_posix_unlink(cli1, hname);
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
cli_setatr(cli1, dname, 0, 0);
diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 69a41e30d9..6b0f70adfa 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -662,7 +662,7 @@ static int net_conf_addshare(struct net_context *c,
goto done;
}
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
d_fprintf(stderr,
"ERROR: path '%s' is not a directory.\n",
path);
diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c
index dadb88303b..992a03d813 100644
--- a/source3/utils/net_usershare.c
+++ b/source3/utils/net_usershare.c
@@ -250,13 +250,13 @@ static int get_share_list(TALLOC_CTX *ctx, const char *wcard, bool only_ours)
continue;
}
- if (!S_ISREG(sbuf.st_mode)) {
+ if (!S_ISREG(sbuf.st_ex_mode)) {
d_fprintf(stderr, "get_share_list: file %s is not a regular file. Ignoring.\n",
path );
continue;
}
- if (only_ours && sbuf.st_uid != myuid) {
+ if (only_ours && sbuf.st_ex_uid != myuid) {
continue;
}
@@ -364,7 +364,7 @@ static int info_fn(struct file_list *fl, void *priv)
return -1;
}
- if (!S_ISREG(sbuf.st_mode)) {
+ if (!S_ISREG(sbuf.st_ex_mode)) {
d_fprintf(stderr, "info_fn: file %s is not a regular file. Ignoring.\n",
basepath );
close(fd);
@@ -574,7 +574,7 @@ static int count_num_usershares(void)
continue;
}
- if (!S_ISREG(sbuf.st_mode)) {
+ if (!S_ISREG(sbuf.st_ex_mode)) {
d_fprintf(stderr, "count_num_usershares: file %s is not a regular file. Ignoring.\n",
path );
continue;
@@ -738,7 +738,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
return -1;
}
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
d_fprintf(stderr, "net usershare add: path %s is not a directory.\n",
us_path );
TALLOC_FREE(ctx);
@@ -749,7 +749,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
/* If we're not root, check if we're restricted to sharing out directories
that we own only. */
- if ((myeuid != 0) && lp_usershare_owner_only() && (myeuid != sbuf.st_uid)) {
+ if ((myeuid != 0) && lp_usershare_owner_only() && (myeuid != sbuf.st_ex_uid)) {
d_fprintf(stderr, "net usershare add: cannot share path %s as "
"we are restricted to only sharing directories we own.\n"
"\tAsk the administrator to add the line \"usershare owner only = false\" \n"
@@ -887,7 +887,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
return -1;
}
- if (!S_ISREG(sbuf.st_mode) || sbuf.st_dev != lsbuf.st_dev || sbuf.st_ino != lsbuf.st_ino) {
+ if (!S_ISREG(sbuf.st_ex_mode) || sbuf.st_ex_dev != lsbuf.st_ex_dev || sbuf.st_ex_ino != lsbuf.st_ex_ino) {
d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n",
full_path_tmp );
TALLOC_FREE(ctx);
diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index e8458fda1b..519eb6954a 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -60,7 +60,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
fprintf(stderr, "ERROR: lock directory %s does not exist\n",
lp_lockdir());
ret = 1;
- } else if ((st.st_mode & 0777) != 0755) {
+ } else if ((st.st_ex_mode & 0777) != 0755) {
fprintf(stderr, "WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
lp_lockdir());
ret = 1;
@@ -70,7 +70,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
fprintf(stderr, "ERROR: state directory %s does not exist\n",
lp_statedir());
ret = 1;
- } else if ((st.st_mode & 0777) != 0755) {
+ } else if ((st.st_ex_mode & 0777) != 0755) {
fprintf(stderr, "WARNING: state directory %s should have permissions 0755 for browsing to work\n",
lp_statedir());
ret = 1;
@@ -80,7 +80,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
fprintf(stderr, "ERROR: cache directory %s does not exist\n",
lp_cachedir());
ret = 1;
- } else if ((st.st_mode & 0777) != 0755) {
+ } else if ((st.st_ex_mode & 0777) != 0755) {
fprintf(stderr, "WARNING: cache directory %s should have permissions 0755 for browsing to work\n",
lp_cachedir());
ret = 1;
diff --git a/source3/web/cgi.c b/source3/web/cgi.c
index 261d4366bf..a31943fa8d 100644
--- a/source3/web/cgi.c
+++ b/source3/web/cgi.c
@@ -448,16 +448,16 @@ static void cgi_download(char *file)
"The requested file was not found");
}
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(st.st_ex_mode))
{
snprintf(buf, sizeof(buf), "%s/index.html", file);
- if (!file_exist_stat(buf, &st) || !S_ISREG(st.st_mode))
+ if (!file_exist_stat(buf, &st) || !S_ISREG(st.st_ex_mode))
{
cgi_setup_error("404 File Not Found","",
"The requested file was not found");
}
}
- else if (S_ISREG(st.st_mode))
+ else if (S_ISREG(st.st_ex_mode))
{
snprintf(buf, sizeof(buf), "%s", file);
}
@@ -496,7 +496,7 @@ static void cgi_download(char *file)
printf("Content-Language: %s\r\n", lang);
}
- printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
+ printf("Content-Length: %d\r\n\r\n", (int)st.st_ex_size);
while ((l=read(fd,buf,sizeof(buf)))>0) {
if (fwrite(buf, 1, l, stdout) != l) {
break;
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
index c097170d03..4aa229cd66 100644
--- a/source3/winbindd/idmap.c
+++ b/source3/winbindd/idmap.c
@@ -761,7 +761,7 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
struct idmap_domain *dom;
struct id_map *maps[2];
- DEBUG(10, ("idmap_backend_sid_to_unixid: domain = '%s', sid = [%s]\n",
+ DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
domain?domain:"NULL", sid_string_dbg(id->sid)));
maps[0] = id;
diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c
index 88ece8c7de..3d1dd488d6 100644
--- a/source3/winbindd/idmap_ldap.c
+++ b/source3/winbindd/idmap_ldap.c
@@ -765,7 +765,6 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
NTSTATUS ret;
struct idmap_ldap_context *ctx = NULL;
char *config_option = NULL;
- const char *range = NULL;
const char *tmp = NULL;
/* Only do init if we are online */
@@ -779,23 +778,63 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
return NT_STATUS_NO_MEMORY;
}
- config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
- if ( ! config_option) {
- DEBUG(0, ("Out of memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ if (strequal(dom->name, "*")) {
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
- /* load ranges */
- range = lp_parm_const_string(-1, config_option, "range", NULL);
- if (range && range[0]) {
- if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
- &ctx->filter_high_id) != 2) ||
- (ctx->filter_low_id > ctx->filter_high_id)) {
- DEBUG(1, ("ERROR: invalid filter range [%s]", range));
- ctx->filter_low_id = 0;
- ctx->filter_high_id = 0;
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ ctx->filter_low_id = low_uid;
+ ctx->filter_high_id = high_uid;
+ } else {
+ DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ if ((low_gid != low_uid) || (high_gid != high_uid)) {
+ DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
+ " ranges do not agree -- building "
+ "intersection\n"));
+ ctx->filter_low_id = MAX(ctx->filter_low_id,
+ low_gid);
+ ctx->filter_high_id = MIN(ctx->filter_high_id,
+ high_gid);
+ }
+ } else {
+ DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
+ }
+ } else {
+ const char *range = NULL;
+
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
}
+
+ /* load ranges */
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (range && range[0]) {
+ if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
+ &ctx->filter_high_id) != 2))
+ {
+ DEBUG(1, ("ERROR: invalid filter range [%s]", range));
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+ }
+ }
+
+ if (ctx->filter_low_id > ctx->filter_high_id) {
+ DEBUG(1, ("ERROR: invalid filter range [%u-%u]",
+ ctx->filter_low_id, ctx->filter_high_id));
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
}
if (params != NULL) {
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index 22c17578e6..c42cd74cbe 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -593,8 +593,8 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
{
NTSTATUS ret;
struct idmap_tdb_context *ctx;
- char *config_option = NULL;
- const char *range;
+
+ DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name));
ctx = talloc(dom, struct idmap_tdb_context);
if ( ! ctx) {
@@ -602,29 +602,72 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
return NT_STATUS_NO_MEMORY;
}
- config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
- if ( ! config_option) {
- DEBUG(0, ("Out of memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto failed;
- }
+ if (strequal(dom->name, "*")) {
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
- ret = idmap_tdb_open_db(ctx, false, &ctx->db);
- if ( ! NT_STATUS_IS_OK(ret)) {
- goto failed;
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ ctx->filter_low_id = low_uid;
+ ctx->filter_high_id = high_uid;
+ } else {
+ DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ if ((low_gid != low_uid) || (high_gid != high_uid)) {
+ DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
+ " ranges do not agree -- building "
+ "intersection\n"));
+ ctx->filter_low_id = MAX(ctx->filter_low_id,
+ low_gid);
+ ctx->filter_high_id = MIN(ctx->filter_high_id,
+ high_gid);
+ }
+ } else {
+ DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
+ }
+ } else {
+ char *config_option = NULL;
+ const char *range;
+
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (( ! range) ||
+ (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2))
+ {
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+
+ talloc_free(config_option);
}
- range = lp_parm_const_string(-1, config_option, "range", NULL);
- if (( ! range) ||
- (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
- (ctx->filter_low_id > ctx->filter_high_id)) {
+ if (ctx->filter_low_id > ctx->filter_high_id) {
ctx->filter_low_id = 0;
ctx->filter_high_id = 0;
}
+ DEBUG(10, ("idmap_tdb_db_init: filter range %u-%u loaded for domain "
+ "'%s'\n", ctx->filter_low_id, ctx->filter_high_id, dom->name));
+
+ ret = idmap_tdb_open_db(ctx, false, &ctx->db);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ goto failed;
+ }
+
dom->private_data = ctx;
- talloc_free(config_option);
return NT_STATUS_OK;
failed:
diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c
index b2723270eb..d34d289906 100644
--- a/source3/winbindd/idmap_tdb2.c
+++ b/source3/winbindd/idmap_tdb2.c
@@ -357,8 +357,6 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
{
NTSTATUS ret;
struct idmap_tdb2_context *ctx;
- char *config_option = NULL;
- const char *range;
NTSTATUS status;
status = idmap_tdb2_open_db();
@@ -370,24 +368,63 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
return NT_STATUS_NO_MEMORY;
}
- config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
- if ( ! config_option) {
- DEBUG(0, ("Out of memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto failed;
+ if (strequal(dom->name, "*")) {
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
+
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ ctx->filter_low_id = low_uid;
+ ctx->filter_high_id = high_uid;
+ } else {
+ DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ if ((low_gid != low_uid) || (high_gid != high_uid)) {
+ DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
+ " ranges do not agree -- building "
+ "intersection\n"));
+ ctx->filter_low_id = MAX(ctx->filter_low_id,
+ low_gid);
+ ctx->filter_high_id = MIN(ctx->filter_high_id,
+ high_gid);
+ }
+ } else {
+ DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
+ }
+ } else {
+ char *config_option = NULL;
+ const char *range;
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (( ! range) ||
+ (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2))
+ {
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+
+ talloc_free(config_option);
}
- range = lp_parm_const_string(-1, config_option, "range", NULL);
- if (( ! range) ||
- (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
- (ctx->filter_low_id > ctx->filter_high_id)) {
+ if (ctx->filter_low_id > ctx->filter_high_id) {
ctx->filter_low_id = 0;
ctx->filter_high_id = 0;
}
dom->private_data = ctx;
- talloc_free(config_option);
return NT_STATUS_OK;
failed:
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index e1ce223475..2b25616cf7 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1304,8 +1304,9 @@ int main(int argc, char **argv, char **envp)
* winbindd-specific resources we must free yet. JRA.
*/
- if (!reinit_after_fork(winbind_messaging_context(),
- winbind_event_context(), false)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
+ winbind_event_context(),
+ false))) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index a69d34f30c..6fb0b5857c 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1121,8 +1121,9 @@ bool winbindd_reinit_after_fork(const char *logfilename)
struct winbindd_domain *domain;
struct winbindd_child *cl;
- if (!reinit_after_fork(winbind_messaging_context(),
- winbind_event_context(), true)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
+ winbind_event_context(),
+ true))) {
DEBUG(0,("reinit_after_fork() failed\n"));
return false;
}
diff --git a/source4/autogen.sh b/source4/autogen.sh
index 8b97023073..2d995caeae 100755
--- a/source4/autogen.sh
+++ b/source4/autogen.sh
@@ -22,7 +22,12 @@ TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50 autoconf259 autoconf253"
AUTOHEADERFOUND="0"
AUTOCONFFOUND="0"
-
+if which which > /dev/null 2>&1; then
+ echo -n
+else
+ echo "$0: need 'which' to figure out if we have the right autoconf to build samba from git" >&2
+ exit 1
+fi
##
## Look for autoheader
##
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
index 0b5994bb88..5bed28b00c 100644
--- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -514,7 +514,7 @@ static int kludge_acl_init(struct ldb_module *module)
ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "partition: Unable to register control with rootdse!\n");
+ "kludge_acl: Unable to register control with rootdse!\n");
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/dsdb/samdb/ldb_modules/show_deleted.c b/source4/dsdb/samdb/ldb_modules/show_deleted.c
index d619558c21..b4f52d7cde 100644
--- a/source4/dsdb/samdb/ldb_modules/show_deleted.c
+++ b/source4/dsdb/samdb/ldb_modules/show_deleted.c
@@ -145,7 +145,7 @@ static int show_deleted_init(struct ldb_module *module)
ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID);
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "extended_dn: Unable to register control with rootdse!\n");
+ "show_deleted: Unable to register control with rootdse!\n");
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 1fdb744a84..585285795f 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -38,6 +38,7 @@
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "librpc/gen_ndr/netlogon.h"
+#include "libcli/security/security.h"
#include "auth/auth.h"
#include "auth/credentials/credentials.h"
#include "auth/auth_sam.h"
@@ -499,7 +500,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
struct hdb_ldb_private *p;
NTTIME acct_expiry;
+ NTSTATUS status;
+ uint32_t rid;
struct ldb_message_element *objectclasses;
struct ldb_val computer_val;
const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
@@ -580,49 +583,70 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
/* First try and figure out the flags based on the userAccountControl */
entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
- if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) {
- entry_ex->entry.flags.invalid = 0;
- entry_ex->entry.flags.server = 1;
- entry_ex->entry.flags.forwardable = 1;
- entry_ex->entry.flags.ok_as_delegate = 1;
- }
-
/* Windows 2008 seems to enforce this (very sensible) rule by
* default - don't allow offline attacks on a user's password
* by asking for a ticket to them as a service (encrypted with
* their probably patheticly insecure password) */
- if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) {
+ if (entry_ex->entry.flags.server
+ && lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) {
if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) {
entry_ex->entry.flags.server = 0;
}
}
- /* use 'whenCreated' */
- entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);
- /* use '???' */
- entry_ex->entry.created_by.principal = NULL;
+ {
+ /* These (created_by, modified_by) parts of the entry are not relevant for Samba4's use
+ * of the Heimdal KDC. They are stored in a the traditional
+ * DB for audit purposes, and still form part of the structure
+ * we must return */
+
+ /* use 'whenCreated' */
+ entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);
+ /* use '???' */
+ entry_ex->entry.created_by.principal = NULL;
+
+ entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
+ if (entry_ex->entry.modified_by == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ ret = ENOMEM;
+ goto out;
+ }
+
+ /* use 'whenChanged' */
+ entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0);
+ /* use '???' */
+ entry_ex->entry.modified_by->principal = NULL;
+ }
- entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
- if (entry_ex->entry.modified_by == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- ret = ENOMEM;
+
+ /* The lack of password controls etc applies to krbtgt by
+ * virtue of being that particular RID */
+ status = dom_sid_split_rid(NULL, samdb_result_dom_sid(mem_ctx, msg, "objectSid"), NULL, &rid);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = EINVAL;
goto out;
}
- /* use 'whenChanged' */
- entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0);
- /* use '???' */
- entry_ex->entry.modified_by->principal = NULL;
+ if (rid == DOMAIN_RID_KRBTGT) {
+ entry_ex->entry.valid_end = NULL;
+ entry_ex->entry.pw_end = NULL;
- entry_ex->entry.valid_start = NULL;
+ entry_ex->entry.flags.invalid = 0;
+ entry_ex->entry.flags.server = 1;
+ entry_ex->entry.flags.change_pw = 1;
+ entry_ex->entry.flags.client = 0;
+ entry_ex->entry.flags.forwardable = 1;
+ entry_ex->entry.flags.ok_as_delegate = 1;
+ } else if (entry_ex->entry.flags.server && ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) {
+ /* The account/password expiry only applies when the account is used as a
+ * client (ie password login), not when used as a server */
- /* The account/password expiry only applies when the account is used as a
- * client (ie password login), not when used as a server */
- if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT || ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) {
/* Make very well sure we don't use this for a client,
- * it could bypass the above password restrictions */
+ * it could bypass the password restrictions */
entry_ex->entry.flags.client = 0;
+
entry_ex->entry.valid_end = NULL;
entry_ex->entry.pw_end = NULL;
@@ -653,7 +677,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
*entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
}
}
-
+
+ entry_ex->entry.valid_start = NULL;
+
entry_ex->entry.max_life = NULL;
entry_ex->entry.max_renew = NULL;
diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c
index 06bfbf61ed..1898269c2c 100644
--- a/source4/lib/events/tevent_s4.c
+++ b/source4/lib/events/tevent_s4.c
@@ -42,7 +42,7 @@ static void ev_wrap_debug(void *context, enum tevent_debug_level level,
samba_level = 2;
break;
case TEVENT_DEBUG_TRACE:
- samba_level = 10;
+ samba_level = 50;
break;
};
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index 0c587e0905..6f127d8c39 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -39,7 +39,6 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char
{
int i;
- /* check if there's a paged request control */
if (req->controls != NULL) {
for (i = 0; req->controls[i]; i++) {
if (strcmp(oid, req->controls[i]->oid) == 0) {
@@ -59,7 +58,6 @@ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid
{
int i;
- /* check if there's a paged request control */
if (rep->controls != NULL) {
for (i = 0; rep->controls[i]; i++) {
if (strcmp(oid, rep->controls[i]->oid) == 0) {
@@ -75,7 +73,7 @@ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid
/* saves the current controls list into the "saver" and replace the one in req with a new one excluding
the "exclude" control */
-/* returns False on error */
+/* returns 0 on error */
int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
{
struct ldb_control **lcs;
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c
index 475b609e41..dd5afd868c 100644
--- a/source4/lib/ldb/modules/asq.c
+++ b/source4/lib/ldb/modules/asq.c
@@ -351,7 +351,7 @@ static int asq_search(struct ldb_module *module, struct ldb_request *req)
ldb = ldb_module_get_ctx(module);
- /* check if there's a paged request control */
+ /* check if there's an ASQ control */
control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID);
if (control == NULL) {
/* not found go on */
diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c
index 2a06c5e6c5..f2692305d5 100644
--- a/source4/lib/ldb/modules/paged_results.c
+++ b/source4/lib/ldb/modules/paged_results.c
@@ -408,7 +408,7 @@ static int paged_request_init(struct ldb_module *module)
ret = ldb_mod_register_control(module, LDB_CONTROL_PAGED_RESULTS_OID);
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
- "paged_request:"
+ "paged_results:"
"Unable to register control with rootdse!\n");
}
diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c
index 309101c32b..b4f76e1007 100644
--- a/source4/lib/ldb/modules/sort.c
+++ b/source4/lib/ldb/modules/sort.c
@@ -255,7 +255,7 @@ static int server_sort_search(struct ldb_module *module, struct ldb_request *req
ldb = ldb_module_get_ctx(module);
- /* check if there's a paged request control */
+ /* check if there's a server sort control */
control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID);
if (control == NULL) {
/* not found go on */
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 8d6ea04dc8..8c1a73b681 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -164,8 +164,11 @@ static void continue_socket(struct composite_context *creq)
struct smbcli_socket *sock;
struct smb2_transport *transport;
struct smb2_request *req;
- uint16_t dialects[3] = { SMB2_DIALECT_REVISION, SMB21_DIALECT_REVISION,
- SMB2_LONGHORN_BETA_DIALECT_REVISION };
+ uint16_t dialects[3] = {
+ SMB2_DIALECT_REVISION_000,
+ SMB2_DIALECT_REVISION_202,
+ SMB2_DIALECT_REVISION_210
+ };
c->status = smbcli_sock_connect_recv(creq, state, &sock);
if (!composite_is_ok(c)) return;
diff --git a/source4/libcli/smb2/smb2_constants.h b/source4/libcli/smb2/smb2_constants.h
index 86dfbfedbe..48f30972dc 100644
--- a/source4/libcli/smb2/smb2_constants.h
+++ b/source4/libcli/smb2/smb2_constants.h
@@ -68,10 +68,11 @@
#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
-/* the dialects we support */
-#define SMB2_DIALECT_REVISION 0x202
-#define SMB21_DIALECT_REVISION 0x210
-#define SMB2_LONGHORN_BETA_DIALECT_REVISION 0x0 /* early beta dialect */
+/* SMB2 negotiate dialects */
+#define SMB2_DIALECT_REVISION_000 0x0000 /* early beta dialect */
+#define SMB2_DIALECT_REVISION_202 0x0202
+#define SMB2_DIALECT_REVISION_210 0x0210
+#define SMB2_DIALECT_REVISION_2FF 0x02FF
/* SMB2 negotiate security_mode */
#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01
@@ -79,9 +80,14 @@
/* SMB2 capabilities - only 1 so far. I'm sure more will be added */
#define SMB2_CAP_DFS 0x00000001
+#define SMB2_CAP_LEASING 0x00000002 /* only in dialect 0x210 */
/* so we can spot new caps as added */
#define SMB2_CAP_ALL SMB2_CAP_DFS
+/* SMB2 session flags */
+#define SMB2_SESSION_FLAG_IS_GUEST 0x0001
+#define SMB2_SESSION_FLAG_IS_NULL 0x0002
+
/* SMB2 share flags */
#define SMB2_SHAREFLAG_MANUAL_CACHING 0x0000
#define SMB2_SHAREFLAG_AUTO_CACHING 0x0010
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index 17b5450a3e..454a9d144c 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -36,14 +36,14 @@ class SamDB(samba.Ldb):
"""The SAM database."""
def __init__(self, url=None, session_info=None, credentials=None,
- modules_dir=None, lp=None):
+ modules_dir=None, lp=None, options=None):
"""Open the Sam Database.
:param url: URL of the database.
"""
self.lp = lp
super(SamDB, self).__init__(session_info=session_info, credentials=credentials,
- modules_dir=modules_dir, lp=lp)
+ modules_dir=modules_dir, lp=lp, options=options)
glue.dsdb_set_global_schema(self)
if url:
self.connect(url)
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index c3399fdd48..5ac5624745 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -469,7 +469,6 @@ static const struct {
int protocol_level;
} supported_protocols[] = {
{"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2},
- {"SMB 2.001", "SMB2", reply_smb2, PROTOCOL_SMB2},
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
{"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 0b65a19634..f915392ffa 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -97,14 +97,21 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
NTSTATUS status;
struct timeval current_time;
struct timeval boot_time;
+ uint16_t i;
+ uint16_t dialect = 0;
/* we only do one dialect for now */
if (io->in.dialect_count < 1) {
return NT_STATUS_NOT_SUPPORTED;
}
- if (io->in.dialects[0] != 0 &&
- io->in.dialects[0] != SMB2_DIALECT_REVISION) {
- DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0]));
+ for (i=0; i < io->in.dialect_count; i++) {
+ dialect = io->in.dialects[i];
+ if (dialect == SMB2_DIALECT_REVISION_202) {
+ break;
+ }
+ }
+ if (dialect != SMB2_DIALECT_REVISION_202) {
+ DEBUG(0,("Got unexpected SMB2 dialect %u\n", dialect));
return NT_STATUS_NOT_SUPPORTED;
}
@@ -128,7 +135,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
req->smb_conn->smb2_signing_required = true;
break;
}
- io->out.dialect_revision = SMB2_DIALECT_REVISION;
+ io->out.dialect_revision = dialect;
io->out.capabilities = 0;
io->out.max_transact_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max transaction size", 0x10000);
@@ -281,7 +288,7 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
SSVAL(req->in.body, 0x02, 1);
memset(req->in.body+0x04, 0, 32);
- SSVAL(req->in.body, 0x24, 0);
+ SSVAL(req->in.body, 0x24, SMB2_DIALECT_REVISION_202);
smb2srv_negprot_recv(req);
return;