secutil.c
上传用户:ig0539
上传日期:2022-05-21
资源大小:181k
文件大小:3k
源码类别:

Ftp客户端

开发平台:

C/C++

  1. /*
  2.  * Part of Very Secure FTPd
  3.  * Licence: GPL v2
  4.  * Author: Chris Evans
  5.  * secutil.c
  6.  */
  7. #include "secutil.h"
  8. #include "str.h"
  9. #include "sysutil.h"
  10. #include "sysstr.h"
  11. #include "utility.h"
  12. #include "sysdeputil.h"
  13. void
  14. vsf_secutil_change_credentials(const struct mystr* p_user_str,
  15.                                const struct mystr* p_dir_str,
  16.                                const struct mystr* p_ext_dir_str,
  17.                                unsigned int caps, unsigned int options)
  18. {
  19.   struct vsf_sysutil_user* p_user;
  20.   if (!vsf_sysutil_running_as_root())
  21.   {
  22.     bug("vsf_secutil_change_credentials: not running as root");
  23.   }
  24.   p_user = str_getpwnam(p_user_str);
  25.   if (p_user == 0)
  26.   {
  27.     die2("cannot locate user entry:", str_getbuf(p_user_str));
  28.   }
  29.   {
  30.     struct mystr dir_str = INIT_MYSTR;
  31.     /* Work out where the chroot() jail is */
  32.     if (p_dir_str == 0 || str_isempty(p_dir_str))
  33.     {
  34.       str_alloc_text(&dir_str, vsf_sysutil_user_get_homedir(p_user));
  35.     }
  36.     else
  37.     {
  38.       str_copy(&dir_str, p_dir_str);
  39.     }
  40.     /* Sort out supplementary groups before the chroot(). We need to access
  41.      * /etc/groups
  42.      */
  43.     if (options & VSF_SECUTIL_OPTION_USE_GROUPS)
  44.     {
  45.       vsf_sysutil_initgroups(p_user);
  46.     }
  47.     else
  48.     {
  49.       vsf_sysutil_clear_supp_groups();
  50.     }
  51.     /* Always do the chdir() regardless of whether we are chroot()'ing */
  52.     {
  53.       /* Do chdir() with the target effective IDs to cater for NFS mounted
  54.        * home directories.
  55.        */
  56.       int saved_euid = 0;
  57.       int saved_egid = 0;
  58.       int retval;
  59.       if (options & VSF_SECUTIL_OPTION_CHANGE_EUID)
  60.       {
  61.         saved_euid = vsf_sysutil_geteuid();
  62.         saved_egid = vsf_sysutil_getegid();
  63.         vsf_sysutil_setegid(p_user);
  64.         vsf_sysutil_seteuid(p_user);
  65.       }
  66.       retval = str_chdir(&dir_str);
  67.       if (retval != 0)
  68.       {
  69.         die2("cannot change directory:", str_getbuf(&dir_str));
  70.       }
  71.       if (p_ext_dir_str && !str_isempty(p_ext_dir_str))
  72.       {
  73.         retval = str_chdir(p_ext_dir_str);
  74.         /* Failure on the extra directory is OK as long as we're not in
  75.          * chroot() mode
  76.          */
  77.         if (retval != 0 && !(options & VSF_SECUTIL_OPTION_CHROOT))
  78.         {
  79.           retval = 0;
  80.         }
  81.       }
  82.       if (retval != 0)
  83.       {
  84.         die2("cannot change directory:", str_getbuf(p_ext_dir_str));
  85.       }
  86.       if (options & VSF_SECUTIL_OPTION_CHANGE_EUID)
  87.       {
  88.         vsf_sysutil_seteuid_numeric(saved_euid);
  89.         vsf_sysutil_setegid_numeric(saved_egid);
  90.       }
  91.       /* Do the chroot() if required */
  92.       if (options & VSF_SECUTIL_OPTION_CHROOT)
  93.       {
  94.         vsf_sysutil_chroot(".");
  95.       }
  96.     }
  97.     str_free(&dir_str);
  98.   }
  99.   if (options & VSF_SECUTIL_OPTION_NO_FDS)
  100.   {
  101.     vsf_sysutil_set_no_fds();
  102.   }
  103.   /* Handle capabilities */
  104.   if (caps)
  105.   {
  106.     if (!vsf_sysdep_has_capabilities())
  107.     {
  108.       /* Need privilege but OS has no capabilities - have to keep root */
  109.       return;
  110.     }
  111.     if (!vsf_sysdep_has_capabilities_as_non_root())
  112.     {
  113.       vsf_sysdep_adopt_capabilities(caps);
  114.       return;
  115.     }
  116.     vsf_sysdep_keep_capabilities();
  117.   }
  118.   /* Set group id */
  119.   vsf_sysutil_setgid(p_user);
  120.   /* Finally set user id */
  121.   vsf_sysutil_setuid(p_user);
  122.   if (caps)
  123.   {
  124.     vsf_sysdep_adopt_capabilities(caps);
  125.   }
  126.   if (options & VSF_SECUTIL_OPTION_NO_PROCS)
  127.   {
  128.     vsf_sysutil_set_no_procs();
  129.   }
  130. }