<div>hi, I add Multiple user root  directory and access control for rtems,I have test it on my board, can somebody interesting about it and test more?</div><div><div>--- ./base/ftpd.c<span class="Apple-tab-span" style="white-space:pre">        </span>2016-03-11 11:39:41.752551200 +0800</div><div>+++ ./ftpd.c<span class="Apple-tab-span" style="white-space:pre">      </span>2016-07-21 16:10:59.308281000 +0800</div><div>@@ -189,7 +189,7 @@</div><div> #if HAVE_CONFIG_H</div><div> #include "config.h"</div><div> #endif</div><div>-</div><div>+ </div><div> #include <stdio.h></div><div> #include <stdlib.h></div><div> #include <string.h></div><div>@@ -266,6 +266,8 @@</div><div>   rtems_id            tid;         /* Task id */</div><div>   char                *user;       /* user name (0 if not supplied) */</div><div>   char                *pass;       /* password (0 if not supplied) */</div><div>+  int                 access;      /* access for session */</div><div>+  struct  rtems_ftpd_user_list *p_user;</div><div>   bool                auth;        /* true if user/pass was valid, false if not or not supplied */</div><div> } FTPD_SessionInfo_t;</div><div> </div><div>@@ -325,15 +327,15 @@</div><div>  */</div><div> </div><div> static int</div><div>-can_read(void)</div><div>+can_read(int access)</div><div> {</div><div>-  return (ftpd_access & FTPD_NO_READ) == 0;</div><div>+  return (access & FTPD_NO_READ) == 0;</div><div> }</div><div> </div><div> static int</div><div>-can_write(void)</div><div>+can_write(int access)</div><div> {</div><div>-  return (ftpd_access & FTPD_NO_WRITE) == 0;</div><div>+  return (access & FTPD_NO_WRITE) == 0;</div><div> }</div><div> </div><div> /*</div><div>@@ -783,7 +785,7 @@</div><div>   struct stat         stat_buf;</div><div>   int                 res = 0;</div><div> </div><div>-  if(!can_read() || !info->auth)</div><div>+  if(!can_read(info->access) || !info->auth)</div><div>   {</div><div>     send_reply(info, 550, "Access denied.");</div><div>     return;</div><div>@@ -927,7 +929,7 @@</div><div>   typedef ssize_t (*WriteProc)(int, void const*, size_t);</div><div>   WriteProc              wrt = &write;</div><div> </div><div>-  if(!can_write() || !info->auth)</div><div>+  if(!can_write(info->access) || !info->auth)</div><div>   {</div><div>     send_reply(info, 550, "Access denied.");</div><div>     return;</div><div>@@ -1667,6 +1669,33 @@</div><div>     *p++ = '\0';</div><div> }</div><div> </div><div>+</div><div>+/*find user list and chroot and set access mode for session*/</div><div>+static  void  check_user_access_ctrl(FTPD_SessionInfo_t *info)</div><div>+{</div><div>+    struct  rtems_ftpd_user_list   *p_head = info->p_user; </div><div>+    if((!info->user)||(!p_head))</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>return;</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>while(p_head->user)</div><div>+<span class="Apple-tab-span" style="white-space:pre">      </span>{</div><div>+       if(!strcmp(info->user,p_head->user))</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>   {</div><div>+          if((!p_head->pass)||(!info->pass)||</div><div>+<span class="Apple-tab-span" style="white-space:pre">                       </span>  (!strcmp(info->pass,p_head->pass)))</div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>  {     </div><div>+               info->access = p_head->access;</div><div>+               if((p_head->root)&& (p_head->root[0] == '/'))</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>   {</div><div>+<span class="Apple-tab-span" style="white-space:pre">                   </span>       chroot(p_head->root);<span class="Apple-tab-span" style="white-space:pre">                              </span>   </div><div>+<span class="Apple-tab-span" style="white-space:pre">                       </span>   }</div><div>+<span class="Apple-tab-span" style="white-space:pre">                   </span>   break;</div><div>+<span class="Apple-tab-span" style="white-space:pre">              </span>  }</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>   }</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>   p_head++;</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div>+}</div><div>+</div><div>+</div><div> /*</div><div>  * exec_command</div><div>  *</div><div>@@ -1688,6 +1717,7 @@</div><div> {</div><div>   char fname[FTPD_BUFSIZE];</div><div>   int wrong_command = 0;</div><div>+  </div><div> </div><div>   fname[0] = '\0';</div><div> </div><div>@@ -1755,7 +1785,10 @@</div><div>   {</div><div>     sscanf(args, "%254s", fname);</div><div>     if (info->user)</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div>       free(info->user);</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>  info->user = NULL;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>     if (info->pass)</div><div>       free(info->pass);</div><div>     info->pass = NULL;</div><div>@@ -1766,6 +1799,7 @@</div><div>       send_reply(info, 331, "User name okay, need password.");</div><div>     } else {</div><div>       info->auth = true;</div><div>+      check_user_access_ctrl(info);</div><div>       send_reply(info, 230, "User logged in.");</div><div>     }</div><div>   }</div><div>@@ -1784,13 +1818,14 @@</div><div>         send_reply(info, 530, "Not logged in.");</div><div>       } else {</div><div>         info->auth = true;</div><div>+        check_user_access_ctrl(info);</div><div>         send_reply(info, 230, "User logged in.");</div><div>       }</div><div>     }</div><div>   }</div><div>   else if (!strcmp("DELE", cmd))</div><div>   {</div><div>-    if(!can_write() || !info->auth)</div><div>+    if(!can_write(info->access) || !info->auth)</div><div>     {</div><div>       send_reply(info, 550, "Access denied.");</div><div>     }</div><div>@@ -1813,7 +1848,7 @@</div><div>     {</div><div>       int mask;</div><div> </div><div>-      if(!can_write() || !info->auth)</div><div>+      if(!can_write(info->access) || !info->auth)</div><div>       {</div><div>         send_reply(info, 550, "Access denied.");</div><div>       }</div><div>@@ -1832,7 +1867,7 @@</div><div>   }</div><div>   else if (!strcmp("RMD", cmd))</div><div>   {</div><div>-    if(!can_write() || !info->auth)</div><div>+    if(!can_write(info->access) || !info->auth)</div><div>     {</div><div>       send_reply(info, 550, "Access denied.");</div><div>     }</div><div>@@ -1849,7 +1884,7 @@</div><div>   }</div><div>   else if (!strcmp("MKD", cmd))</div><div>   {</div><div>-    if(!can_write() || !info->auth)</div><div>+    if(!can_write(info->access) || !info->auth)</div><div>     {</div><div>       send_reply(info, 550, "Access denied.");</div><div>     }</div><div>@@ -1907,7 +1942,11 @@</div><div>   int chroot_made = 0;</div><div> </div><div>   rtems_libio_set_private_env();</div><div>-</div><div>+  </div><div>+  /*add list for individual user access control*/</div><div>+  info->p_user = rtems_ftpd_configuration.user_ctrl_list;</div><div>+  info->access = rtems_ftpd_configuration.access; </div><div>+  </div><div>   /* chroot() can fail here because the directory may not exist yet. */</div><div>   chroot_made = chroot(ftpd_root) == 0;</div><div> </div></div><div><div>--- ./base/ftpd.h<span class="Apple-tab-span" style="white-space:pre">    </span>2016-03-11 11:39:41.760052200 +0800</div><div>+++ ./ftpd.h<span class="Apple-tab-span" style="white-space:pre">      </span>2016-07-21 16:11:02.474638800 +0800</div><div>@@ -6,7 +6,7 @@</div><div> #define _RTEMS_FTPD_H</div><div> </div><div> #include <rtems/rtems/tasks.h></div><div>-</div><div>+ </div><div> #ifdef __cplusplus</div><div> extern "C" {</div><div> #endif</div><div>@@ -38,6 +38,18 @@</div><div>    rtems_ftpd_hookfunction hook_function;</div><div> };</div><div> </div><div>+</div><div>+/*add  more lever control access for different user and password*/</div><div>+</div><div>+struct  rtems_ftpd_user_list</div><div>+{</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>char const *root;</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>char const *user;</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>char const *pass;</div><div>+    int         access;</div><div>+};</div><div>+</div><div>+</div><div> struct rtems_ftpd_configuration</div><div> {</div><div>    rtems_task_priority     priority;           /* FTPD task priority  */</div><div>@@ -54,6 +66,7 @@</div><div>                                                   3 - browse-only */</div><div>    rtems_shell_login_check_t login;            /* Login check or 0 to ignore</div><div>                                                   user/passwd. */</div><div>+   struct  rtems_ftpd_user_list   *user_ctrl_list;</div><div> };</div><div> </div><div> /*</div></div><div><br></div><div><br></div><div><br></div><div><br></div><div>usage example:</div><div><br></div><div><div>#define INCLUDE_FTPD_MULT_USER_ACCESS_CTRL</div><div>#define  DEFAULT_FTPD_USER   "admin"</div><div>#define  DEFAULT_FTPD_PASS    "123"</div><div>#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL</div><div>static struct rtems_ftpd_user_list rtems_ftpd_user_ctrl_list[] =</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>{<span class="Apple-tab-span" style="white-space:pre">   </span>"/", "admin", "admin", 0}, /*admin user for access all*/</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>{<span class="Apple-tab-span" style="white-space:pre">   </span>"/mnt/data", "read", "read", 1}, /*read user for read /mnt/data only*/</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{<span class="Apple-tab-span" style="white-space:pre">   </span>"/mnt/etc", "look", "look", 3}, /* look user for brower etc only*/</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>{<span class="Apple-tab-span" style="white-space:pre">   </span>"/mnt", "mine", "mine", 0}, /*mine user for access /mnt only*/</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{<span class="Apple-tab-span" style="white-space:pre">   </span>0, 0, 0, 0},};</div><div>#endif</div><div>static bool rtems_ftpd_login_check(const char *user, const char *passphrase)</div><div>{</div><div>#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>struct rtems_ftpd_user_list *p_head = rtems_ftpd_user_ctrl_list;</div><div>#endif</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if ((user == NULL) || (passphrase == NULL))</div><div><span class="Apple-tab-span" style="white-space:pre">          </span>return false;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">       </span>if ((!strcmp(user, DEFAULT_FTPD_USER))</div><div><span class="Apple-tab-span" style="white-space:pre">                       </span>&& (!strcmp(passphrase, DEFAULT_FTPD_PASS)))</div><div><span class="Apple-tab-span" style="white-space:pre">         </span>return true;</div><div>#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>while (p_head->user)</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">            </span>if ((!strcmp(user, p_head->user))</div><div><span class="Apple-tab-span" style="white-space:pre">                         </span>&& (!strcmp(passphrase, p_head->pass)))</div><div><span class="Apple-tab-span" style="white-space:pre">           </span>return true;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>p_head++;</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div>#endif</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>return false;</div><div>}</div><div><br></div><div>/************************************************************************************************</div><div> * ftpd support</div><div> */</div><div><br></div><div>struct rtems_ftpd_configuration rtems_ftpd_configuration =</div><div>{ .priority = 199, .max_hook_filesize = 32768, .port = 21, .hooks = 0, .root =</div><div><span class="Apple-tab-span" style="white-space:pre">              </span>"/mnt", .tasks_count = 4, .idle = 60, .access = 0, .login =0,</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>//<span class="Apple-tab-span" style="white-space:pre">  </span>rtems_ftpd_login_check,</div><div>#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL</div><div>        .user_ctrl_list = rtems_ftpd_user_ctrl_list</div><div>#endif</div><div>};</div><div><br></div><div>void net_ftpd_init(void)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>rtems_initialize_ftpd();</div><div>}</div></div><div><br></div><div><br></div><div><br></div>