34extern int pedigree_login(
int uid);
36static int password_matches(
const char* password,
const char* stored) {
37 if (!stored || stored[0] ==
'!' || stored[0] ==
'*')
41 if (stored[0] ==
'$') {
42 const char* encrypted = crypt(password, stored);
43 return encrypted && !strcmp(encrypted, stored);
46 return !strcmp(password, stored);
49static int wait_for_child(pid_t pid) {
51 while (waitpid(pid, &status, 0) == -1) {
55 fprintf(stderr,
"sudo: couldn't wait for child: %s\n", strerror(errno));
56 return errno ? errno : EXIT_FAILURE;
59 if (WIFEXITED(status))
60 return WEXITSTATUS(status);
61 if (WIFSIGNALED(status))
62 return 128 + WTERMSIG(status);
67int main(
int argc,
char* argv[]) {
68 int iRunShell = 0, error = 0, help = 0, nStart = 0, i = 0;
69 for (i = 1; i < argc; i++) {
70 if (!strcmp(argv[i],
"-s"))
72 else if (!strcmp(argv[i],
"-h"))
79 if (error || help || (!nStart && !iRunShell)) {
80 fprintf(stderr,
"Usage: sudo [-h] [-s|<command>]\n");
81 fprintf(stderr,
"\n");
82 fprintf(stderr,
" -s: Access root shell\n");
83 fprintf(stderr,
" -h: Show this help text\n");
88 struct passwd* pw = getpwnam(
"root");
90 fprintf(stderr,
"sudo: user 'root' doesn't exist!\n");
93 struct spwd* sp = getspnam(
"root");
95 fprintf(stderr,
"sudo: shadow entry for 'root' doesn't exist!\n");
102 size_t passwordLength = 0;
106 curt.c_lflag &= ~(ECHO | ICANON);
107 tcsetattr(0, TCSANOW, &curt);
109 printf(
"[sudo] Enter password: ");
112 while ((c = getchar()) !=
'\n' && c != EOF) {
114 if (passwordLength > 0) {
115 password[--passwordLength] =
'\0';
118 }
else if (c !=
'\033' && passwordLength < (
sizeof(password) - 1)) {
119 password[passwordLength++] = c;
124 curt.c_lflag |= (ECHO | ICANON);
125 tcsetattr(0, TCSANOW, &curt);
128 password[passwordLength] =
'\0';
131 if (!password_matches(password, sp->sp_pwdp) || pedigree_login(pw->pw_uid) != 0) {
132 fprintf(stderr,
"sudo: password is incorrect\n");
144 fprintf(stderr,
"sudo: couldn't fork: %s\n", strerror(errno));
146 }
else if (pid == 0) {
148 execlp(pw->pw_shell, pw->pw_shell, 0);
151 fprintf(stderr,
"sudo: couldn't run shell: %s\n", strerror(errno));
154 return wait_for_child(pid);
160 fprintf(stderr,
"sudo: couldn't fork: %s\n", strerror(errno));
162 }
else if (pid == 0) {
164 execvp(argv[nStart], &argv[nStart]);
167 fprintf(stderr,
"sudo: couldn't run command '%s': %s\n", argv[nStart], strerror(errno));
170 return wait_for_child(pid);