Hello all,
I was trying to setup a backup server for a number of machines, and for
a number of reasons ftp was choosen as the underlying tranfer protocol.
Since in this backup server from a ftp point of view I wanted to make
the files "immutable", but also i wanted the user to be able to create
new files under certain directories, i was looking ways to achieve it
with ftpd.
I didn't find an obvious solution, so i wrote a small patch that adds
the -p flag to ftpd and prevents the user from issueing the DELE
command. (i didn't like much using -p, but i couldn't think of anything
better).
Anyhow, i attach the patch, if anyone finds it useful. (flages,
suggestions, etc also welcomed ;) )
Best Regards,
Aristotelis
diff -Naur /usr/src/libexec/ftpd/ftpcmd.y ./ftpd/ftpcmd.y
--- /usr/src/libexec/ftpd/ftpcmd.y Thu Nov 5 16:43:15 2009
+++ ./ftpd/ftpcmd.y Tue Nov 10 16:50:04 2009
@@ -82,6 +82,7 @@
extern int portcheck;
extern union sockunion his_addr;
extern int umaskchange;
+extern int no_dele;
off_t restart_point;
@@ -394,10 +395,16 @@
}
| DELE check_login SP pathname CRLF
{
- if ($2 && $4 != NULL)
- delete($4);
- if ($4 != NULL)
- free($4);
+ if (no_dele) {
+ reply(550,
+ "No permission to delete files");
+ }
+ else {
+ if ($2 && $4 != NULL)
+ delete($4);
+ if ($4 != NULL)
+ free($4);
+ }
}
| RNTO check_login SP pathname CRLF
{
diff -Naur /usr/src/libexec/ftpd/ftpd.c ./ftpd/ftpd.c
--- /usr/src/libexec/ftpd/ftpd.c Thu Nov 5 16:43:16 2009
+++ ./ftpd/ftpd.c Tue Nov 10 16:51:13 2009
@@ -154,6 +154,7 @@
#endif
mode_t defumask = CMASK; /* default umask value */
int umaskchange = 1; /* allow user to change umask value. */
+int no_dele = 0 ; /* disallow ftp delete */
char tmpline[7];
char hostname[MAXHOSTNAMELEN];
char remotehost[MAXHOSTNAMELEN];
@@ -252,13 +253,13 @@
return (guest ? path+1 : path);
}
-char *argstr = "AdDhnlMSt:T:u:UvP46";
+char *argstr = "AdDhnlMSt:T:u:UvP46p";
static void
usage(void)
{
syslog(LOG_ERR,
- "usage: ftpd [-46ADdlMnPSU] [-T maxtimeout] [-t timeout] [-u
mask]");
+ "usage: ftpd [-46ADdlMnPSUp] [-T maxtimeout] [-t timeout] [-u
mask]");
exit(2);
}
@@ -371,7 +372,9 @@
case '6':
family = AF_INET6;
break;
-
+ case 'p':
+ no_dele = 1;
+ break;
default:
usage();
break;