4 |
|
// |
5 |
|
// Change Shell |
6 |
|
|
7 |
– |
#include <sys/utsname.h> |
8 |
– |
|
7 |
|
#include "common.h" |
8 |
|
|
9 |
|
int main(int argc, char *argv[]) |
11 |
|
if (argc < 1) |
12 |
|
return 1; |
13 |
|
|
14 |
+ |
umask(S_IWGRP | S_IWOTH); |
15 |
+ |
|
16 |
|
int exception; |
17 |
|
jmp_buf environment; |
18 |
|
|
30 |
|
return 1; |
31 |
|
} |
32 |
|
|
33 |
– |
char user[MAXLOGNAME] = "", *shell = NULL; |
34 |
– |
regex_t shell_; |
35 |
– |
|
33 |
|
typedef struct |
34 |
|
{ |
35 |
|
const char *name; |
36 |
< |
char *freebsd, *linux, *darwin; |
36 |
> |
char *freebsd, *linux, *darwin, *solaris; |
37 |
|
} |
38 |
|
Shells; |
39 |
|
|
40 |
|
typedef enum { sh, csh, tcsh, bash, ksh, zsh, _3sh, custom } Shell; |
41 |
|
|
42 |
|
Shells shells[] = { |
43 |
< |
{ "sh", "/bin/sh", "/bin/sh", "/bin/sh" }, |
44 |
< |
{ "csh", "/bin/csh", "/bin/csh", "/bin/csh" }, |
45 |
< |
{ "tcsh", "/bin/tcsh", "/bin/tcsh", "/bin/tcsh" }, |
46 |
< |
{ "bash", "/usr/local/bin/bash", "/bin/bash", "/bin/bash" }, |
47 |
< |
{ "ksh", "/usr/local/bin/ksh", "/bin/ksh", "/bin/ksh" }, |
48 |
< |
{ "zsh", "/usr/local/bin/zsh", "/bin/zsh", "/bin/zsh" }, |
49 |
< |
{ "3sh", "/ccs/bin/3sh", "/ccs/bin/3sh", "/ccs/bin/3sh" }, |
50 |
< |
{ "custom", NULL, NULL, NULL } |
43 |
> |
{ "sh", "/bin/sh", "/bin/sh", "/bin/sh", "/usr/bin/sh" }, |
44 |
> |
{ "csh", "/bin/csh", "/bin/csh", "/bin/csh", "/usr/bin/csh" }, |
45 |
> |
{ "tcsh", "/bin/tcsh", "/bin/tcsh", "/bin/tcsh", "/usr/bin/tcsh" }, |
46 |
> |
{ "bash", "/usr/local/bin/bash", "/bin/bash", "/bin/bash", "/usr/bin/bash" }, |
47 |
> |
{ "ksh", "/usr/local/bin/ksh", "/bin/ksh", "/bin/ksh", "/usr/bin/ksh" }, |
48 |
> |
{ "zsh", "/usr/local/bin/zsh", "/bin/zsh", "/bin/zsh", "/usr/bin/zsh" }, |
49 |
> |
{ "3sh", "/ccs/bin/3sh", "/ccs/bin/3sh", "/ccs/bin/3sh", "/ccs/bin/3sh" }, |
50 |
> |
{ "custom", NULL, NULL, NULL, NULL } |
51 |
|
}; |
52 |
|
|
53 |
|
char *shell_regex = NULL; |
68 |
|
char shell_regex_[strlen(shell_regex) + 12]; |
69 |
|
|
70 |
|
sprintf(shell_regex_, "^-shell=(%s)$", shell_regex); |
71 |
+ |
|
72 |
+ |
regex_t shell_; |
73 |
+ |
|
74 |
|
regcheck(regcomp(&shell_, shell_regex_, REG_EXTENDED), &shell_, environment); |
75 |
|
|
76 |
+ |
char user[MAXLOGNAME] = "", *shell = NULL; |
77 |
+ |
|
78 |
|
if (!getuid()) |
79 |
|
{ |
80 |
|
regex_t user_; |
132 |
|
{ |
133 |
|
sprintf(shell_regex_, "^%s$", shell_regex); |
134 |
|
regcheck(regcomp(&shell_, shell_regex_, REG_EXTENDED), &shell_, environment); |
135 |
+ |
|
136 |
|
do |
137 |
|
{ |
138 |
|
printf("Shell ("); |
170 |
|
get("FreeBSD", &path, &shells_->freebsd, environment); |
171 |
|
get("Linux", &path, &shells_->linux, environment); |
172 |
|
get("Darwin", &path, &shells_->darwin, environment); |
173 |
+ |
get("Solaris", &path, &shells_->solaris, environment); |
174 |
|
regfree(&path); |
175 |
|
|
176 |
|
no: check(setuid(geteuid()), environment); |
177 |
|
|
174 |
– |
int pipe_[2]; |
175 |
– |
|
176 |
– |
check(pipe(pipe_), environment); |
177 |
– |
|
178 |
|
pid_t bash_; |
179 |
|
|
180 |
|
if (!(bash_ = check(fork(), environment))) |
181 |
|
{ |
182 |
– |
check(dup2(pipe_[0], 0), environment); |
183 |
– |
check(close(pipe_[1]), environment); |
182 |
|
check(setenv("USER", user, 1), environment); |
183 |
+ |
check(setenv("FREEBSD", shells_->freebsd, 1), environment); |
184 |
+ |
check(setenv("LINUX", shells_->linux, 1), environment); |
185 |
+ |
check(setenv("DARWIN", shells_->darwin, 1), environment); |
186 |
+ |
check(setenv("SOLARIS", shells_->solaris, 1), environment); |
187 |
|
check(execl("/ccs/bin/chsh.sh", argv[0], NULL), environment); |
188 |
|
} |
189 |
|
|
188 |
– |
check(close(pipe_[0]), environment); |
189 |
– |
|
190 |
– |
FILE *sed = fdopen(pipe_[1], "w"); |
191 |
– |
|
192 |
– |
if (fprintf(sed, "%s\n%s\n%s\n", shells_->freebsd, shells_->linux, shells_->darwin) < 0) |
193 |
– |
longjmp(environment, 1); |
194 |
– |
|
195 |
– |
if (fclose(sed)) |
196 |
– |
longjmp(environment, 1); |
197 |
– |
|
190 |
|
int status; |
191 |
|
|
192 |
|
check(waitpid(bash_, &status, 0), environment); |