Loading commands/auth/su.cpp +32 −1 Changes for commands/auth/su.cpp: 32 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading Loading
commands/auth/su.cpp +32 −1 Changes for commands/auth/su.cpp: 32 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading