Commit d08c1ab7 authored by jan.koester's avatar jan.koester
Browse files

test

parent fbbac469
Loading
Loading
Loading
Loading
+32 −1
Changes for commands/auth/su.cpp: 32 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -32,15 +32,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <unistd.h>
#include <cstdlib>
#include <grp.h>

#include "shell.h"
#include "authutil.h"

namespace fresh { namespace cmd {

    // Whether the calling user may use su at all: only members of group
    // "wheel" (primary gid, supplementary groups, or listed in
    // /etc/group.yaml's members -- login doesn't initgroups(), so the
    // member list is the authoritative one). No wheel group: nobody but
    // root.
    static bool callerInWheel(){
        struct group *gr=getgrnam("wheel");
        if(!gr) return false;
        gid_t wheel=gr->gr_gid;
        auth::PasswdEntry self;
        bool haveSelf=auth::lookupPasswdByUid(getuid(),self);
        if(haveSelf){
            for(char **m=gr->gr_mem;m && *m;++m)
                if(self.name==*m) return true;
            if(self.gid==wheel) return true;
        }
        if(getgid()==wheel || getegid()==wheel) return true;
        gid_t groups[256];
        int n=getgroups(256,groups);
        for(int i=0;i<n;++i)
            if(groups[i]==wheel) return true;
        return false;
    }

    // "su [-|-l|--login] [USERNAME]" (default USERNAME: root). Root
    // switching to any user needs no password (matches real su); anyone
    // else is prompted, verified the same way login verifies. "-"/"-l"
    // else must be in group wheel and is prompted, verified the same way
    // login verifies. "-"/"-l"
    // additionally chdir's to the target's home and resets HOME/USER/
    // LOGNAME/SHELL, i.e. a login shell rather than just a privilege swap
    // that keeps the caller's own environment/cwd.
@@ -57,6 +83,11 @@ namespace fresh { namespace cmd {
                else target=a;
            }

            if(getuid()!=0 && !callerInWheel()){
                std::cerr << "su: permission denied (not in group wheel)" << std::endl;
                return 1;
            }

            auth::PasswdEntry pe;
            if(!auth::lookupPasswd(target,pe)){
                std::cerr << "su: user " << target << " does not exist" << std::endl;