Commit 7a6e4eae authored by jan.koester's avatar jan.koester
Browse files

tes

parent afd2b001
Loading
Loading
Loading
Loading
+4 −1
Changes for commands/auth/CMakeLists.txt: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ target_sources(fresh PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}/su.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/passwd.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/getty.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/useradd.cpp
)
target_include_directories(fresh PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

@@ -21,6 +22,8 @@ endif()
string(REGEX REPLACE "/+$" "" FRESH_PREFIX_NOSLASH "${CMAKE_INSTALL_PREFIX}")
target_compile_definitions(fresh PRIVATE FRESH_SU_PATH="${FRESH_PREFIX_NOSLASH}/bin/su")
add_executable(su ${CMAKE_CURRENT_SOURCE_DIR}/su_main.cpp)
# ids.h (UUID and GUID ids) lives in src/
target_include_directories(su PRIVATE ${CMAKE_SOURCE_DIR}/src)
if(HAVE_LIBCRYPT)
  target_link_libraries(su crypt)
endif()
@@ -28,4 +31,4 @@ install(TARGETS su DESTINATION bin
        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
                    WORLD_READ WORLD_EXECUTE SETUID)

set(FRESH_APPLETS ${FRESH_APPLETS} login passwd getty PARENT_SCOPE)
set(FRESH_APPLETS ${FRESH_APPLETS} login passwd getty useradd PARENT_SCOPE)
+9 −6
Changes for commands/auth/authutil.h: 9 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -53,15 +53,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pwd.h>
#include <shadow.h>

#include "ids.h"

namespace fresh { namespace auth {

    // uid and gid can be UUIDs and GUIDs (ids.h, user.yaml)
    struct PasswdEntry {
        std::string name,passwd,gecos,home,shell;
        uid_t uid=0;
        gid_t gid=0;
        uid_r_t uid=uid_r_legacy(0);
        gid_r_t gid=uid_r_legacy(0);
    };

    inline void fillFromPasswd(const struct passwd *pw,PasswdEntry &out){
    inline void fillFromPasswd(const struct passwd_id_r *pw,PasswdEntry &out){
        out.name=pw->pw_name;
        out.passwd=pw->pw_passwd;
        out.uid=pw->pw_uid;
@@ -72,14 +75,14 @@ namespace fresh { namespace auth {
    }

    inline bool lookupPasswd(const std::string &username,PasswdEntry &out){
        struct passwd *pw=getpwnam(username.c_str());
        struct passwd_id_r *pw=getpwnam_id_r(username.c_str());
        if(!pw) return false;
        fillFromPasswd(pw,out);
        return true;
    }

    inline bool lookupPasswdByUid(uid_t uid,PasswdEntry &out){
        struct passwd *pw=getpwuid(uid);
    inline bool lookupPasswdByUid(const uid_r_t &uid,PasswdEntry &out){
        struct passwd_id_r *pw=getpwuid_id_r(&uid);
        if(!pw) return false;
        fillFromPasswd(pw,out);
        return true;
+2 −1
Changes for commands/auth/login.cpp: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -88,7 +88,8 @@ namespace fresh { namespace cmd {
                return 1;
            }

            if(setgid(pe.gid)!=0 || setuid(pe.uid)!=0){
            // also UUID and GUID users, with their supplementary groups
            if(ids::becomeUser(pe.name.c_str(),pe.uid,pe.gid)!=0){
                std::cerr << "login: cannot switch to " << username << ": " << strerror(errno) << std::endl;
                return 1;
            }
+4 −3
Changes for commands/auth/passwd.cpp: 4 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ namespace fresh { namespace cmd {
                target=argv[1];
            }else{
                auth::PasswdEntry me;
                if(auth::lookupPasswdByUid(getuid(),me))
                if(auth::lookupPasswdByUid(ids::ruid(),me))
                    target=me.name;
            }
            if(target.empty()){
@@ -66,8 +66,9 @@ namespace fresh { namespace cmd {
                return 1;
            }

            if(geteuid()!=0){
                if(getuid()!=pe.uid){
            if(!ids::isRoot(ids::euid())){
                uid_r_t me=ids::ruid();
                if(!uid_r_eq(&me,&pe.uid)){
                    std::cerr << "passwd: permission denied" << std::endl;
                    return 1;
                }
+14 −14
Changes for commands/auth/suimpl.h: 14 added lines, 14 removed lines.
Original line number Diff line number Diff line
@@ -50,25 +50,24 @@ namespace fresh { namespace auth {

    // 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
    // /etc/group.yaml's members -- the member list counts even for a
    // session started before the user was added). No wheel group: nobody but
    // root.
    inline bool callerInWheel(){
        struct group *gr=getgrnam("wheel");
        struct group_id_r *gr=getgrnam_id_r("wheel");
        if(!gr) return false;
        gid_t wheel=gr->gr_gid;
        gid_r_t wheel=gr->gr_gid;
        PasswdEntry self;
        bool haveSelf=lookupPasswdByUid(getuid(),self);
        bool haveSelf=lookupPasswdByUid(ids::ruid(),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(uid_r_eq(&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;
        gid_r_t gid=ids::rgid(),egid=ids::egid();
        if(uid_r_eq(&gid,&wheel) || uid_r_eq(&egid,&wheel)) return true;
        for(const gid_r_t &g: ids::groups())
            if(uid_r_eq(&g,&wheel)) return true;
        return false;
    }

@@ -87,7 +86,8 @@ namespace fresh { namespace auth {
            else target=a;
        }

        if(getuid()!=0 && !callerInWheel()){
        bool callerIsRoot=ids::isRoot(ids::ruid());
        if(!callerIsRoot && !callerInWheel()){
            std::cerr << "su: permission denied (not in group wheel)" << std::endl;
            return 1;
        }
@@ -98,7 +98,7 @@ namespace fresh { namespace auth {
            return 1;
        }

        if(getuid()!=0){
        if(!callerIsRoot){
            std::string hash;
            if(!lookupShadowHash(target,hash))
                hash=pe.passwd;
@@ -112,7 +112,7 @@ namespace fresh { namespace auth {
        }

        // the target's own groups, not the caller's supplementary ones
        if(initgroups(pe.name.c_str(),pe.gid)!=0 || setgid(pe.gid)!=0 || setuid(pe.uid)!=0){
        if(ids::becomeUser(pe.name.c_str(),pe.uid,pe.gid)!=0){
            std::cerr << "su: cannot switch to " << target << ": " << strerror(errno) << std::endl;
            return 1;
        }
Loading