ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/chsh.c
(Generate patch)

Comparing CCSAdmin/chsh.c (file contents):
Revision 562 by douglas, 2005-08-27T21:46:39-07:00 vs.
Revision 583 by douglas, 2005-11-21T12:56:05-08:00

# Line 4 | Line 4
4   //
5   // Change Shell
6  
7 #include <sys/utsname.h>
8
7   #include "common.h"
8  
9   int main(int argc, char *argv[])
10   {
11 +        if (argc < 1)
12 +                return 1;
13 +
14 +        umask(S_IWGRP | S_IWOTH);
15 +        
16          int exception;
17          jmp_buf environment;
18  
# Line 27 | Line 30 | int main(int argc, char *argv[])
30                  return 1;
31          }
32  
33 <        typedef struct
33 >        char *shell_regex = NULL;
34 >
35 >        {
36 >                size_t size = 0;
37 >
38 >                for (Shell shell = sh; shell <= custom; ++shell)
39 >                {
40 >                        shell_regex = shell_regex ? realloc(shell_regex, size += strlen(shells[shell].name) + (shell != custom ? 1 : 0)) : calloc(size += strlen(shells[shell].name) + 2, 1);
41 >                        strlcat(shell_regex, shells[shell].name, size);
42 >
43 >                        if (shell != custom)
44 >                                strlcat(shell_regex, "|", size);
45 >                }
46 >        }
47 >
48 >        char shell_regex_[strlen(shell_regex) + 12];
49 >
50 >        sprintf(shell_regex_, "^-shell=(%s)$", shell_regex);
51 >
52 >        regex_t shell_;
53 >
54 >        regcheck(regcomp(&shell_, shell_regex_, REG_EXTENDED), &shell_, environment);
55 >
56 >        char user[MAXLOGNAME] = "", *shell = NULL;
57 >
58 >        if (!getuid())
59          {
60 <                const char *name;
61 <                char *freebsd, *linux, *darwin;
60 >                regex_t user_;
61 >
62 >                regcheck(regcomp(&user_, "^-user=([a-z0-9]{1,16})$", REG_EXTENDED), &user_, environment);
63 >
64 >                for (int index = 1; index != argc; ++index)
65 >                {
66 >                        regmatch_t match[2];
67 >
68 >                        if (!regcheck(regexec(&user_, argv[index], 2, match, 0), &user_, environment))
69 >                                strlcpy(user, argv[index] + match[1].rm_so, match[1].rm_eo - match[1].rm_so + 1);
70 >                        else if (!regcheck(regexec(&shell_, argv[index], 2, match, 0), &shell_, environment))
71 >                                shell = argv[index] + match[1].rm_so;
72 >                        else
73 >                        {
74 >                                printf("Usage: %s -user=user [-shell=%s]\n", argv[0], shell_regex);
75 >
76 >                                return 1;
77 >                        }
78 >                }
79 >
80 >                regfree(&user_);
81 >
82 >                if (strlen(user))
83 >                        goto on;
84 >                else
85 >                        longjmp(environment, (int)"Cannot change root shell");
86          }
87 <        Shell;
87 >        else
88 >                for (int index = 1; index != argc; ++index)
89 >                {
90 >                        regmatch_t match[2];
91 >
92 >                        if (!regcheck(regexec(&shell_, argv[index], 2, match, 0), &shell_, environment))
93 >                                shell = argv[index] + match[1].rm_so;
94 >                        else
95 >                        {
96 >                                printf("Usage: %s [-shell=%s]\n", argv[0], shell_regex);
97 >
98 >                                return 1;
99 >                        }
100 >                }
101 >
102 >        struct passwd *entry = getpwuid(getuid());
103 >
104 >        if (!entry)
105 >                longjmp(environment, 1);
106 >
107 >        strlcpy(user, entry->pw_name, sizeof (user));
108 > on:     regfree(&shell_);
109 >        authenticate(argv[0], environment);
110 >
111 >        if (!shell)
112 >        {
113 >                sprintf(shell_regex_, "^%s$", shell_regex);
114 >                regcheck(regcomp(&shell_, shell_regex_, REG_EXTENDED), &shell_, environment);
115 >
116 >                do
117 >                {
118 >                        printf("Shell (");
119  
120 <        typedef enum { sh, csh, tcsh, bash, ksh, zsh, _3sh, custom } Shells;
120 >                        for (Shell shell = sh; shell <= custom; ++shell)
121 >                                printf(shell != custom ? "%s, " : "%s): ", shells[shell].name);
122  
123 <        Shell shells[] = {
124 <                { "sh", "/bin/sh", "/bin/sh", "/bin/sh" },
41 <                { "csh", "/bin/csh", "/bin/csh", "/bin/csh" },
42 <                { "tcsh", "/bin/tcsh", "/bin/tcsh", "/bin/tcsh" },
43 <                { "bash", "/usr/local/bin/bash", "/bin/bash", "/bin/bash" },
44 <                { "ksh", "/usr/local/bin/ksh", "/bin/ksh", "/bin/ksh" },
45 <                { "zsh", "/usr/local/bin/zsh", "/bin/zsh", "/bin/zsh" },
46 <                { "3sh", "/ccs/bin/3sh", "/ccs/bin/3sh", "/ccs/bin/3sh" },
47 <                { "custom", NULL, NULL, NULL }
48 <        };
123 >                        size_t size;
124 >                        char *shell_ = fcheck(fgetln(stdin, &size), stdin, environment);
125  
126 <        for (Shells shell = sh; shell != custom; ++shell)
51 <                printf("%s, ", shells[shell].name);
126 >                        shell = shell ? realloc(shell, size) : malloc(size);
127  
128 <        printf("%s\n", shells[custom].name);
128 >                        strlcpy(shell, shell_, size);
129 >                }
130 >                while (regcheck(regexec(&shell_, shell, 0, NULL, 0), &shell_, environment));
131 >
132 >                regfree(&shell_);
133 >        }
134 >
135 >        free(shell_regex);
136 >
137 >        Shells *shells_ = shells + custom;
138 >
139 >        for (Shell shell_ = sh; shell_ != custom; ++shell_)
140 >                if (!strcmp(shell, shells[shell_].name))
141 >                {
142 >                        shells_ = shells + shell_;
143 >
144 >                        goto no;
145 >                }
146 >
147 >        regex_t path;
148 >
149 >        regcheck(regcomp(&path, "^/.*[^/]$", REG_EXTENDED), &path, environment);
150 >        get("FreeBSD", &path, &shells_->freebsd, environment);
151 >        get("Linux", &path, &shells_->linux, environment);
152 >        get("Darwin", &path, &shells_->darwin, environment);
153 >        get("Solaris", &path, &shells_->solaris, environment);
154 >        regfree(&path);
155 >
156 > no:     check(setuid(geteuid()), environment);
157 >
158 >        pid_t bash_;
159 >
160 >        if (!(bash_ = check(fork(), environment)))
161 >        {
162 >                check(setenv("USER", user, 1), environment);
163 >                setshells(shells_, environment);
164 >                check(execl("/ccs/bin/chsh.sh", argv[0], NULL), environment);
165 >        }
166 >
167 >        int status;
168 >
169 >        check(waitpid(bash_, &status, 0), environment);
170 >
171 >        if (WEXITSTATUS(status))
172 >                return 1;
173  
174          return 0;
175   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines