ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/adduser.c
Revision: 584
Committed: 2005-11-22T18:14:57-08:00 (19 years, 7 months ago) by douglas
Content type: text/x-c
File size: 4720 byte(s)
Log Message:
Solaris worky!

File Contents

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