[SCM] Samba Shared Repository - branch v4-1-test updated

Karolin Seeger kseeger at samba.org
Fri Apr 4 15:08:05 MDT 2014


The branch, v4-1-test has been updated
       via  dadd863 s3: messages: Implement cleanup of dead records.
       via  bdd6da6 s3:libsmb: SMBC_getatr() if no method worked, try all methods again on next attempt
       via  4aa742a client: use cli_qpathinfo3 for allinfo
       via  0874ff2 s3:libsmb: cli_qpathinfo3 use cli_qpathinfo2 for smb2
       via  e98e835 client: remove a write only variable
       via  66115ff s3:libsmb: SMBC_getatr use pathinfo3 for second try
       via  0bea2d2 s3:libsmb: SMBC_getatr do not let ino undefined on success
       via  d15c014 s3:libsmb: SMBC_getatr try pathinfo2 only once
       via  976030c s3:libsmb: add function cli_qpathinfo3()
       via  f76511c s3:libsmb: add function cli_qpathinfo_standard()
       via  1f4b445 s3:libsmb: pass creation or birth time in cli_qpathinfo_basic()
       via  b1c6431 rpcclient: abort shadow-copy set on commit failure
       via  400e4f0 rpcclient: append a trailing slash to FSRVP request UNCs
       via  c9703c9 s3: smbd: Ensure we always go via getgroups_unix_user() when creating an NT token.
      from  34fcb4e lsa.idl: define lsa.ForestTrustCollisionInfo and ForestTrustCollisionRecord as public structs

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-1-test


- Log -----------------------------------------------------------------
commit dadd86364f300d952e3c6ad825c8da04a3f45e5d
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Apr 2 16:45:25 2014 -0700

    s3: messages: Implement cleanup of dead records.
    
    When a smbd process dies, pending messages.tdb records for this process
    might not get cleaned up. Implement a cleanup for dead records that is
    triggered after a smbd dies uncleanly; the records for that PID are
    deleted.
    
    Based on a patchset from Christof Schmitt <cs at samba.org>.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Christof Schmitt <cs at samba.org>
    
    (cherry picked from commit 837671f47670b16726aa96ba7a0902974a1037eb)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10534
    Cleanup messages.tdb record after unclean smbd shutdown
    
    Autobuild-User(v4-1-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-1-test): Fri Apr  4 23:07:07 CEST 2014 on sn-devel-104

commit bdd6da6d93689cd94d9b7f92e43f01f6cdbd58d9
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 18 15:32:55 2013 +0200

    s3:libsmb: SMBC_getatr() if no method worked, try all methods again on next attempt
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    The last 10 patches address bug #10230 - (lib)smbclient fails with NetApp.
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10230

commit 4aa742a3d374b578df73594336c79bb49fe11d83
Author: Gregor Beck <gbeck at sernet.de>
Date:   Mon Oct 14 11:44:36 2013 +0200

    client: use cli_qpathinfo3 for allinfo
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0874ff20b91f62a09173d25bc899a348426c9fd4
Author: Gregor Beck <gbeck at sernet.de>
Date:   Mon Oct 14 11:43:45 2013 +0200

    s3:libsmb: cli_qpathinfo3 use cli_qpathinfo2 for smb2
    
    cli_qpathinfo3 only works (and is only needed as fallback so far) for smb1.
    Use cli_qpathinfo2 in the smb2 case to make it universally usable.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e98e83558ef253cf2a380d8f1556254e3707f055
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 11:05:06 2013 +0200

    client: remove a write only variable
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 66115ff2b39d6ed732c2abf20f4d04d7e89326a1
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 11:02:24 2013 +0200

    s3:libsmb: SMBC_getatr use pathinfo3 for second try
    
    The pathinfo2 call might fail against NetApp because it is sending broken
    packages.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0bea2d23b3af7f2ac063a617c31a8371de7b5fcb
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 11:00:48 2013 +0200

    s3:libsmb: SMBC_getatr do not let ino undefined on success
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d15c014000fe3e215b48e45fdafbde4c7c810a91
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 10:59:59 2013 +0200

    s3:libsmb: SMBC_getatr try pathinfo2 only once
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 976030c70bb95dd2be1c22846d4a80b5b0c2ec98
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 10:53:45 2013 +0200

    s3:libsmb: add function cli_qpathinfo3()
    
    This is a reimplemantation of cli_qpathinfo2 without the use of info level
    SMB_QFILEINFO_ALL_INFO which leads to broken responses from NetApp.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f76511cb619db5918b48107d6c85088619767ff1
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 10:52:21 2013 +0200

    s3:libsmb: add function cli_qpathinfo_standard()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1f4b4452f523083b23b1f13e305716039716fd60
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 11 10:50:39 2013 +0200

    s3:libsmb: pass creation or birth time in cli_qpathinfo_basic()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b1c64310db7b1182e36678bdca372818b9b87846
Author: David Disseldorp <ddiss at samba.org>
Date:   Sat Mar 29 02:18:20 2014 +0100

    rpcclient: abort shadow-copy set on commit failure
    
    Use similar behaviour to the diskshadow.exe FSRVP client, which aborts
    the shadow-copy set if it receives a failed commit response.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Apr  1 00:54:06 CEST 2014 on sn-devel-104
    
    (cherry picked from commit d550acf24a8ec20e3e32891ed702c6cc42bc3dee)

commit 400e4f0c79c2ff520d71f770ef5818f3647324fb
Author: David Disseldorp <ddiss at samba.org>
Date:   Sat Mar 29 02:18:18 2014 +0100

    rpcclient: append a trailing slash to FSRVP request UNCs
    
    The Windows Server 2012 FSRVP server exhibits strange behaviour when
    exposing hidden shadow copy shares. If the hidden share UNC in the
    AddToShadowCopySet request includes a trailing backslash (e.g.
    "\\server\share$\"), then the new shadow-copy share will also be hidden
    (e.g. "\\server\share$@{ShadowCopy.ShadowCopyId}$").
    However, if the UNC does not include a trailing backslash, which until
    now was rpcclient's default behaviour, then the exposed shadow-copy
    share is not hidden.
    
    Thanks to the MS Open Specifications team for helping me track down this
    one.
    
    bug: https://bugzilla.samba.org/show_bug.cgi?id=10521
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit d9bc82d90d6c4425028e225cf470283dd3a98049)

commit c9703c96deaf8b08ed6d10db94585f4be45935bb
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 25 08:47:39 2014 -0700

    s3: smbd: Ensure we always go via getgroups_unix_user() when creating an NT token.
    
    This has to be done in every code path that creates
    an NT token, as remote users may have been added to
    the local /etc/group database. Tokens created merely
    from the info3 structs (via the DC or via the krb5 PAC)
    won't have these local groups.
    
    This code needs to special-case the guest user, as
    this token can have the token_sid[0] set to the Guest
    SID, not the mapping of UNIX uid -> SID.
    
    Other users that may have a well-known SID
    set in token_sid[0] (like SYSTEM) are usually
    not mappable to UNIX users and can be ignored
    when adding local groups from /etc/group.
    
    Combined back-port of fixes
    6034ab521c47fc5f4732398652c9c6847ff92035 and
    a9fa09723bee3588db2168ac13f7ad0334452c11 from
    master.
    
    https://bugzilla.samba.org/show_bug.cgi?id=10508
    
    Signed-off-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/auth/token_util.c         |  101 ++++++++++++++++++++++++++++++++++
 source3/client/client.c           |    7 +-
 source3/include/libsmb_internal.h |    1 +
 source3/include/messages.h        |    6 ++
 source3/lib/messages.c            |   17 ++++++
 source3/lib/messages_local.c      |   38 +++++++++++++
 source3/libsmb/clirap.c           |  110 +++++++++++++++++++++++++++++++++++++
 source3/libsmb/clirap.h           |   11 ++++
 source3/libsmb/libsmb_file.c      |   27 ++++++++-
 source3/libsmb/libsmb_server.c    |    1 +
 source3/rpcclient/cmd_fss.c       |   57 ++++++++++++++++---
 source3/smbd/server.c             |    7 ++
 12 files changed, 366 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c
index d86d589..be44ce9 100644
--- a/source3/auth/token_util.c
+++ b/source3/auth/token_util.c
@@ -389,6 +389,100 @@ struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
 	return result;
 }
 
+/***************************************************
+ Merge in any groups from /etc/group.
+***************************************************/
+
+static NTSTATUS add_local_groups(struct security_token *result,
+				 bool is_guest)
+{
+	gid_t *gids = NULL;
+	uint32_t getgroups_num_group_sids = 0;
+	struct passwd *pass = NULL;
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
+	int i;
+
+	if (is_guest) {
+		/*
+		 * Guest is a special case. It's always
+		 * a user that can be looked up, but
+		 * result->sids[0] is set to DOMAIN\Guest.
+		 * Lookup by account name instead.
+		 */
+		pass = Get_Pwnam_alloc(tmp_ctx, lp_guestaccount());
+	} else {
+		uid_t uid;
+
+		/* For non-guest result->sids[0] is always the user sid. */
+		if (!sid_to_uid(&result->sids[0], &uid)) {
+			/*
+			 * Non-mappable SID like SYSTEM.
+			 * Can't be in any /etc/group groups.
+			 */
+			TALLOC_FREE(tmp_ctx);
+			return NT_STATUS_OK;
+		}
+
+		pass = getpwuid_alloc(tmp_ctx, uid);
+		if (pass == NULL) {
+			DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
+				sid_string_dbg(&result->sids[0]),
+				(unsigned int)uid));
+		}
+	}
+
+	if (!pass) {
+		TALLOC_FREE(tmp_ctx);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	/*
+	 * Now we must get any groups this user has been
+	 * added to in /etc/group and merge them in.
+	 * This has to be done in every code path
+	 * that creates an NT token, as remote users
+	 * may have been added to the local /etc/group
+	 * database. Tokens created merely from the
+	 * info3 structs (via the DC or via the krb5 PAC)
+	 * won't have these local groups. Note the
+	 * groups added here will only be UNIX groups
+	 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
+	 * turns off winbindd before calling getgroups().
+	 *
+	 * NB. This is duplicating work already
+	 * done in the 'unix_user:' case of
+	 * create_token_from_sid() but won't
+	 * do anything other than be inefficient
+	 * in that case.
+	 */
+
+	if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
+			&gids, &getgroups_num_group_sids)) {
+		DEBUG(1, ("getgroups_unix_user for user %s failed\n",
+			pass->pw_name));
+		TALLOC_FREE(tmp_ctx);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	for (i=0; i<getgroups_num_group_sids; i++) {
+		NTSTATUS status;
+		struct dom_sid grp_sid;
+		gid_to_sid(&grp_sid, gids[i]);
+
+		status = add_sid_to_array_unique(result,
+					 &grp_sid,
+					 &result->sids,
+					 &result->num_sids);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
+			TALLOC_FREE(tmp_ctx);
+			return status;
+		}
+	}
+	TALLOC_FREE(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
 static NTSTATUS finalize_local_nt_token(struct security_token *result,
 					bool is_guest)
 {
@@ -396,6 +490,13 @@ static NTSTATUS finalize_local_nt_token(struct security_token *result,
 	gid_t gid;
 	NTSTATUS status;
 
+	/* Add any local groups. */
+
+	status = add_local_groups(result, is_guest);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/* Add in BUILTIN sids */
 
 	status = add_sid_to_array(result, &global_sid_World,
diff --git a/source3/client/client.c b/source3/client/client.c
index b4a3031..9d5cec9 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -1695,7 +1695,6 @@ static int do_allinfo(const char *name)
 	struct timespec b_time, a_time, m_time, c_time;
 	off_t size;
 	uint16_t mode;
-	SMB_INO_T ino;
 	NTTIME tmp;
 	uint16_t fnum;
 	unsigned int num_streams;
@@ -1722,8 +1721,8 @@ static int do_allinfo(const char *name)
 	}
 	d_printf("altname: %s\n", altname);
 
-	status = cli_qpathinfo2(cli, name, &b_time, &a_time, &m_time, &c_time,
-				&size, &mode, &ino);
+	status = cli_qpathinfo3(cli, name, &b_time, &a_time, &m_time, &c_time,
+				&size, &mode, NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("%s getting pathinfo for %s\n", nt_errstr(status),
 			 name);
@@ -1800,7 +1799,7 @@ static int do_allinfo(const char *name)
 		d_printf("%s\n", snapshots[i]);
 		snap_name = talloc_asprintf(talloc_tos(), "%s%s",
 					    snapshots[i], name);
-		status = cli_qpathinfo2(cli, snap_name, &b_time, &a_time,
+		status = cli_qpathinfo3(cli, snap_name, &b_time, &a_time,
 					&m_time, &c_time, &size,
 					NULL, NULL);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h
index 63c96fe..ce73181 100644
--- a/source3/include/libsmb_internal.h
+++ b/source3/include/libsmb_internal.h
@@ -78,6 +78,7 @@ struct _SMBCSRV {
 	dev_t dev;
 	bool no_pathinfo;
 	bool no_pathinfo2;
+	bool no_pathinfo3;
         bool no_nt_session;
         struct policy_handle pol;
 
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 12fc439..09c39cc 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -101,6 +101,9 @@ bool messaging_tdb_parent_init(TALLOC_CTX *mem_ctx);
 void *messaging_tdb_event(TALLOC_CTX *mem_ctx, struct messaging_context *msg,
 			  struct tevent_context *ev);
 
+NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx,
+			struct server_id pid);
+
 NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx,
 			      TALLOC_CTX *mem_ctx,
 			      struct messaging_backend **presult);
@@ -140,6 +143,9 @@ NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx,
 void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 			    struct messaging_rec *rec);
 
+void messaging_cleanup_server(struct messaging_context *msg_ctx,
+				struct server_id pid);
+
 #include "librpc/gen_ndr/ndr_messaging.h"
 
 #endif
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index f4d6227..cb78e22 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -397,4 +397,21 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 	return;
 }
 
+/*
+  Call when a process has terminated abnormally.
+*/
+void messaging_cleanup_server(struct messaging_context *msg_ctx,
+				struct server_id server)
+{
+	if (server_id_is_disconnected(&server)) {
+		return;
+	}
+
+	if (!procid_is_local(&server)) {
+		return;
+	}
+
+	(void)messaging_tdb_cleanup(msg_ctx, server);
+
+}
 /** @} **/
diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c
index 6b63d72..859eeb8 100644
--- a/source3/lib/messages_local.c
+++ b/source3/lib/messages_local.c
@@ -45,6 +45,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "messages.h"
+#include "serverid.h"
 #include "lib/tdb_wrap/tdb_wrap.h"
 #include "lib/param/param.h"
 
@@ -200,6 +201,43 @@ static TDB_DATA message_key_pid(TALLOC_CTX *mem_ctx, struct server_id pid)
 	return kbuf;
 }
 
+/*******************************************************************
+ Called when a process has terminated abnormally. Remove all messages
+ pending for it.
+******************************************************************/
+
+NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx,
+				struct server_id pid)
+{
+	struct messaging_tdb_context *ctx = talloc_get_type(
+					msg_ctx->local->private_data,
+					struct messaging_tdb_context);
+	struct tdb_wrap *tdb = ctx->tdb;
+	TDB_DATA key;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	key = message_key_pid(frame, pid);
+	/*
+	 * We have to lock the key to avoid
+	 * races in case the server_id was
+	 * re-used and is active (a remote
+	 * possibility, true). We only
+	 * clean up the database if we
+	 * know server_id doesn't exist
+	 * while checked under the chainlock.
+	 */
+	if (tdb_chainlock(tdb->tdb, key) != 0) {
+		TALLOC_FREE(frame);
+		return NT_STATUS_LOCK_NOT_GRANTED;
+	}
+	if (!serverid_exists(&pid)) {
+		(void)tdb_delete(tdb->tdb, key);
+	}
+	tdb_chainunlock(tdb->tdb, key);
+	TALLOC_FREE(frame);
+	return NT_STATUS_OK;
+}
+
 /*
   Fetch the messaging array for a process
  */
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index d6d2fae..7e6f8d7 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -1265,6 +1265,7 @@ NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
 		return status;
 	}
 
+	sbuf->st_ex_btime = interpret_long_date((char *)state->data);
 	sbuf->st_ex_atime = interpret_long_date((char *)state->data+8);
 	sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16);
 	sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24);
@@ -1362,3 +1363,112 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
 
 	return NT_STATUS_OK;
 }
+
+/****************************************************************************
+ Send a qpathinfo SMB_QUERY_FILE_STADNDARD_INFO call.
+****************************************************************************/
+
+NTSTATUS cli_qpathinfo_standard(struct cli_state *cli, const char *fname,
+				uint64_t *allocated, uint64_t *size,
+				uint32_t *nlinks,
+				bool *is_del_pending, bool *is_dir)
+{
+	uint8_t *rdata;
+	uint32_t num_rdata;
+	NTSTATUS status;
+
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	status = cli_qpathinfo(talloc_tos(), cli, fname,
+			       SMB_QUERY_FILE_STANDARD_INFO,
+			       24, CLI_BUFFER_SIZE, &rdata, &num_rdata);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (allocated) {
+		*allocated = BVAL(rdata, 0);
+	}
+
+	if (size) {
+		*size = BVAL(rdata, 8);
+	}
+
+	if (nlinks) {
+		*nlinks = IVAL(rdata, 16);
+	}
+
+	if (is_del_pending) {
+		*is_del_pending = CVAL(rdata, 20);
+	}
+
+	if (is_dir) {
+		*is_dir = CVAL(rdata, 20);
+	}
+
+	TALLOC_FREE(rdata);
+
+	return NT_STATUS_OK;
+}
+
+
+/* like cli_qpathinfo2 but do not use SMB_QUERY_FILE_ALL_INFO with smb1 */
+NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname,
+			struct timespec *create_time,
+			struct timespec *access_time,
+			struct timespec *write_time,
+			struct timespec *change_time,
+			off_t *size, uint16 *mode,
+			SMB_INO_T *ino)
+{
+	NTSTATUS status = NT_STATUS_OK;
+	SMB_STRUCT_STAT st;
+	uint32_t attr;
+	uint64_t pos;
+
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		return cli_qpathinfo2(cli, fname,
+				      create_time, access_time, write_time, change_time,
+				      size, mode, ino);
+	}
+
+	if (create_time || access_time || write_time || change_time || mode) {
+		status = cli_qpathinfo_basic(cli, fname, &st, &attr);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
+
+	if (size) {
+		status = cli_qpathinfo_standard(cli, fname,
+						NULL, &pos, NULL, NULL, NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+
+		*size = pos;
+	}
+
+	if (create_time) {
+		*create_time = st.st_ex_btime;
+	}
+	if (access_time) {
+		*access_time = st.st_ex_atime;
+	}
+	if (write_time) {
+		*write_time = st.st_ex_mtime;
+	}
+	if (change_time) {
+		*change_time = st.st_ex_ctime;
+	}
+	if (mode) {
+		*mode = attr;
+	}
+	if (ino) {
+		*ino = 0;
+	}
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/libsmb/clirap.h b/source3/libsmb/clirap.h
index e105182..54f06b4 100644
--- a/source3/libsmb/clirap.h
+++ b/source3/libsmb/clirap.h
@@ -82,6 +82,13 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
 			struct timespec *change_time,
 			off_t *size, uint16 *mode,
 			SMB_INO_T *ino);
+NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname,
+			struct timespec *create_time,
+			struct timespec *access_time,
+			struct timespec *write_time,
+			struct timespec *change_time,
+			off_t *size, uint16 *mode,
+			SMB_INO_T *ino);
 struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx,
 					      struct tevent_context *ev,
 					      struct cli_state *cli,
@@ -115,6 +122,10 @@ NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
 				  SMB_STRUCT_STAT *sbuf, uint32 *attributes);
 NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
 			     SMB_STRUCT_STAT *sbuf, uint32 *attributes);
+NTSTATUS cli_qpathinfo_standard(struct cli_state *cli, const char *fname,
+				uint64_t *allocated, uint64_t *size,
+				uint32_t *nlinks,
+				bool *is_del_pending, bool *is_dir);
 NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name);
 struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c
index 32210b6..8fb7a2e 100644
--- a/source3/libsmb/libsmb_file.c
+++ b/source3/libsmb/libsmb_file.c
@@ -558,11 +558,24 @@ SMBC_getatr(SMBCCTX * context,
 		return True;
         }
 
+	srv->no_pathinfo2 = True;
+
+	if (!srv->no_pathinfo3 &&
+            NT_STATUS_IS_OK(cli_qpathinfo3(targetcli, targetpath,
+                           create_time_ts,
+                           access_time_ts,
+                           write_time_ts,
+                           change_time_ts,
+			   size, mode, ino))) {
+		TALLOC_FREE(frame);
+		return True;
+        }
+
+	srv->no_pathinfo3 = True;
+
 	/* if this is NT then don't bother with the getatr */
 	if (smb1cli_conn_capabilities(targetcli->conn) & CAP_NT_SMBS) {
-                errno = EPERM;
-		TALLOC_FREE(frame);
-                return False;
+		goto all_failed;
         }
 
 	if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) {
@@ -581,11 +594,17 @@ SMBC_getatr(SMBCCTX * context,
                 if (change_time_ts != NULL) {
                         *change_time_ts = w_time_ts;
                 }
-		srv->no_pathinfo2 = True;
+		if (ino) {
+			*ino = 0;
+		}
 		TALLOC_FREE(frame);
 		return True;
 	}
 
+all_failed:
+	srv->no_pathinfo2 = False;
+	srv->no_pathinfo3 = False;
+
         errno = EPERM;
 	TALLOC_FREE(frame);
 	return False;
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 9e4ea5c..517753d 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -606,6 +606,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
 	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
         srv->no_pathinfo = False;
         srv->no_pathinfo2 = False;
+	srv->no_pathinfo3 = False;
         srv->no_nt_session = False;
 
 done:
diff --git a/source3/rpcclient/cmd_fss.c b/source3/rpcclient/cmd_fss.c
index af194e2..972fe9d 100644
--- a/source3/rpcclient/cmd_fss.c
+++ b/source3/rpcclient/cmd_fss.c
@@ -88,7 +88,7 @@ static NTSTATUS cmd_fss_is_path_sup(struct rpc_pipe_client *cli,
 	}
 
 	ZERO_STRUCT(r);
-	r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s",
+	r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s\\",
 					 cli->srv_name_slash, argv[1]);
 	if (r.in.ShareName == NULL) {
 		return NT_STATUS_NO_MEMORY;
@@ -187,8 +187,24 @@ static NTSTATUS cmd_fss_create_expose_parse(TALLOC_CTX *mem_ctx, int argc,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list