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

# 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    
22 douglas 562 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 douglas 564
47 douglas 562 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 douglas 563 get("Full Name", &name_, &name, environment);
89 douglas 562 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 douglas 566 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 douglas 562 #else
191     longjmp(environment, (int)"Log in to zweihander.ccs.ucsb.edu to add users");
192     #endif
193    
194     return 0;
195     }