ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ccs/admin/adduser.c
Revision: 264
Committed: 2008-06-08T04:05:38-07:00 (17 years, 1 month ago) by douglas
Content type: text/x-c
File size: 6095 byte(s)
Log Message:
64bit safe and multiplatform build environment.

File Contents

# User Rev Content
1 douglas 1 // Douglas Thrift
2     //
3     // CCS Computer Science
4     // Add User
5     //
6     // $Id$
7    
8     #include "common.h"
9    
10     #include <errno.h>
11     #include <stdbool.h>
12     #include <sys/resource.h>
13     #include <sys/time.h>
14     #include <sys/types.h>
15     #include <sys/stat.h>
16     #include <fcntl.h>
17    
18     #ifdef _Master_
19     #include <fts.h>
20    
21     static int compare(const char **key, const char **item)
22     {
23     return strcmp(*key, *item);
24     }
25    
26     static bool exists(const char *program, const char *user, jmp_buf environment)
27     {
28     int pipe_[2];
29    
30     check(pipe(pipe_), environment);
31    
32     pid_t ldapsearch;
33    
34     if (!(ldapsearch = check(fork(), environment)))
35     {
36     check(dup2(pipe_[1], 1), environment);
37     check(close(pipe_[0]), environment);
38    
39     char uid[strlen(user) + 5];
40    
41     sprintf(uid, "uid=%s", user);
42     check(execl(LDAPSEARCH, program, "-b", "ou=People,dc=ccs,dc=ucsb,dc=edu", "-H", "ldaps://" MASTER, "-LLL", "-x", uid, "1.1", NULL), environment);
43     }
44    
45     check(close(pipe_[1]), environment);
46    
47     FILE *ldapsearch_ = fdopen(pipe_[0], "r");
48     size_t size;
49     char *uid = fcheck(fgetln(ldapsearch_, &size), ldapsearch_, environment);
50     int status;
51    
52     check(waitpid(ldapsearch, &status, 0), environment);
53    
54     char user_[strlen(user) + 41];
55    
56     sprintf(user_, "dn: uid=%s,ou=People,dc=ccs,dc=ucsb,dc=edu", user);
57    
58     if (size != 0 && !strncmp(user_, uid, size - 1))
59     return true;
60    
61     static const char *users[] = {
62     # include "users.h"
63     };
64    
65     if (bsearch(&user, users, sizeof (users) / sizeof (*users), sizeof (*users), (int (*)(const void *, const void *))compare))
66     return true;
67    
68     return false;
69     }
70     #endif
71    
72     int main(int argc, char *argv[])
73     {
74     if (argc < 1)
75     return 1;
76    
77     umask(S_IWGRP | S_IWOTH);
78 douglas 34
79 douglas 1 jmp_buf environment;
80    
81 douglas 264 switch (setjmp(environment))
82 douglas 1 {
83     case 0:
84     break;
85     case 1:
86     perror(argv[0]);
87    
88     return 1;
89     default:
90 douglas 264 fprintf(stderr, "%s: %s\n", argv[0], exception);
91 douglas 1
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 douglas 264 longjmp(environment, (exception = "User exists", 3));
142 douglas 1
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 douglas 264 longjmp(environment, (exception = "Log in to " MASTER " to add users", 3));
251 douglas 1 #endif
252    
253     return 0;
254     }

Properties

Name Value
svn:keywords Id