this repo has no description
1/*
2 This file is part of Darling.
3
4 Copyright (C) 2019 Lubos Dolezel
5
6 Darling is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Darling is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Darling. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <stdlib.h>
21#include <unistd.h>
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25
26unsigned int firstarg = 1, uid = 0, gid = 0;
27
28static int list_mode = 0;
29
30int argparse(int, char**);
31int usage(int, int);
32
33int main(int argc, char **argv)
34{
35 char *path = getenv("PATH"), *path_orig, *fullpath = NULL;
36 int i, len;
37 if (argparse(argc, argv))
38 return 1;
39
40 setuid(uid);
41 setgid(gid);
42
43 if (firstarg == argc && list_mode)
44 {
45 printf("List mode without command not supported yet.\n");
46 return EXIT_SUCCESS;
47 }
48 else if (list_mode)
49 {
50 /* Print fill path to command, then args if present */
51 if (!path)
52 printf("can't search for command if no path\n");
53 path = strdup(path);
54 path_orig = path;
55 len = strlen(path_orig);
56 for (i = 0; i < len; i++)
57 {
58 if (path_orig[i] == ':' || path_orig[i] == '\0')
59 {
60 path_orig[i] = '\0';
61 fullpath = malloc(strlen(argv[firstarg])+strlen(path)+2);
62 strcpy(fullpath, path);
63 fullpath[strlen(path)] = '/';
64 strcpy(fullpath+strlen(path)+1, argv[firstarg]);
65 if (access(fullpath, X_OK) == 0)
66 break;
67 free(fullpath);
68 fullpath = NULL;
69 path = path_orig+i+1;
70 }
71 }
72 free(path_orig);
73 if (!fullpath)
74 {
75 fprintf(stderr, "%s: %s: command not found\n", argv[0], argv[firstarg]);
76 return EXIT_FAILURE;
77 }
78 printf("%s", fullpath);
79 free(fullpath);
80 for (i = firstarg+1; i < argc; i++)
81 {
82 printf(" %s", argv[i]);
83 }
84 putchar('\n');
85 return EXIT_SUCCESS;
86 }
87 else
88 {
89 if (firstarg < argc)
90 {
91 execvp(argv[firstarg], &argv[firstarg]);
92 perror("Running sudo failed");
93 }
94 else
95 return EXIT_SUCCESS;
96 }
97 return EXIT_FAILURE;
98}
99
100int argparse(int argc, char **argv)
101{
102 for (firstarg = 1; firstarg < argc; firstarg++)
103 {
104 if(!strcmp(argv[firstarg], "-g"))
105 {
106 sscanf(argv[++firstarg], "%u", &gid);
107 }
108 else if(!strcmp(argv[firstarg], "-u"))
109 {
110 sscanf(argv[++firstarg], "%u", &uid);
111 }
112 else if (!strcmp(argv[firstarg], "-A"))
113 {
114 }
115 else if (!strcmp(argv[firstarg], "-n"))
116 {
117 }
118 else if (!strcmp(argv[firstarg], "-v"))
119 {
120 }
121 else if(!strcmp(argv[firstarg], "--"))
122 {
123 break;
124 }
125 else if(!strcmp(argv[firstarg], "-k"))
126 {
127 }
128 else if(!strcmp(argv[firstarg], "--help"))
129 {
130 return usage(argc, 1);
131 }
132 else if (!strcmp(argv[firstarg], "-l"))
133 {
134 list_mode = 1;
135 }
136 else
137 {
138 break;
139 }
140 }
141 return 0;
142}
143
144int usage(int argc, int arg_help)
145{
146 if (argc <= firstarg || arg_help == 1)
147 {
148 fprintf(stderr, "This is a fake 'sudo' implementation, intended for use in Darling.\n"
149 "Processes will think they are run as UID/GID 0, but they are still run as your original UID/GID.\n"
150 "One purpose of this program is to convince some tools that they can write into '/'.\n"
151 "Another is to enable you to talk to certain system daemons.\n"
152 "\nUsage:\n"
153 " sudo [-g GID] [-u UID] [-k] [--] COMMAND\n");
154 return 1;
155 }
156 return 0;
157}