3

We have a server that acts as a "dropbox" for (outside) users to upload data to us over sftp/ssh. We need to process these files (gpg decrypt, unzip, etc) as they come in. In the past, we simply processed each file in each users home directory without regard to whether we had already processed it. This turned out to be wasteful. I updated (rewrote) our processing script to rely on a mechanism like:

FILESTOPROCESS=$(find -H /home/$CUST -type f -newer /home/$CUST/marker-file)

This combined with a touch /home/$CUST/marker-file has worked great and our workload was dramatically reduced.

A day or so ago, we had a configuration issue in our SSH server which temporarily disallowed users to upload files to us. When the script ran again, it overlooked a file the user initially failed to upload, but subsequently uploaded via sftp/ssh with a "-p" option, for preserve timestamp. This set the c/a/mtimes of the file to be a day or so older than the marker-file and so it was subsequently ignored.

I'd like to disallow users from uploading with "-p" so that files are created with current timestamps.

Can I do this in sshd_config?

dmourati
  • 25,540
  • 2
  • 42
  • 72

4 Answers4

6

No, you cannot do this in the config. Looking through sftp-server.c, I see that the only way to disable this is to run sftp-server in read only mode, which is quite useless if you want to allow uploads :)

If you don't mind maintaining your own openssh package, you can remove the calls to utimes/futimes in sftp-server.c before compiling. Alternatively you can use an LD_PRELOAD library with noop implementations of these functions.

Dennis Kaarsemaker
  • 19,277
  • 2
  • 44
  • 70
  • I think it would be safer the LD_PRELOAD trick. – Mircea Vutcovici May 06 '13 at 21:22
  • It would be less maintenance, but patching things out in `sftp-server.c` sounds cleaner to me. – Dennis Kaarsemaker May 06 '13 at 21:24
  • This patch should go to upstream (openssh) and implemented to support a config option. – Mircea Vutcovici May 06 '13 at 21:26
  • @Mircea This is more a symptom of attempting to leverage the OpenSSH stack as a dedicated file transfer solution. It's not the design intent of the software at all, and there are always a handful of kludges you end up needing to make it behave the way you want in this context. – Andrew B May 09 '13 at 21:42
4

You can use incond (inotify cron daemon), to trigger a script when a file is added.

If you have a many uploaded files at once, you can queue the file names to be processed, then you can process the queue items one by one.

Mircea Vutcovici
  • 17,619
  • 4
  • 56
  • 83
2

You said that the ... "-p" option ... set the c/a/mtimes of the file ... - this is incorrect, as the ctime can only ever be set to the current time by changing the inode mtime or permissions (or other inode settings not relevant here).

With this knowledge, you can find unprocessed files using -cnewer.

$ FILESTOPROCESS=$(find -H /home/$CUST -type f \
   \( -newer /home/$CUST/marker-file -o \
      -cnewer /home/$CUST/marker-file \) )
PhilR
  • 483
  • 1
  • 4
  • 15
1

I don't know if (but I don't think that) you can accomplish this in sshd_config. However, here's an idea: What if you modified the processing script so that the files go into a temp directory first, you grab the hash (md5, perhaps) of the file, and compare that hash to the file with the same name in the user's directory (if such a file exists).

If the hash matches, then don't do anything (what's the point?)

If the hash doesn't match, then copy (don't move) the file from the temp directory into the final location (without the -p option, of course).

David W
  • 3,453
  • 5
  • 36
  • 62
  • It is better to check for modify timestamp and size of the file before checking the hash. – Mircea Vutcovici May 06 '13 at 21:20
  • Our previous script was a bit like this. It computed/checked the hash for all files and used rsync to copy the files into another temp directory. I tried to eliminate these steps with my marker-file. – dmourati May 06 '13 at 22:05