1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Os;
9 using System.Security;
10 using paths;
11
12 void PrintHelp()
13 {
14 Console.Out() << "sudo [options] COMMAND [ARGS...]" << endl() << endl();
15 Console.Out() << "Execute COMMAND as superuser." << endl() << endl();
16 Console.Out() << "Options:" << endl() << endl();
17 Console.Out() << "--help | -h" << endl();
18 Console.Out() << " Print help and exit." << endl() << endl();
19 }
20
21 int main(int argc, const char** argv)
22 {
23 try
24 {
25 List<string> args;
26 bool programSeen = false;
27 for (int i = 1; i < argc; ++i;)
28 {
29 string arg = argv[i];
30 if (!programSeen)
31 {
32 if (arg.StartsWith("--"))
33 {
34 if (arg == "--help")
35 {
36 PrintHelp();
37 return 1;
38 }
39 else
40 {
41 throw Exception("unknown option '" + arg + "'");
42 }
43 }
44 else if (arg.StartsWith("-"))
45 {
46 string options = arg.Substring(1);
47 if (options.IsEmpty())
48 {
49 throw Exception("unknown argument '" + arg + "'");
50 }
51 else
52 {
53 bool unknown = false;
54 string uo;
55 for (char o : options)
56 {
57 switch (o)
58 {
59 case 'h':
60 {
61 PrintHelp();
62 return 1;
63 }
64 default:
65 {
66 unknown = true;
67 uo.Append(o);
68 break;
69 }
70 }
71 if (unknown)
72 {
73 throw Exception("unknown option '-" + uo + "'");
74 }
75 }
76 }
77 }
78 else
79 {
80 programSeen = true;
81 args.Add(arg);
82 }
83 }
84 else
85 {
86 args.Add(arg);
87 }
88 }
89 if (args.IsEmpty())
90 {
91 throw Exception("no program to execute");
92 }
93 int uid = GetUID();
94 Users users = GetUsers();
95 User* user = users.GetUser(uid);
96 SetUID(0);
97 SetGID(0);
98 if (user->HasPassword())
99 {
100 int pid = Fork();
101 if (pid == 0)
102 {
103 List<string> loginArgs;
104 loginArgs.Add("--user");
105 loginArgs.Add(user->Name());
106 Exec("/bin/login", loginArgs);
107 }
108 else
109 {
110 byte loginExitCode = 0u;
111 if (Wait(&loginExitCode) != -1)
112 {
113 if (loginExitCode != 0u)
114 {
115 return loginExitCode;
116 }
117 }
118 else
119 {
120 throw Exception("login failed");
121 }
122 }
123 }
124 int pid = Fork();
125 if (pid == 0)
126 {
127 string program = GetProgramFilePath(args[0]);
128 List<string> progArgs;
129 for (int i = 1; i < args.Count(); ++i;)
130 {
131 progArgs.Add(args[i]);
132 }
133 Exec(program, progArgs);
134 }
135 else
136 {
137 byte exitCode = 0u;
138 if (Wait(&exitCode) != -1)
139 {
140 return exitCode;
141 }
142 else
143 {
144 throw Exception("error executing '" + args[0] + "'");
145 }
146 }
147 }
148 catch (const Exception& ex)
149 {
150 Console.Error() << ex.ToString() << endl();
151 return 1;
152 }
153 return 0;
154 }