ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/adduser.c
Revision: 566
Committed: 2005-08-28T22:29:20-07:00 (19 years, 9 months ago) by douglas
Content type: text/x-c
File size: 4566 byte(s)
Log Message:
Worky!

File Contents

# Content
1 // Douglas Thrift
2 //
3 // CCS Computer Science
4 //
5 // Add User
6
7 #include <errno.h>
8 #include <sys/resource.h>
9 #include <sys/time.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <fts.h>
14
15 #include "common.h"
16
17 int main(int argc, char *argv[])
18 {
19 if (argc < 1)
20 return 1;
21
22 int exception;
23 jmp_buf environment;
24
25 switch (exception = setjmp(environment))
26 {
27 case 0:
28 break;
29 case 1:
30 perror(argv[0]);
31
32 return 1;
33 default:
34 fprintf(stderr, "%s: %s\n", argv[0], (char *)exception);
35
36 return 1;
37 }
38
39 #ifdef _Zweihander_
40 regex_t user_, name_;
41
42 regcheck(regcomp(&user_, "^-user=([a-z0-9]{1,16})$", REG_EXTENDED), &user_, environment);
43 regcheck(regcomp(&name_, "^-name=([^:]+)$", REG_EXTENDED), &name_, environment);
44
45 char user[MAXLOGNAME] = "", *name = NULL;
46
47 for (int index = 1; index != argc; ++index)
48 {
49 regmatch_t match[2];
50
51 if (!regcheck(regexec(&user_, argv[index], 2, match, 0), &user_, environment))
52 strlcpy(user, argv[index] + match[1].rm_so, match[1].rm_eo - match[1].rm_so + 1);
53 else if (!regcheck(regexec(&name_, argv[index], 2, match, 0), &name_, environment))
54 name = argv[index] + match[1].rm_so;
55 else
56 {
57 printf("Usage: %s [-user=user] [-name=name]\n", argv[0]);
58
59 return 1;
60 }
61 }
62
63 regfree(&user_);
64 regfree(&name_);
65 authenticate(argv[0], environment);
66
67 if (!strlen(user))
68 {
69 regcheck(regcomp(&user_, "^[a-z0-9]{1,16}$", REG_EXTENDED), &user_, environment);
70
71 do
72 {
73 printf("User Name: ");
74
75 size_t size;
76 char *user_ = fcheck(fgetln(stdin, &size), stdin, environment);
77
78 strlcpy(user, user_, size < sizeof (user) ? size : sizeof (user));
79 }
80 while (regcheck(regexec(&user_, user, 0, NULL, 0), &user_, environment));
81
82 regfree(&user_);
83 }
84
85 if (!name)
86 {
87 regcheck(regcomp(&name_, "^[^:]+$", REG_EXTENDED), &name_, environment);
88 get("Full Name", &name_, &name, environment);
89 regfree(&name_);
90 }
91
92 char password[_PASSWORD_LEN];
93
94 getpassword(password, environment);
95 check(setuid(geteuid()), environment);
96
97 char slappasswd[] = "/tmp/slappasswd.XXXXXX";
98
99 putpassword(password, slappasswd, environment);
100
101 int pipe_[2];
102
103 check(pipe(pipe_), environment);
104
105 pid_t bash;
106
107 if (!(bash = check(fork(), environment)))
108 {
109 check(dup2(pipe_[0], 0), environment);
110 check(close(pipe_[1]), environment);
111 check(setenv("USER", user, 1), environment);
112 check(setenv("NAME", name, 1), environment);
113 check(setenv("FILE", slappasswd, 1), environment);
114 check(execl("/ccs/bin/adduser.sh", argv[0], NULL), environment);
115 }
116
117 check(close(pipe_[0]), environment);
118
119 FILE *smbpasswd = fdopen(pipe_[1], "w");
120
121 if (fprintf(smbpasswd, "%s\n%s\n", password, password) < 0)
122 longjmp(environment, 1);
123
124 if (fclose(smbpasswd))
125 longjmp(environment, 1);
126
127 int status;
128
129 check(waitpid(bash, &status, 0), environment);
130 check(unlink(slappasswd), environment);
131
132 if (WEXITSTATUS(status))
133 return 1;
134
135 struct passwd *entry = getpwnam(user);
136
137 if (!entry)
138 longjmp(environment, 1);
139
140 check(mkdir(entry->pw_dir, 0755), environment);
141 check(chown(entry->pw_dir, entry->pw_uid, entry->pw_gid), environment);
142 check(chdir(entry->pw_dir), environment);
143
144 FTS *traversal = fts_open((char *[]){ "/usr/share/skel", NULL }, FTS_LOGICAL | FTS_NOCHDIR, NULL);
145
146 if (!traversal)
147 longjmp(environment, 1);
148
149 FTSENT *entity;
150
151 while ((entity = fts_read(traversal)))
152 switch (entity->fts_info)
153 {
154 case FTS_D:
155 if (entity->fts_level != FTS_ROOTLEVEL)
156 {
157 check(mkdir(entity->fts_name, entity->fts_statp->st_mode), environment);
158 check(chown(entity->fts_name, entry->pw_uid, entry->pw_gid), environment);
159 check(chdir(entity->fts_name), environment);
160 }
161
162 break;
163 case FTS_DP:
164 if (entity->fts_level != FTS_ROOTLEVEL)
165 check(chdir(".."), environment);
166
167 break;
168 case FTS_F:
169 {
170 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);
171 char buffer[entity->fts_statp->st_blksize];
172 size_t size;
173
174 while ((size = check(read(input, buffer, sizeof (buffer)), environment)))
175 check(write(output, buffer, size), environment);
176
177 check(fchown(output, entry->pw_uid, entry->pw_gid), environment);
178 check(close(output), environment);
179 check(close(input), environment);
180 }
181
182 break;
183 }
184
185 if (errno)
186 longjmp(environment, 1);
187
188 if (fts_close(traversal))
189 longjmp(environment, 1);
190 #else
191 longjmp(environment, (int)"Log in to zweihander.ccs.ucsb.edu to add users");
192 #endif
193
194 return 0;
195 }