-
-
Save AlekSi/5317326 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a dead simple wrapper that can have setuid set on it so that | |
// the sudo helper is run as root. It is expected to run in the same CWD | |
// as the actual Ruby sudo helper. Any arguments to this script are forwarded | |
// to the Ruby sudo helper script. | |
package main | |
import ( | |
"log" | |
"os" | |
"path/filepath" | |
"syscall" | |
) | |
const sudoHelperCommand = "vagrant_vmware_desktop_sudo_helper" | |
func main() { | |
log.SetFlags(0) | |
// We need to be running as root to properly setuid and execute | |
// the sudo helper as root. | |
if os.Geteuid() != 0 { | |
log.Fatalln("sudo helper setuid-wrapper must run as root.") | |
} | |
// We have to setuid here because suid bits only change the EUID, | |
// and when Ruby sees the EUID != RUID, it resets the EUID back to RUID, | |
// nullifying the change we actually want. This forces the script to | |
// run as root. | |
if err := syscall.Setuid(0); err != nil { | |
log.Fatalln(err) | |
} | |
// Put together the complete path to the helper program. | |
helperPath := filepath.Join(filepath.Dir(os.Args[0]), sudoHelperCommand) | |
// Setup the argv array so that the arguments are preserved for the | |
// helper, while also adding our arguments so the helper is properly called. | |
helperArgs := make([]string, len(os.Args)+1) | |
helperArgs[0] = "ruby" | |
helperArgs[1] = helperPath | |
copy(helperArgs[2:], os.Args[1:]) | |
// Replace ourselves with the actual helper. This should terminate | |
// execution of this program, but if not we output and exit. | |
if err := syscall.Exec("ruby", helperArgs, os.Environ()); err != nil { | |
log.Fatalf("Exec error: %s\n", err) | |
} | |
panic("not reached") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Vagrant VMWare Fusion Sudo Helper Wrapper | |
* | |
* This is a dead simple wrapper that can have setuid set on it so that | |
* the sudo helper is run as root. It is expected to run in the same CWD | |
* as the actual Ruby sudo helper. Any arguments to this script are forwarded | |
* to the Ruby sudo helper script. | |
* */ | |
#include <errno.h> | |
#include <libgen.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#define HELPER_PATH_MAX 4096 | |
#define SUDO_HELPER_COMMAND "vagrant_vmware_fusion_sudo_helper" | |
int main(int argc, char *argv[]) { | |
// We need to be running as root to properly setuid and execute | |
// the sudo helper as root. | |
if (geteuid() != 0) { | |
fprintf(stderr, "sudo helper setuid-wrapper must run as root\n"); | |
return 1; | |
} | |
// Put together the actual path to the Ruby script we want to | |
// execute. Using dirname(argv[0]) is safe because the VMware Fusion | |
// provider guarantees that a full path is given as the argv[0]. | |
char helperPath[HELPER_PATH_MAX]; | |
snprintf(helperPath, HELPER_PATH_MAX, "%s/%s", | |
dirname(argv[0]), SUDO_HELPER_COMMAND); | |
// Setup the argv array so that the arguments are preserved for the | |
// sudo helper. | |
char **helperArgs = malloc(sizeof(char *) * (argc + 1));; | |
memcpy(helperArgs + 2, argv + 1, sizeof(char *) * (argc - 1)); | |
helperArgs[0] = "ruby"; | |
helperArgs[1] = helperPath; | |
helperArgs[argc + 1] = NULL; | |
// You have to setuid here because suid bits only change the EUID, | |
// and when Ruby sees the EUID != RUID, it resets the EUID back to | |
// RUID. This forces the script to run as root. | |
setuid(0); | |
// Replace ourselves with the sudo helper. This should terminate | |
// execution of this file, but if not we output the errno and then | |
// quit. | |
execvp("ruby", helperArgs); | |
fprintf(stderr, "sudo helper setuid-wrapper failed: %d\n", errno); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment