Hi,
This patch allows changing file permissions via ftp.
Mode is limited to octal values (no a+rwx etc.) and just access permissions
(0777, no suid), like in vsftpd.
Verified with following FTP clients: Midnight Commander, ncftp (in the latter
case explicit chmod command is needed).
Without this patch the executable bit is lost and you have to recover
permissions of uploaded files on your own.
function old new delta
ftpd_main 2061 2280 +219
.rodata 33114 33120 +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 225/0) Total: 225 bytes
text data bss dec hex filename
300584 1331 1212 303127 4a017 busybox_old
300809 1331 1212 303352 4a0f8 busybox_unstripped
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -92,6 +92,7 @@
#define FTP_PORTOK 200
#define FTP_STRUOK 200
#define FTP_MODEOK 200
+#define FTP_SITEOK 200
#define FTP_ALLOOK 202
#define FTP_STATOK 211
#define FTP_STATFILE_OK 213
@@ -118,6 +119,7 @@
#define FTP_BADSENDNET 426
#define FTP_BADSENDFILE 451
#define FTP_BADCMD 500
+#define FTP_BADARG 501
#define FTP_COMMANDNOTIMPL 502
#define FTP_NEEDUSER 503
#define FTP_NEEDRNFR 503
@@ -1031,6 +1033,50 @@
G.restart_pos = 0;
handle_upload_common(0, 1);
}
+
+static void
+handle_site_chmod(const char *site_args)
+{
+ /* example site_args: 0755 /path/to/file */
+ char *path = site_args ? strchr(site_args, ' ') : NULL;
+ unsigned long mode;
+ char *e;
+
+ if (!path) {
+ WRITE_ERR(FTP_BADCMD);
+ return;
+ }
+ *path++ = '\0';
+ /* support octal mask only - like vsftpd (no stat+bb_parse_mode) */
+ mode = strtoul(site_args, &e, 8);
+ if (*e || (mode > 07777U)) {
+ WRITE_ERR(FTP_BADARG);
+ return;
+ }
+ /* mask mode to just access permissions like vsftpd (no suid) */
+ if (chmod(path, mode & 0777)) {
+ WRITE_ERR(FTP_FILEFAIL);
+ return;
+ }
+ WRITE_OK(FTP_SITEOK);
+}
+
+static void
+handle_site(void)
+{
+ if (G.ftp_arg) {
+ /* e.g. CHMOD 0755 /path/to/file */
+ char *site_cmd = G.ftp_arg;
+ char *site_arg = strchr(site_cmd, ' ');
+
+ if (site_arg)
+ *site_arg++ = '\0';
+ if (!strcasecmp(site_cmd, "chmod"))
+ return handle_site_chmod(site_arg);
+ }
+
+ WRITE_ERR(FTP_BADCMD);
+}
#endif /* ENABLE_FEATURE_FTPD_WRITE */
static uint32_t
@@ -1157,6 +1203,7 @@
const_SYST = mk_const4('S', 'Y', 'S', 'T'),
const_TYPE = mk_const4('T', 'Y', 'P', 'E'),
const_USER = mk_const4('U', 'S', 'E', 'R'),
+ const_SITE = mk_const4('S', 'I', 'T', 'E'),
#if !BB_MMU
OPT_l = (1 << 0),
@@ -1451,6 +1498,8 @@
handle_appe();
else if (cmdval == const_STOU) /* "store unique" */
handle_stou();
+ else if (cmdval == const_SITE)
+ handle_site();
else
goto bad_cmd;
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox