ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/adduser.c
Revision: 807
Committed: 2006-06-29T07:39:29-07:00 (18 years, 11 months ago) by douglas
Content type: text/x-c
File size: 6098 byte(s)
Log Message:
Yarg!

File Contents

# Content
1 // Douglas Thrift
2 //
3 // CCS Computer Science
4 //
5 // Add User
6
7 #include "common.h"
8
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <sys/resource.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16
17 #ifdef _Master_
18 #include <fts.h>
19
20 static int compare(const char **key, const char **item)
21 {
22 return strcmp(*key, *item);
23 }
24
25 static bool exists(const char *program, const char *user, jmp_buf environment)
26 {
27 int pipe_[2];
28
29 check(pipe(pipe_), environment);
30
31 pid_t ldapsearch;
32
33 if (!(ldapsearch = check(fork(), environment)))
34 {
35 check(dup2(pipe_[1], 1), environment);
36 check(close(pipe_[0]), environment);
37
38 char uid[strlen(user) + 5];
39
40 sprintf(uid, "uid=%s", user);
41 check(execl(LDAPSEARCH, program, "-b", "ou=People,dc=ccs,dc=ucsb,dc=edu", "-H", "ldaps://" MASTER, "-LLL", "-x", uid, "1.1", NULL), environment);
42 }
43
44 check(close(pipe_[1]), environment);
45
46 FILE *ldapsearch_ = fdopen(pipe_[0], "r");
47 size_t size;
48 char *uid = fcheck(fgetln(ldapsearch_, &size), ldapsearch_, environment);
49 int status;
50
51 check(waitpid(ldapsearch, &status, 0), environment);
52
53 char user_[strlen(user) + 41];
54
55 sprintf(user_, "dn: uid=%s,ou=People,dc=ccs,dc=ucsb,dc=edu", user);
56
57 if (size != 0 && !strncmp(user_, uid, size - 1))
58 return true;
59
60 static const char *users[] = {
61 # include "users.h"
62 };
63
64 if (bsearch(&user, users, sizeof (users) / sizeof (*users), sizeof (*users), (int (*)(const void *, const void *))compare))
65 return true;
66
67 return false;
68 }
69 #endif
70
71 int main(int argc, char *argv[])
72 {
73 if (argc < 1)
74 return 1;
75
76 umask(S_IWGRP | S_IWOTH);
77
78 int exception;
79 jmp_buf environment;
80
81 switch (exception = setjmp(environment))
82 {
83 case 0:
84 break;
85 case 1:
86 perror(argv[0]);
87
88 return 1;
89 default:
90 fprintf(stderr, "%s: %s\n", argv[0], (char *)exception);
91
92 return 1;
93 }
94
95 #ifdef _Master_
96 regex_t user_, name_;
97
98 regcheck(regcomp(&user_, "^-user=([a-z0-9]{1,16})$", REG_EXTENDED), &user_, environment);
99 regcheck(regcomp(&name_, "^-name=([^:]+)$", REG_EXTENDED), &name_, environment);
100
101 char user[MAXLOGNAME] = "", *name = NULL;
102
103 for (int index = 1; index != argc; ++index)
104 {
105 regmatch_t match[2];
106
107 if (!regcheck(regexec(&user_, argv[index], 2, match, 0), &user_, environment))
108 strlcpy(user, argv[index] + match[1].rm_so, match[1].rm_eo - match[1].rm_so + 1);
109 else if (!regcheck(regexec(&name_, argv[index], 2, match, 0), &name_, environment))
110 name = argv[index] + match[1].rm_so;
111 else
112 {
113 printf("Usage: %s [-user=user] [-name=name]\n", argv[0]);
114
115 return 1;
116 }
117 }
118
119 regfree(&user_);
120 regfree(&name_);
121 authenticate(argv[0], environment);
122
123 if (!strlen(user))
124 {
125 regcheck(regcomp(&user_, "^[a-z0-9]{1,16}$", REG_EXTENDED), &user_, environment);
126
127 do
128 {
129 printf("User Name: ");
130
131 size_t size;
132 char *user_ = fcheck(fgetln(stdin, &size), stdin, environment);
133
134 strlcpy(user, user_, size < sizeof (user) ? size : sizeof (user));
135 }
136 while (regcheck(regexec(&user_, user, 0, NULL, 0), &user_, environment) || (exists(argv[0], user, environment) && fprintf(stderr, "%s: User exists\n", argv[0])));
137
138 regfree(&user_);
139 }
140 else if (exists(argv[0], user, environment))
141 longjmp(environment, (int)"User exists");
142
143 if (!name)
144 {
145 regcheck(regcomp(&name_, "^[^:]+$", REG_EXTENDED), &name_, environment);
146 get("Full Name", &name_, &name, environment);
147 regfree(&name_);
148 }
149
150 char password[_PASSWORD_LEN];
151
152 getpassword(password, environment);
153 check(setuid(geteuid()), environment);
154
155 char slappasswd[] = "/tmp/slappasswd.XXXXXX";
156
157 putpassword(password, slappasswd, environment);
158
159 int pipe_[2];
160
161 check(pipe(pipe_), environment);
162
163 pid_t bash_;
164
165 if (!(bash_ = check(fork(), environment)))
166 {
167 check(dup2(pipe_[0], 0), environment);
168 check(close(pipe_[1]), environment);
169 check(setenv("USER", user, 1), environment);
170 check(setenv("NAME", name, 1), environment);
171 check(setenv("FILE", slappasswd, 1), environment);
172 setshells(shells + bash, environment);
173 check(execl("/ccs/bin/adduser.sh", argv[0], NULL), environment);
174 }
175
176 check(close(pipe_[0]), environment);
177
178 FILE *smbpasswd = fdopen(pipe_[1], "w");
179
180 if (fprintf(smbpasswd, "%s\n%s\n", password, password) < 0)
181 longjmp(environment, 1);
182
183 if (fclose(smbpasswd))
184 longjmp(environment, 1);
185
186 int status;
187
188 check(waitpid(bash_, &status, 0), environment);
189 check(unlink(slappasswd), environment);
190
191 if (WEXITSTATUS(status))
192 return 1;
193
194 struct passwd *entry = getpwnam(user);
195
196 if (!entry)
197 longjmp(environment, 1);
198
199 check(mkdir(entry->pw_dir, S_IRWXU | S_IRWXG | S_IRWXO), environment);
200 check(chown(entry->pw_dir, entry->pw_uid, entry->pw_gid), environment);
201 check(chdir(entry->pw_dir), environment);
202
203 FTS *traversal = fts_open((char *[]){ "/usr/share/skel", "/ccs/skel", NULL }, FTS_LOGICAL | FTS_NOCHDIR, NULL);
204
205 if (!traversal)
206 longjmp(environment, 1);
207
208 FTSENT *entity;
209
210 while ((entity = fts_read(traversal)))
211 switch (entity->fts_info)
212 {
213 case FTS_D:
214 if (entity->fts_level != FTS_ROOTLEVEL)
215 {
216 check(mkdir(entity->fts_name, entity->fts_statp->st_mode), environment);
217 check(chown(entity->fts_name, entry->pw_uid, entry->pw_gid), environment);
218 check(chdir(entity->fts_name), environment);
219 }
220
221 break;
222 case FTS_DP:
223 if (entity->fts_level != FTS_ROOTLEVEL)
224 check(chdir(".."), environment);
225
226 break;
227 case FTS_F:
228 {
229 int output = check(open(strncmp(entity->fts_name, "dot", 3) ? entity->fts_name : entity->fts_name + 3, O_WRONLY | O_CREAT | O_EXCL, entity->fts_statp->st_mode), environment), input = check(open(entity->fts_accpath, O_RDONLY), environment);
230 char buffer[entity->fts_statp->st_blksize];
231 size_t size;
232
233 while ((size = check(read(input, buffer, sizeof (buffer)), environment)))
234 check(write(output, buffer, size), environment);
235
236 check(fchown(output, entry->pw_uid, entry->pw_gid), environment);
237 check(close(output), environment);
238 check(close(input), environment);
239 }
240
241 break;
242 }
243
244 if (errno)
245 longjmp(environment, 1);
246
247 if (fts_close(traversal))
248 longjmp(environment, 1);
249 #else
250 longjmp(environment, (int)"Log in to " MASTER " to add users");
251 #endif
252
253 return 0;
254 }