[PATCH] add restricted mode to sftp-server
Pavel Volkov
pavelivolkov at gmail.com
Wed Jun 5 04:03:48 EST 2013
Hi again. Attachment is lost in the mailing list. I'm sorry. I will
repeat them again in the body.
--- sftp-server.8.orig 2013-06-04 13:32:44.000000000 +0400
+++ sftp-server.8 2013-06-04 18:08:32.000000000 +0400
@@ -99,6 +99,13 @@
into a read-only mode.
Attempts to open files for writing, as well as other operations that change
the state of the filesystem, will be denied.
+.It Fl r
+Places this instance of
+.Nm
+into a restricted mode.
+Attempts to open files for writing, as well as other operations that change
+the state of the filesystem, will be denied if files already exist.
+Allows to resume via 'put' command for such program as winscp or
filezilla, or other.
.It Fl u Ar umask
Sets an explicit
.Xr umask 2
--- sftp-server.c.orig 2013-01-04 23:26:38.000000000 +0400
+++ sftp-server.c 2013-06-04 12:22:35.000000000 +0400
@@ -64,6 +64,9 @@
/* Disable writes */
int readonly;
+/* Disable change if file exist */
+int nochange=0;
+
/* portable attributes, etc. */
typedef struct Stat Stat;
@@ -533,6 +536,28 @@
buffer_free(&msg);
}
+static int
+fnochange(const char *name)
+{
+ const char *filepart = ".filepart";
+ char bname[PATH_MAX], *pbname;
+ struct stat st;
+
+ if(nochange) { /* nochange = 1 */
+ pbname=stpncpy(bname,name,sizeof(bname)-1);
+ bname[sizeof(bname)-1]='\0';
+ debug3("fnochange 1: bname=%s, length bname=%d", bname, strlen(bname));
+ if(strlen(name)>strlen(filepart)) {
+ pbname-=strlen(filepart);
+ debug3("fnochange 2: pbname=%s, length pbname=%d",
pbname, strlen(pbname));
+ if(bcmp(pbname,filepart,strlen(filepart))==0) *pbname='\0';
+ }
+ debug3("fnochange 3: bname=%s, length bname=%d", bname, strlen(bname));
+ if(lstat(bname,&st)!=-1) return 1;
+ }
+ return 0;
+}
+
static void
process_open(void)
{
@@ -550,7 +575,7 @@
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
- if (readonly &&
+ if ((readonly || (fnochange(name) && (flags != O_WRONLY))) &&
((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR))
status = SSH2_FX_PERMISSION_DENIED;
else {
@@ -762,7 +787,7 @@
name = get_string(NULL);
a = get_attrib();
debug("request %u: setstat name \"%s\"", id, name);
- if (readonly) {
+ if (readonly || fnochange(name)) {
status = SSH2_FX_PERMISSION_DENIED;
a->flags = 0;
}
@@ -954,7 +979,7 @@
name = get_string(NULL);
debug3("request %u: remove", id);
logit("remove name \"%s\"", name);
- if (readonly)
+ if (readonly || fnochange(name))
status = SSH2_FX_PERMISSION_DENIED;
else {
ret = unlink(name);
@@ -1000,7 +1025,7 @@
name = get_string(NULL);
debug3("request %u: rmdir", id);
logit("rmdir name \"%s\"", name);
- if (readonly)
+ if (readonly || fnochange(name))
status = SSH2_FX_PERMISSION_DENIED;
else {
ret = rmdir(name);
@@ -1050,7 +1075,7 @@
debug3("request %u: rename", id);
logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
status = SSH2_FX_FAILURE;
- if (readonly)
+ if (readonly || fnochange(oldpath))
status = SSH2_FX_PERMISSION_DENIED;
else if (lstat(oldpath, &sb) == -1)
status = errno_to_portable(errno);
@@ -1150,7 +1175,7 @@
newpath = get_string(NULL);
debug3("request %u: posix-rename", id);
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
- if (readonly)
+ if (readonly || fnochange(oldpath))
status = SSH2_FX_PERMISSION_DENIED;
else {
ret = rename(oldpath, newpath);
@@ -1362,7 +1387,7 @@
extern char *__progname;
fprintf(stderr,
- "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
+ "usage: %s [-ehRr] [-d start_directory] [-f log_facility] "
"[-l log_level]\n\t[-u umask]\n",
__progname);
exit(1);
@@ -1385,8 +1410,11 @@
pw = pwcopy(user_pw);
- while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehR")) != -1) {
+ while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehRr")) != -1) {
switch (ch) {
+ case 'r':
+ nochange = 1;
+ break;
case 'R':
readonly = 1;
break;
On Tue, Jun 4, 2013 at 6:46 PM, Pavel Volkov <pavelivolkov at gmail.com> wrote:
> Hello.
> These patches add a new mode of operation for the sftp server.
> It is located between the ordinary, unrestricted mode and read-only mode.
> It allows you to add files to the server, but only if these files do
> not exist on the server before.
> Changes to existing files - are prohibited.
> Please review them, maybe these patches will be useful not only to me.
> Thank you.
More information about the openssh-unix-dev
mailing list