/* This file is part of Darling. Copyright (C) 2019 Lubos Dolezel Darling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Darling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Darling. If not, see . */ #include #include #include #include #include unsigned int firstarg = 1, uid = 0, gid = 0; static int list_mode = 0; int argparse(int, char**); int usage(int, int); int main(int argc, char **argv) { char *path = getenv("PATH"), *path_orig, *fullpath = NULL; int i, len; if (argparse(argc, argv)) return 1; setuid(uid); setgid(gid); if (firstarg == argc && list_mode) { printf("List mode without command not supported yet.\n"); return EXIT_SUCCESS; } else if (list_mode) { /* Print fill path to command, then args if present */ if (!path) printf("can't search for command if no path\n"); path = strdup(path); path_orig = path; len = strlen(path_orig); for (i = 0; i < len; i++) { if (path_orig[i] == ':' || path_orig[i] == '\0') { path_orig[i] = '\0'; fullpath = malloc(strlen(argv[firstarg])+strlen(path)+2); strcpy(fullpath, path); fullpath[strlen(path)] = '/'; strcpy(fullpath+strlen(path)+1, argv[firstarg]); if (access(fullpath, X_OK) == 0) break; free(fullpath); fullpath = NULL; path = path_orig+i+1; } } free(path_orig); if (!fullpath) { fprintf(stderr, "%s: %s: command not found\n", argv[0], argv[firstarg]); return EXIT_FAILURE; } printf("%s", fullpath); free(fullpath); for (i = firstarg+1; i < argc; i++) { printf(" %s", argv[i]); } putchar('\n'); return EXIT_SUCCESS; } else { if (firstarg < argc) { execvp(argv[firstarg], &argv[firstarg]); perror("Running sudo failed"); } else return EXIT_SUCCESS; } return EXIT_FAILURE; } int argparse(int argc, char **argv) { for (firstarg = 1; firstarg < argc; firstarg++) { if(!strcmp(argv[firstarg], "-g")) { sscanf(argv[++firstarg], "%u", &gid); } else if(!strcmp(argv[firstarg], "-u")) { sscanf(argv[++firstarg], "%u", &uid); } else if (!strcmp(argv[firstarg], "-A")) { } else if (!strcmp(argv[firstarg], "-n")) { } else if (!strcmp(argv[firstarg], "-v")) { } else if(!strcmp(argv[firstarg], "--")) { break; } else if(!strcmp(argv[firstarg], "-k")) { } else if(!strcmp(argv[firstarg], "--help")) { return usage(argc, 1); } else if (!strcmp(argv[firstarg], "-l")) { list_mode = 1; } else { break; } } return 0; } int usage(int argc, int arg_help) { if (argc <= firstarg || arg_help == 1) { fprintf(stderr, "This is a fake 'sudo' implementation, intended for use in Darling.\n" "Processes will think they are run as UID/GID 0, but they are still run as your original UID/GID.\n" "One purpose of this program is to convince some tools that they can write into '/'.\n" "Another is to enable you to talk to certain system daemons.\n" "\nUsage:\n" " sudo [-g GID] [-u UID] [-k] [--] COMMAND\n"); return 1; } return 0; }