waycrate / swhkd

Sxhkd clone for Wayland (works on TTY and X11 too)
https://git.sr.ht/~shinyzenith/swhkd
BSD 2-Clause "Simplified" License
679 stars 47 forks source link

I think there is a mistake here, fn set_initgroups #208

Open planetoryd opened 1 year ago

planetoryd commented 1 year ago

https://github.com/waycrate/swhkd/blob/8377aaf92a3516c1e12741b0436346989681e0b6/swhkd/src/perms.rs#LL23C1-L23C54

The effect of using gecos is the same as using any random string as I tested, which gives only one group, clearing that list. I use username and it works then, which restores the actual groups I got when logging in.

Shinyzenith commented 1 year ago

I believe that entire file was written by angelo so I am not too well versed on it, If you can send a PR comparing the diffs that would be helpful.

planetoryd commented 1 year ago
pub fn drop_privs1(gi: Gid, ui: Uid) -> Result<()> {
    log::trace!("groups, {:?}", nix::unistd::getgroups()?);
    log::trace!("GID to {gi}");
    nix::unistd::setresgid(gi, gi, gi)?;
    let user = nix::unistd::User::from_uid(ui).unwrap().unwrap();
    set_initgroups(&user, gi.as_raw());
    log::trace!("UID to {ui}");
    nix::unistd::setresuid(ui, ui, ui)?;

    log::info!("dropped privs to resuid={ui} resgid={gi}");

    Ok(())
}

fn set_initgroups(user: &nix::unistd::User, gid: u32) {
    let gid = Gid::from_raw(gid);
    let s = user.name.clone();
    let c_str = CString::new(s).unwrap();
    match nix::unistd::initgroups(&c_str, gid) {
        std::result::Result::Ok(_) => log::debug!("Setting initgroups..."),
        Err(e) => {
            log::error!("Failed to set init groups: {:#?}", e);
            exit(1);
        }
    }
}

This is the code I use in my small tool. I don't really know much about the syscalls but I repeatedly experimented. That code always changes the grouplist to the 'default one' for the user regardless what it was before.

The code in swhkd gives me a grouplist with only one gid.