ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/adduser.c
Revision: 583
Committed: 2005-11-21T12:56:05-08:00 (19 years, 7 months ago) by douglas
Content type: text/x-c
File size: 4692 byte(s)
Log Message:
Refactorx0r!

File Contents

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