ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSAdmin/adduser.c
Revision: 567
Committed: 2005-08-28T22:42:38-07:00 (19 years, 9 months ago) by douglas
Content type: text/x-c
File size: 4617 byte(s)
Log Message:
Umask and portability, just in case the HURD takes over. Nooooooooooo!

File Contents

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