[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    ftpd: support SITE CHMOD 0777 /path/to/file
From:       Aleksander Mazur <deweloper () wp ! pl>
Date:       2023-06-02 18:04:15
Message-ID: 20230602200415.254c5c3f () mocarz
[Download RAW message or body]

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


[Attachment #3 (text/x-patch)]

--- 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
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic