From ceed3cb3dea993e05d8651646213a94a6d1b5271 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Mon, 25 Sep 2017 12:57:37 -0700
Subject: [PATCH] Issue #593: If the IgnoreExtendedAttributes FSOption is used,
 then do not include the EXTENDED attribute flag in the SFTP ATTRS responses.

---
 contrib/mod_sftp/fxp.c | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

--- proftpd-dfsg.orig/contrib/mod_sftp/fxp.c
+++ proftpd-dfsg/contrib/mod_sftp/fxp.c
@@ -297,6 +297,8 @@
 static pool *fxp_pool = NULL;
 static int fxp_use_gmt = TRUE;
 
+/* FSOptions */
+static unsigned long fxp_fsio_opts = 0UL;
 static unsigned int fxp_min_client_version = 1;
 static unsigned int fxp_max_client_version = 6;
 static unsigned int fxp_utf8_protocol_version = 4;
@@ -7453,6 +7455,11 @@
     pr_trace_msg(trace_channel, 7, "received request: FSTAT %s", name);
     attr_flags = SSH2_FX_ATTR_SIZE|SSH2_FX_ATTR_UIDGID|SSH2_FX_ATTR_PERMISSIONS|
       SSH2_FX_ATTR_ACMODTIME;
+#ifdef PR_USE_XATTR
+    if (!(fxp_fsio_opts & PR_FSIO_OPT_IGNORE_XATTR)) {
+      attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    }
+#endif /* PR_USE_XATTR */
   }
 
   fxb = pcalloc(fxp->pool, sizeof(struct fxp_buffer));
@@ -7603,6 +7610,7 @@
   uint32_t buflen, bufsz;
   struct fxp_packet *resp;
   cmd_rec *cmd;
+  config_rec *c;
 
   fxp_session->client_version = sftp_msg_read_int(fxp->pool, &fxp->payload,
     &fxp->payload_sz);
@@ -7692,6 +7700,22 @@
 
   fxp_version_add_openssh_exts(fxp->pool, &buf, &buflen);
 
+  /* Look up the FSOptions here, for use later (Issue #593).  We do not need
+   * set these for the FSIO API; that is already done by mod_core.  Instead,
+   * we look them up for ourselves, for our own consumption/use.
+   */
+  c = find_config(main_server->conf, CONF_PARAM, "FSOptions", FALSE);
+  while (c != NULL) {
+    unsigned long opts = 0;
+
+    pr_signals_handle();
+
+    opts = *((unsigned long *) c->argv[0]);
+    fxp_fsio_opts |= opts;
+
+    c = find_config_next(c, c->next, CONF_PARAM, "FSOptions", FALSE);
+  }
+
   pr_event_generate("mod_sftp.sftp.protocol-version",
     &(fxp_session->client_version));
 
@@ -8142,7 +8166,9 @@
     attr_flags = SSH2_FX_ATTR_SIZE|SSH2_FX_ATTR_UIDGID|SSH2_FX_ATTR_PERMISSIONS|
       SSH2_FX_ATTR_ACMODTIME;
 #ifdef PR_USE_XATTR
-    attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    if (!(fxp_fsio_opts & PR_FSIO_OPT_IGNORE_XATTR)) {
+      attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    }
 #endif /* PR_USE_XATTR */
   }
 
@@ -10352,7 +10378,9 @@
      * to protocol version 6 clients.
      */
 #ifdef PR_USE_XATTR
-    attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    if (!(fxp_fsio_opts & PR_FSIO_OPT_IGNORE_XATTR)) {
+      attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    }
 #endif /* PR_USE_XATTR */
   }
 
@@ -12208,7 +12236,9 @@
     attr_flags = SSH2_FX_ATTR_SIZE|SSH2_FX_ATTR_UIDGID|SSH2_FX_ATTR_PERMISSIONS|
       SSH2_FX_ATTR_ACMODTIME;
 #ifdef PR_USE_XATTR
-    attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    if (!(fxp_fsio_opts & PR_FSIO_OPT_IGNORE_XATTR)) {
+      attr_flags |= SSH2_FX_ATTR_EXTENDED;
+    }
 #endif /* PR_USE_XATTR */
   }
 
