commit 0ef7291684441a423cc2aec3b22e165de2e8773a Author: southerntofu Date: Tue Jan 5 18:25:58 2021 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31063c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +.*.sw* diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fb9ef7d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "testsuid" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b2a908a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "testsuid" +version = "0.1.0" +authors = ["southerntofu "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..930d2b8 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# testsuid + +This program is a simple git wrapper intended to be used with suid/guid bits set to "impersonate" another user and let them clone a repository (with their consent, of course). + +When cloning the repository without initializing the submodules, everything works as expected. However, it appears git fails when cloning submodules when called from a suid program (the program uses `git clone --recursive`). + +How to reproduce: + +``` +$ git clone https://tildegit.org/southerntofu/testsuid +$ cd testsuid +$ cargo build --release +$ cp target/release/testsuid /tmp/testsuid +$ chmod u+s,g+s /tmp/testsuid +$ mkdir /tmp/dest/ +$ /tmp/testsuid "https://tildegit.org/tilde-fr/site" /tmp/dest/1 +Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/1 (recursive: false) +$ # SUCCESS +$ /tmp/testsuid --recursive "https://tildegit.org/tilde-fr/site" /tmp/dest/2 +Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/2 (recursive: true) +$ # SUCCESS +$ # Now let's try from a different user. +$ su guest +$ /tmp/testsuid "https://tildegit.org/tilde-fr/site" /tmp/dest/3 +Cloning https://tildegit.org/tilde-fr/site to /tmp/dest3 (recursive: false) +$ # SUCCESS +$ /tmp/testsuid --recursive "https://tildegit.org/tilde-fr/site" /tmp/dest/4 +Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/4 (recursive: true) +FAILED! +STDOUT: + +STDERR: +18:24:38.064467 git.c:418 trace: built-in: git clone --recursive https://tildegit.org/tilde-fr/site /tmp/dest/4 +Cloning into '/tmp/dest/4'... +18:24:38.070170 run-command.c:643 trace: run_command: git-remote-https origin https://tildegit.org/tilde-fr/site +18:24:38.621635 run-command.c:643 trace: run_command: git fetch-pack --stateless-rpc --stdin --lock-pack --thin --check-self-contained-and-connected --cloning --no-progress https://tildegit.org/tilde-fr/site/ +18:24:38.625704 git.c:418 trace: built-in: git fetch-pack --stateless-rpc --stdin --lock-pack --thin --check-self-contained-and-connected --cloning --no-progress https://tildegit.org/tilde-fr/site/ +18:24:38.820744 run-command.c:643 trace: run_command: git unpack-objects -q --pack_header=2,60 +18:24:38.823934 git.c:418 trace: built-in: git unpack-objects -q --pack_header=2,60 +18:24:38.840025 run-command.c:643 trace: run_command: git rev-list --objects --stdin --not --all --quiet +18:24:38.841075 git.c:418 trace: built-in: git rev-list --objects --stdin --not --all --quiet +warning: unable to access '/home/guest/.config/git/attributes': Permission denied +18:24:38.848734 run-command.c:643 trace: run_command: git submodule update --require-init --recursive +18:24:38.849745 git.c:669 trace: exec: git-submodule update --require-init --recursive +18:24:38.849789 run-command.c:643 trace: run_command: git-submodule update --require-init --recursive +18:24:38.857209 git.c:418 trace: built-in: git rev-parse --git-dir +18:24:38.858398 git.c:418 trace: built-in: git rev-parse --git-path objects +18:24:38.859289 git.c:418 trace: built-in: git rev-parse -q --git-dir +18:24:38.861442 git.c:418 trace: built-in: git rev-parse --show-prefix +18:24:38.862713 git.c:418 trace: built-in: git rev-parse --show-toplevel +18:24:38.864570 git.c:418 trace: built-in: git submodule--helper init +error: could not lock config file /tmp/dest/4/.git/config: Permission denied +fatal: Failed to register url for submodule path 'themes/water' +``` diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5cc45ac --- /dev/null +++ b/src/main.rs @@ -0,0 +1,68 @@ +use std::process::Command; + +fn help() { + eprintln!("testsuid [--recursive] REMOTE DESTINATION"); +} + +fn main() { + let args: Vec = std::env::args().collect(); + + let (recurse, source, dest) = match args.len() { + 0|1|2 => { + help(); + panic!(); + }, + 3 => { + ( + false, + args.get(1).unwrap(), + args.get(2).unwrap() + ) + }, + 4 => { + let recurse = args.get(1).unwrap(); + if ! (recurse == "--recursive" || recurse == "-r") { + eprintln!("You provided 3 arguments. The first one must be -r or --recursive."); + eprintln!("Otherwise, please give me only 2 arguments."); + help(); + panic!(); + } + ( + true, + args.get(2).unwrap(), + args.get(3).unwrap() + ) + }, + _ => { + help(); + panic!(); + } + }; + + println!("Cloning {} to {} (recursive: {})", source, dest, recurse); + + let output = if recurse { + Command::new("git") + .arg("clone") + .arg("--recursive") + .arg(source) + .arg(dest) + .env("GIT_TRACE", "1") + .output().expect("Failed to run process") + } else { + Command::new("git") + .arg("clone") + .arg(source) + .arg(dest) + .env("GIT_TRACE", "1") + .output().expect("Failed to run process") + }; + + if !output.status.success() { + println!("FAILED!"); + println!("STDOUT:"); + println!("{}", String::from_utf8_lossy(&output.stdout)); + println!("STDERR:"); + println!("{}", String::from_utf8_lossy(&output.stderr)); + } +}