⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflprocu.imp

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 IMP
📖 第 1 页 / 共 2 页
字号:
      int SEAE_error = errcode;                                      \
      write (pipe_handle [1], &(SEAE_error), sizeof (SEAE_error));   \
      exit (EXIT_FAILURE);                                           \
    }

    /*  Sort out privileged issues immediately, to minimise the amount of    
     *  time we have more privilege than the program eventually run will     
     *  have.                                                                
     */

    /*  Force empty strings to be NULL strings, to simplify logic */
    if (! procinfo-> username || ! *(procinfo-> username))
        new_username = NULL;
    else
        new_username = procinfo-> username;
    if (! procinfo-> groupname || ! *(procinfo-> groupname))
        new_groupname = NULL;
    else
        new_groupname = procinfo-> groupname;

    ASSERT (new_username  == procinfo-> username  || ! *(procinfo-> username));
    ASSERT (new_groupname == procinfo-> groupname || ! *(procinfo-> groupname));

    if (new_username)
      {
        struct passwd
            *pwdbuf;                    /*  User information from passwd     */
        pwdbuf = getpwnam (new_username);
        if (pwdbuf)
          {
            new_uid = pwdbuf-> pw_uid;
            dosetuid = TRUE;
          }
        else
            SEND_ERROR_AND_EXIT (errno)
      }
    if (new_groupname)
      {
        struct group
            *grpbuf;                    /*  Group information                */
        grpbuf = getgrnam (new_groupname);
        if (grpbuf)
          {
            new_gid = grpbuf-> gr_gid;
            dosetgid = TRUE;
          }
        else
            SEND_ERROR_AND_EXIT (errno)
      }

    ASSERT ((new_username && dosetuid) || 
            (new_username == NULL && ! dosetuid));
    ASSERT ((new_groupname && dosetgid) || 
            (new_groupname == NULL && ! dosetgid));

    /*  HP/UX and BeOS don't provide seteuid() functions                     */
#   if (!defined (__UTYPE_HPUX) && !defined (__UTYPE_BEOS))      
    /*  If we are not to preserve root privileges, and won't otherwise be    
     *  setting the uid, then check to see if we can get root privileges now 
     *  (eg, we have them "saved").  If we do, force a setuid/setgid to      
     *  happen by setting the appropriate flags.
     */
    if (!(procinfo-> preserveroot)
    &&  !(dosetuid && dosetgid))
      {
        if (seteuid (0) == 0)
          {
            /* CAREFUL: We're root now; the seteuid worked.                  */

            /*  Arrange for setuid/setgid to happen to current real UID/GID. */
            dosetuid = TRUE;
            new_uid = getuid ();
            dosetgid = TRUE;
            new_gid = getgid ();
          }
       }
    
    /*  We first set the effective user to be root, to ensure that we can    
     *  carry out the requests.  If that fails, we give up immediately.      
     *  This means that the setuid() and setgid() calls will give up all     
     *  other privilege, which is deisred at this point.  To make use of     
     *  the saved uid/saved gid ability of some setuid()/setgid() calls,     
     *  use them prior to call create_process().  This is not recommended.   
     *  And chroot() will work only if the euid can be made root (0).        
     */
    if (procinfo-> rootdir != NULL
    ||  dosetgid || dosetuid)
      {
        if (seteuid (0) != 0)
            SEND_ERROR_AND_EXIT (errno);

        /*  CAUTION: We are now root.  Careful.                              */

        /*  Change root directory, if required                               */
        if (procinfo-> rootdir)
            if (chroot (procinfo-> rootdir) != 0)
                SEND_ERROR_AND_EXIT (errno);

        /*  Change uid and gid if required.  Since we are root at this point
         *  these functions should give away all our other gids and our
         *  original uid.                                                    
         */
        if (dosetgid)
          {
            if (setgid (new_gid) != 0)
                SEND_ERROR_AND_EXIT (errno);
            ASSERT (getgid () == new_gid);
          }
        if (dosetuid)
          {
            if (setuid (new_uid) != 0)
                SEND_ERROR_AND_EXIT (errno);
            ASSERT (getuid () == new_uid);
          }
      }

    /*  SANITY CHECK                                                         
     *  ----------------------------------------------------------------- 
     *  Unless we are preserving root, or explicitly set our uid to root,    
     *  we should no longer be root, and an attempt to set our euid to root  
     *  should fail.  If this turns out not to be the case, we give up       
     *  immediately.                                                         
     *  NOTE: Returning EPERM at this point is probably undesireable, but    
     *  it is not clear what would be better to return.                      
     */
    if (!(procinfo-> preserveroot)
    &&  !(dosetuid && new_uid == 0))
      {
        if (getuid () == 0 || geteuid () == 0)
            SEND_ERROR_AND_EXIT(EPERM); 

        if (seteuid (0) == 0)             /*  Should fail                    */
            SEND_ERROR_AND_EXIT(EPERM);

        ASSERT (geteuid () != 0 && getuid () != 0);
      }
#   endif

    /*  Now we are not root, unless the user really wanted us to be root.    */

#   include "sflprocx.imp"              /*  Get implementation core          */

    if (procinfo-> error)
        SEND_ERROR_AND_EXIT (procinfo-> error);

    /*  If requested, make this into a daemon process                        */
    if (procinfo-> createdaemon)
      {
        /*  XXX: Maybe we should have a lockfilename as well?                */
        if (process_server (procinfo-> workdir, NULL, 0, NULL, NULL) == -1)
            SEND_ERROR_AND_EXIT (errno);
      }
    else
    /*  If requested, change to working directory                            */
    if (procinfo-> workdir)
        if (chdir (procinfo-> workdir) == -1)
            SEND_ERROR_AND_EXIT (errno);

    /*  Mark extra file handles to close when we exec()                      */
    if (procinfo-> no_handles < FILEHANDLE_MAX)
      {
        int fh;
        for (fh = procinfo-> no_handles; fh < FILEHANDLE_MAX; fh++)
            fcntl (fh, F_SETFD, FD_CLOEXEC);         /*  Ignore errors       */
      }

    /*  Tell the system to close the pipe when we've done the exec()         */
    fcntl (pipe_handle [0], F_SETFD, FD_CLOEXEC);
    fcntl (pipe_handle [1], F_SETFD, FD_CLOEXEC);

    /*  Execute the program - normally this call does not return, as it      
     *  replaces the current process image by the new one.  If we ever do    
     *  return, it is because there was an error.
     */

    argv = arglist_to_table (arglist);
    if (! argv)
        SEND_ERROR_AND_EXIT (ENOMEM);

#if defined (DEBUG)
#if DEBUG > 1
    {
        char **ptr = argv;
        fprintf(stderr, "About to run: (%s) ", full_filename);
        while (*ptr != NULL)
            fprintf(stderr, "[%s] ", *ptr++);

        fprintf(stderr, "\n");

        errno = 0;
    }
#endif
#endif

    execve (full_filename, argv, envv);

    /*  If we're still here, then exec*() failed for some reason.  Tell our  
     *  parent about this.
     */
    SEND_ERROR_AND_EXIT (errno);


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -