ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ccs/admin/adduser.c
Revision: 575
Committed: 2009-10-08T04:56:15-07:00 (15 years, 9 months ago) by douglas
Content type: text/x-c
File size: 6677 byte(s)
Log Message:
Start to work with passwd service and fix MySQL issues.

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 douglas 438 #ifdef _Master_
11     #include "mysql.h"
12     #endif
13    
14 douglas 1 #include <errno.h>
15     #include <stdbool.h>
16     #include <sys/resource.h>
17     #include <sys/time.h>
18     #include <sys/types.h>
19     #include <sys/stat.h>
20     #include <fcntl.h>
21    
22     #ifdef _Master_
23     #include <fts.h>
24    
25     static int compare(const char **key, const char **item)
26     {
27     return strcmp(*key, *item);
28     }
29    
30     static bool exists(const char *program, const char *user, jmp_buf environment)
31     {
32     int pipe_[2];
33    
34     check(pipe(pipe_), environment);
35    
36     pid_t ldapsearch;
37    
38     if (!(ldapsearch = check(fork(), environment)))
39     {
40     check(dup2(pipe_[1], 1), environment);
41     check(close(pipe_[0]), environment);
42    
43     char uid[strlen(user) + 5];
44    
45     sprintf(uid, "uid=%s", user);
46     check(execl(LDAPSEARCH, program, "-b", "ou=People,dc=ccs,dc=ucsb,dc=edu", "-H", "ldaps://" MASTER, "-LLL", "-x", uid, "1.1", NULL), environment);
47     }
48    
49     check(close(pipe_[1]), environment);
50    
51     FILE *ldapsearch_ = fdopen(pipe_[0], "r");
52     size_t size;
53     char *uid = fcheck(fgetln(ldapsearch_, &size), ldapsearch_, environment);
54     int status;
55    
56     check(waitpid(ldapsearch, &status, 0), environment);
57    
58     char user_[strlen(user) + 41];
59    
60     sprintf(user_, "dn: uid=%s,ou=People,dc=ccs,dc=ucsb,dc=edu", user);
61    
62     if (size != 0 && !strncmp(user_, uid, size - 1))
63     return true;
64    
65     static const char *users[] = {
66     # include "users.h"
67     };
68    
69     if (bsearch(&user, users, sizeof (users) / sizeof (*users), sizeof (*users), (int (*)(const void *, const void *))compare))
70     return true;
71    
72     return false;
73     }
74     #endif
75    
76     int main(int argc, char *argv[])
77     {
78     if (argc < 1)
79     return 1;
80    
81     umask(S_IWGRP | S_IWOTH);
82 douglas 34
83 douglas 1 jmp_buf environment;
84    
85 douglas 438 #ifdef _Master_
86     MYSQL_BEGIN();
87     #endif
88    
89 douglas 264 switch (setjmp(environment))
90 douglas 1 {
91     case 0:
92     break;
93 douglas 438 case POSIX_EXCEPTION:
94 douglas 1 perror(argv[0]);
95    
96 douglas 438 goto end;
97     case STRING_EXCEPTION:
98 douglas 264 fprintf(stderr, "%s: %s\n", argv[0], exception);
99 douglas 438 #ifdef _Master_
100 douglas 1
101 douglas 438 goto end;
102     case MYSQL_EXCEPTION:
103     fprintf(stderr, "%s: %s\n", argv[0], mysql_error(mysql));
104 douglas 575
105     goto end;
106    
107     case MYSQL_STATEMENT_EXCEPTION:
108     fprintf(stderr, "%s: %s\n", argv[0], mysql_stmt_error(mysqlstatement));
109 douglas 438 #endif
110    
111     end:
112     #ifdef _Master_
113     MYSQL_END();
114    
115     #endif
116 douglas 1 return 1;
117     }
118    
119     #ifdef _Master_
120     regex_t user_, name_;
121    
122     regcheck(regcomp(&user_, "^-user=([a-z0-9]{1,16})$", REG_EXTENDED), &user_, environment);
123     regcheck(regcomp(&name_, "^-name=([^:]+)$", REG_EXTENDED), &name_, environment);
124    
125     char user[MAXLOGNAME] = "", *name = NULL;
126    
127     for (int index = 1; index != argc; ++index)
128     {
129     regmatch_t match[2];
130    
131     if (!regcheck(regexec(&user_, argv[index], 2, match, 0), &user_, environment))
132     strlcpy(user, argv[index] + match[1].rm_so, match[1].rm_eo - match[1].rm_so + 1);
133     else if (!regcheck(regexec(&name_, argv[index], 2, match, 0), &name_, environment))
134     name = argv[index] + match[1].rm_so;
135     else
136     {
137     printf("Usage: %s [-user=user] [-name=name]\n", argv[0]);
138    
139 douglas 438 goto end;
140 douglas 1 }
141     }
142    
143     regfree(&user_);
144     regfree(&name_);
145 douglas 575 authenticate(argv[0], NULL, environment);
146 douglas 1
147     if (!strlen(user))
148     {
149     regcheck(regcomp(&user_, "^[a-z0-9]{1,16}$", REG_EXTENDED), &user_, environment);
150    
151     do
152     {
153     printf("User Name: ");
154    
155     size_t size;
156     char *user_ = fcheck(fgetln(stdin, &size), stdin, environment);
157    
158     strlcpy(user, user_, size < sizeof (user) ? size : sizeof (user));
159     }
160     while (regcheck(regexec(&user_, user, 0, NULL, 0), &user_, environment) || (exists(argv[0], user, environment) && fprintf(stderr, "%s: User exists\n", argv[0])));
161    
162     regfree(&user_);
163     }
164     else if (exists(argv[0], user, environment))
165 douglas 438 longjmp(environment, (exception = "User exists", STRING_EXCEPTION));
166 douglas 1
167     if (!name)
168     {
169     regcheck(regcomp(&name_, "^[^:]+$", REG_EXTENDED), &name_, environment);
170     get("Full Name", &name_, &name, environment);
171     regfree(&name_);
172     }
173    
174     char password[_PASSWORD_LEN];
175    
176     getpassword(password, environment);
177     check(setuid(geteuid()), environment);
178    
179     char slappasswd[] = "/tmp/slappasswd.XXXXXX";
180    
181     putpassword(password, slappasswd, environment);
182    
183     int pipe_[2];
184    
185     check(pipe(pipe_), environment);
186    
187     pid_t bash_;
188    
189     if (!(bash_ = check(fork(), environment)))
190     {
191     check(dup2(pipe_[0], 0), environment);
192     check(close(pipe_[1]), environment);
193     check(setenv("USER", user, 1), environment);
194     check(setenv("NAME", name, 1), environment);
195     check(setenv("FILE", slappasswd, 1), environment);
196     setshells(shells + bash, environment);
197     check(execl("/ccs/bin/adduser.sh", argv[0], NULL), environment);
198     }
199    
200     check(close(pipe_[0]), environment);
201    
202     FILE *smbpasswd = fdopen(pipe_[1], "w");
203    
204     if (fprintf(smbpasswd, "%s\n%s\n", password, password) < 0)
205 douglas 438 longjmp(environment, POSIX_EXCEPTION);
206 douglas 1
207     if (fclose(smbpasswd))
208 douglas 438 longjmp(environment, POSIX_EXCEPTION);
209 douglas 1
210     int status;
211    
212     check(waitpid(bash_, &status, 0), environment);
213     check(unlink(slappasswd), environment);
214    
215     if (WEXITSTATUS(status))
216 douglas 438 goto end;
217 douglas 1
218 douglas 438 mysqlpassword(mysql, user, password, environment);
219     MYSQL_END();
220    
221 douglas 1 struct passwd *entry = getpwnam(user);
222    
223     if (!entry)
224 douglas 438 longjmp(environment, POSIX_EXCEPTION);
225 douglas 1
226     check(mkdir(entry->pw_dir, S_IRWXU | S_IRWXG | S_IRWXO), environment);
227     check(chown(entry->pw_dir, entry->pw_uid, entry->pw_gid), environment);
228     check(chdir(entry->pw_dir), environment);
229    
230     FTS *traversal = fts_open((char *[]){ "/usr/share/skel", "/ccs/skel", NULL }, FTS_LOGICAL | FTS_NOCHDIR, NULL);
231    
232     if (!traversal)
233 douglas 438 longjmp(environment, POSIX_EXCEPTION);
234 douglas 1
235     FTSENT *entity;
236    
237     while ((entity = fts_read(traversal)))
238     switch (entity->fts_info)
239     {
240     case FTS_D:
241     if (entity->fts_level != FTS_ROOTLEVEL)
242     {
243     check(mkdir(entity->fts_name, entity->fts_statp->st_mode), environment);
244     check(chown(entity->fts_name, entry->pw_uid, entry->pw_gid), environment);
245     check(chdir(entity->fts_name), environment);
246     }
247    
248     break;
249     case FTS_DP:
250     if (entity->fts_level != FTS_ROOTLEVEL)
251     check(chdir(".."), environment);
252    
253     break;
254     case FTS_F:
255     {
256     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);
257     char buffer[entity->fts_statp->st_blksize];
258     size_t size;
259    
260     while ((size = check(read(input, buffer, sizeof (buffer)), environment)))
261     check(write(output, buffer, size), environment);
262    
263     check(fchown(output, entry->pw_uid, entry->pw_gid), environment);
264     check(close(output), environment);
265     check(close(input), environment);
266     }
267    
268     break;
269     }
270    
271     if (errno)
272 douglas 438 longjmp(environment, POSIX_EXCEPTION);
273 douglas 1
274     if (fts_close(traversal))
275 douglas 438 longjmp(environment, POSIX_EXCEPTION);
276 douglas 1 #else
277 douglas 438 longjmp(environment, (exception = "Log in to " MASTER " to add users", STRING_EXCEPTION));
278 douglas 1 #endif
279    
280     return 0;
281     }

Properties

Name Value
svn:keywords Id