rev |
line source |
yuuji@1
|
1 #include <stdio.h>
|
yuuji@1
|
2 #include <stdlib.h>
|
yuuji@1
|
3 #include <string.h>
|
yuuji@1
|
4 #include <unistd.h>
|
yuuji@1
|
5 #include <sys/types.h>
|
yuuji@1
|
6 #include <sys/wait.h>
|
yuuji@1
|
7 #include <sys/stat.h>
|
yuuji@1
|
8 #include <pwd.h>
|
yuuji@1
|
9 #ifdef SHADOW_PASSWD
|
yuuji@1
|
10 #include <shadow.h>
|
yuuji@1
|
11 #endif
|
yuuji@1
|
12
|
yuuji@1
|
13 #ifndef APOPPASSWD
|
yuuji@1
|
14 #define APOPPASSWD "/usr/local/bin/apoppasswd"
|
yuuji@1
|
15 #endif
|
yuuji@1
|
16 #ifndef APOPFILEBASE
|
yuuji@1
|
17 #define APOPFILEBASE ".apop"
|
yuuji@1
|
18 #endif
|
yuuji@1
|
19 #ifndef XADDR_DELIM
|
yuuji@1
|
20 #define XADDR_DELIM ('-')
|
yuuji@1
|
21 #endif
|
yuuji@1
|
22
|
yuuji@1
|
23 char *myname;
|
yuuji@1
|
24
|
yuuji@1
|
25 int ishexa(int c) {
|
yuuji@1
|
26 strchr("0123456789ABCDFabcdef", c) ? 1 : 0;
|
yuuji@1
|
27 }
|
yuuji@1
|
28
|
yuuji@1
|
29 put_form(email, pass, new, new2, suffix, hidden, auth, force)
|
yuuji@1
|
30 char *email, *pass, *new, *new2, *suffix;
|
yuuji@1
|
31 int hidden, auth, force;
|
yuuji@1
|
32 /* auth = 0: old password
|
yuuji@1
|
33 1: base addresse's mail password
|
yuuji@1
|
34 2: unix password */
|
yuuji@1
|
35 {
|
yuuji@1
|
36 char *authtype[] = {"old", "base", "unix"};
|
yuuji@1
|
37 char *var[] = {"email", "pass", "new", "new2", "auth", ""};
|
yuuji@1
|
38 char *val[] = {email, pass, new, new2, authtype[auth]};
|
yuuji@1
|
39 char *prm[] = {"", /* "ユーザ名", */
|
yuuji@1
|
40 auth ?
|
yuuji@1
|
41 ((auth==1)
|
yuuji@1
|
42 ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address"
|
yuuji@1
|
43 : "UNIXログインパスワード<br>UNIX login Password")
|
yuuji@1
|
44 : "古いメイルパスワード<br>Old Mail Password",
|
yuuji@1
|
45 "新しいメイルパスワード<br>New Mail Password",
|
yuuji@1
|
46 "新パスワードをもう一回(確認)<br>New Mail Password Again",
|
yuuji@1
|
47 ""};
|
yuuji@1
|
48 int h=0, i;
|
yuuji@1
|
49
|
yuuji@1
|
50 printf("<form method=POST action\"./%s\">\n", myname);
|
yuuji@1
|
51 printf(" <table border=1>\n");
|
yuuji@1
|
52 for (i=0; var[i][0]; i++) {
|
yuuji@1
|
53 h = hidden || strstr("email,suffix,auth", var[i]);
|
yuuji@1
|
54 if (prm[i][0]) {
|
yuuji@1
|
55 printf("<tr><td>%s</td><td>", prm[i]);
|
yuuji@1
|
56 } else {
|
yuuji@1
|
57 }
|
yuuji@1
|
58 printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n",
|
yuuji@1
|
59 var[i],
|
yuuji@1
|
60 h ? "type=hidden "
|
yuuji@1
|
61 : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"),
|
yuuji@1
|
62 val[i]);
|
yuuji@1
|
63 if (!strcmp(var[i], "suffix")) {
|
yuuji@1
|
64 /* ここでは suffix を入れさせない方がいいかも */
|
yuuji@1
|
65 /* 表向きのメイルアドレスを表示しておく */
|
yuuji@1
|
66 printf("%s", email);
|
yuuji@1
|
67 /* if (suffix[0]) {
|
yuuji@1
|
68 printf("-%s", suffix);
|
yuuji@1
|
69 } */
|
yuuji@1
|
70 if (auth)
|
yuuji@1
|
71 printf("<br>(新規作成:New Account)");
|
yuuji@1
|
72 }
|
yuuji@1
|
73 if (prm[i][0])
|
yuuji@1
|
74 printf("</td></tr>");
|
yuuji@1
|
75 printf("\n");
|
yuuji@1
|
76 }
|
yuuji@1
|
77
|
yuuji@1
|
78 printf("</table>\n");
|
yuuji@1
|
79 if (force)
|
yuuji@1
|
80 printf("<input name=force type=hidden value=ON>\n");
|
yuuji@1
|
81 if (auth) {
|
yuuji@1
|
82 char *a[] = {"basic", "unix"};
|
yuuji@1
|
83 printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]);
|
yuuji@1
|
84 }
|
yuuji@1
|
85 printf("<input name=OK value=OK type=submit>\n");
|
yuuji@1
|
86 printf("<input name=RESET value=RESET type=reset>\n");
|
yuuji@1
|
87 printf("</form>\n");
|
yuuji@1
|
88 fflush(stdout);
|
yuuji@1
|
89 }
|
yuuji@1
|
90
|
yuuji@1
|
91 char *decode(char *code) {
|
yuuji@1
|
92 int l=1+strlen(code);
|
yuuji@1
|
93 int i, c, d;
|
yuuji@1
|
94 char *ret = (char*)malloc(l*sizeof(char));
|
yuuji@1
|
95 char *p = code;
|
yuuji@1
|
96 memset(ret, 0, l);
|
yuuji@1
|
97 for (i=0; i<strlen(code); i++) {
|
yuuji@1
|
98 if (code[i] == '+') code[i] = ' ';
|
yuuji@1
|
99 }
|
yuuji@1
|
100 while (code[0] && (p=strchr(code, '%'))
|
yuuji@1
|
101 && ishexa(*(p+1)) && ishexa(*(p+2))) {
|
yuuji@1
|
102 *(p++) = '\0';
|
yuuji@1
|
103 strncat(ret, code, l);
|
yuuji@1
|
104 c = (islower(*p) ? toupper(*p) : *p) - '0';
|
yuuji@1
|
105 p++;
|
yuuji@1
|
106 d = (islower(*p) ? toupper(*p) : *p) - '0';
|
yuuji@1
|
107 if (c > 9) c -= ('A'-'9'-1);
|
yuuji@1
|
108 if (d > 9) d -= ('A'-'9'-1);
|
yuuji@1
|
109 ret[strlen(ret)] = c*16+d;
|
yuuji@1
|
110 code = p+1;
|
yuuji@1
|
111 }
|
yuuji@1
|
112 if (code[0]) strncat(ret, code, l);
|
yuuji@1
|
113 return ret;
|
yuuji@1
|
114 }
|
yuuji@1
|
115
|
yuuji@1
|
116 #define BSIZE 8192
|
yuuji@1
|
117 char **decode_post() {
|
yuuji@1
|
118 char *buf = (char*)malloc(BSIZE*sizeof(char));
|
yuuji@1
|
119 char **post, *p = buf;
|
yuuji@1
|
120 int n=0, i;
|
yuuji@1
|
121 post = (char**)calloc(1, sizeof(char*));
|
yuuji@1
|
122 *buf = '\0';
|
yuuji@1
|
123 fgets(buf, BSIZE, stdin);
|
yuuji@1
|
124 if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */
|
yuuji@1
|
125 buf[strlen(buf)-1] = '\0';
|
yuuji@1
|
126 while (buf[0] && NULL != (p=strchr(buf, '&'))) {
|
yuuji@1
|
127 *p = '\0';
|
yuuji@1
|
128 post[n] = (char*)malloc((p-buf+1)*sizeof(char));
|
yuuji@1
|
129 strcpy(post[n], buf);
|
yuuji@1
|
130 n++;
|
yuuji@1
|
131 post = (char**)realloc(post, (1+n)*sizeof(char*));
|
yuuji@1
|
132 buf = 1+p;
|
yuuji@1
|
133 }
|
yuuji@1
|
134 if (buf[0]) post[n++] = buf;
|
yuuji@1
|
135 /* decode URL encoded */
|
yuuji@1
|
136 for (i=0; i < n; i++) {
|
yuuji@1
|
137 char *p;
|
yuuji@1
|
138 p=post[i];
|
yuuji@1
|
139 post[i] = decode(p);
|
yuuji@1
|
140 }
|
yuuji@1
|
141 post[i] = ""; /* terminator */
|
yuuji@1
|
142 return post;
|
yuuji@1
|
143 }
|
yuuji@1
|
144
|
yuuji@1
|
145 void footer() {
|
yuuji@1
|
146 puts("</body>\n</html>");
|
yuuji@1
|
147 fflush(stdout);
|
yuuji@1
|
148 }
|
yuuji@1
|
149
|
yuuji@1
|
150 void fail() {
|
yuuji@1
|
151 printf("パスワード更新に失敗しました<br>\n");
|
yuuji@1
|
152 printf("<a href=\"./\">やり直し</a><br>\n");
|
yuuji@1
|
153 footer();
|
yuuji@1
|
154 exit(1);
|
yuuji@1
|
155 }
|
yuuji@1
|
156 void success(char *email) {
|
yuuji@1
|
157 printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n",
|
yuuji@1
|
158 email);
|
yuuji@1
|
159 footer();
|
yuuji@1
|
160 exit(0);
|
yuuji@1
|
161 }
|
yuuji@1
|
162
|
yuuji@1
|
163 int apopfile_existp(char *home, char *suffix, uid_t uid) {
|
yuuji@1
|
164 struct stat st;
|
yuuji@1
|
165 int s;
|
yuuji@1
|
166 int len = strlen(home) + 1
|
yuuji@1
|
167 + strlen(APOPFILEBASE) + strlen(suffix) + 3;
|
yuuji@1
|
168 char *apopfile = (char*)malloc(len);
|
yuuji@1
|
169 if (suffix[0]) {
|
yuuji@1
|
170 snprintf(apopfile, len, "%s/%s%c%s%c",
|
yuuji@1
|
171 home, APOPFILEBASE, XADDR_DELIM, suffix, 0);
|
yuuji@1
|
172 } else {
|
yuuji@1
|
173 snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0);
|
yuuji@1
|
174 }
|
yuuji@1
|
175 seteuid(uid);
|
yuuji@1
|
176 s = stat(apopfile, &st);
|
yuuji@1
|
177 seteuid(0);
|
yuuji@1
|
178 memset(apopfile, '\0', strlen(apopfile));
|
yuuji@1
|
179 free(apopfile);
|
yuuji@1
|
180 return !s;
|
yuuji@1
|
181 }
|
yuuji@1
|
182
|
yuuji@1
|
183 #ifndef QMAILCONTROL
|
yuuji@1
|
184 # define QMAILCONTROL "/var/qmail/control"
|
yuuji@1
|
185 #endif
|
yuuji@1
|
186 #ifndef MAILTMPLEN
|
yuuji@1
|
187 # define MAILTMPLEN 1024
|
yuuji@1
|
188 #endif
|
yuuji@1
|
189
|
yuuji@1
|
190 /* Convert virtual domain user
|
yuuji@1
|
191 */
|
yuuji@1
|
192 char* conv_virtualdomain(char *account) {
|
yuuji@1
|
193 char *dom = strchr(account, '@'), *p;
|
yuuji@1
|
194 char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1];
|
yuuji@1
|
195 FILE *vdfd;
|
yuuji@1
|
196 int match=0;
|
yuuji@1
|
197 char buf[MAILTMPLEN+1], *s;
|
yuuji@1
|
198 snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains");
|
yuuji@1
|
199 if (NULL == dom) return account;
|
yuuji@1
|
200 dom++; /* set position of domain part beginning */
|
yuuji@1
|
201 if (dom && NULL != (vdfd = fopen (vd, "r"))) {
|
yuuji@1
|
202 int l = strlen(dom);
|
yuuji@1
|
203 int L = strlen(account);
|
yuuji@1
|
204 while ((s=fgets(buf, MAILTMPLEN, vdfd))) {
|
yuuji@1
|
205 if (p=strchr(s, '#'))
|
yuuji@1
|
206 *p = '\0'; /* zap comments */
|
yuuji@1
|
207 if (!strchr(buf, ':'))
|
yuuji@1
|
208 continue;
|
yuuji@1
|
209 while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' ')))
|
yuuji@1
|
210 s[strlen(s)-1] = '\0';
|
yuuji@1
|
211 if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */
|
yuuji@1
|
212 match = 3;
|
yuuji@1
|
213 snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account);
|
yuuji@1
|
214 break;
|
yuuji@1
|
215 }
|
yuuji@1
|
216 if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */
|
yuuji@1
|
217 match = 2;
|
yuuji@1
|
218 snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account);
|
yuuji@1
|
219 continue;
|
yuuji@1
|
220 }
|
yuuji@1
|
221 if (match < 2 && s[0] == '.') { /* if domain described in wildcard */
|
yuuji@1
|
222 if (p=strchr(s, ':')) {
|
yuuji@1
|
223 *p = '\0';
|
yuuji@1
|
224 if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) {
|
yuuji@1
|
225 if (match == 0
|
yuuji@1
|
226 || strlen(previous) < strlen(s)) {
|
yuuji@1
|
227 match = 1;
|
yuuji@1
|
228 strncpy(previous, s, MAILTMPLEN);
|
yuuji@1
|
229 snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account);
|
yuuji@1
|
230 }
|
yuuji@1
|
231 }
|
yuuji@1
|
232 }
|
yuuji@1
|
233 }
|
yuuji@1
|
234 }
|
yuuji@1
|
235 fclose(vdfd);
|
yuuji@1
|
236 if (match) {
|
yuuji@1
|
237 p = strchr(rewrite, '@');
|
yuuji@1
|
238 /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */
|
yuuji@1
|
239 if (p) {
|
yuuji@1
|
240 *p = '\0';
|
yuuji@1
|
241 }
|
yuuji@1
|
242 /* fprintf(stderr, "rwr=[%s]\n", rewrite); */
|
yuuji@1
|
243 s = malloc(strlen(rewrite)+1);
|
yuuji@1
|
244 strncpy(s, rewrite, strlen(rewrite)+1);
|
yuuji@1
|
245 memset(vd, 0, sizeof(vd));
|
yuuji@1
|
246 memset(rewrite, 0, sizeof(rewrite));
|
yuuji@1
|
247 memset(previous, 0, sizeof(previous));
|
yuuji@1
|
248 return s;
|
yuuji@1
|
249 }
|
yuuji@1
|
250 }
|
yuuji@1
|
251 /* Then, compare with locals */
|
yuuji@1
|
252 snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals");
|
yuuji@1
|
253 if (NULL != (vdfd=fopen(vd, "r"))) {
|
yuuji@1
|
254 while (s=fgets(buf, MAILTMPLEN, vdfd)) {
|
yuuji@1
|
255 if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */
|
yuuji@1
|
256 while (*s && (strrchr(s, '\r')||strrchr(s, '\n')
|
yuuji@1
|
257 ||strrchr(s, ' ')||strrchr(s, '\t'))) {
|
yuuji@1
|
258 *(s+strlen(s)-1) = '\0';
|
yuuji@1
|
259 }
|
yuuji@1
|
260 while (*s && (*s == '\t' || *s == ' ')) s++;
|
yuuji@1
|
261 if (!strncmp(s, dom, strlen(s))) { /* matches with local domain */
|
yuuji@1
|
262 int len = dom-account-1;
|
yuuji@1
|
263 p = (char*)malloc(len+1);
|
yuuji@1
|
264 memset(p, '\0', len+1);
|
yuuji@1
|
265 strncpy(p, account, len);
|
yuuji@1
|
266 return p;
|
yuuji@1
|
267 }
|
yuuji@1
|
268 }
|
yuuji@1
|
269 }
|
yuuji@1
|
270 return NULL; /* invalid domain */
|
yuuji@1
|
271 /* return account; return itself */
|
yuuji@1
|
272 }
|
yuuji@1
|
273
|
yuuji@1
|
274 void apopcall(char **args) {
|
yuuji@1
|
275 int i=0, sc=0;
|
yuuji@1
|
276 pid_t pid;
|
yuuji@1
|
277 char *email="", *suffix="", *pass="", *new="", *new2 = "", *home="";
|
yuuji@1
|
278 char buf[BUFSIZ], auth, *user;
|
yuuji@1
|
279 FILE *child, *result;
|
yuuji@1
|
280 while (args[i][0]) {
|
yuuji@1
|
281 /* printf("[%s]<br>\n", args[i]); */
|
yuuji@1
|
282 if (!strncmp("email=", args[i], 6)) {
|
yuuji@1
|
283 email = args[i]+6;
|
yuuji@1
|
284 } else if (!strncmp("suffix=", args[i], 7)) {
|
yuuji@1
|
285 suffix = args[i]+7;
|
yuuji@1
|
286 } else if (!strncmp("pass=", args[i], 5)) {
|
yuuji@1
|
287 pass = args[i]+5;
|
yuuji@1
|
288 } else if (!strncmp("new=", args[i], 4)) {
|
yuuji@1
|
289 new = args[i]+4;
|
yuuji@1
|
290 } else if (!strncmp("new2=", args[i], 5)) {
|
yuuji@1
|
291 new2 = args[i]+5;
|
yuuji@1
|
292 } else if (!strncmp("auth=", args[i], 5)) {
|
yuuji@1
|
293 /* "this" or "base" or "unix" */
|
yuuji@1
|
294 auth = args[i][5];
|
yuuji@1
|
295 }
|
yuuji@1
|
296 i++;
|
yuuji@1
|
297 }
|
yuuji@1
|
298 /* Make a backup of original e-mail address */
|
yuuji@1
|
299 /* user = (char*)malloc(1+strlen(email));
|
yuuji@1
|
300 strcpy(user, email);
|
yuuji@1
|
301 */
|
yuuji@1
|
302 user = conv_virtualdomain(email);
|
yuuji@1
|
303 if (NULL == user) {
|
yuuji@1
|
304 printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@'));
|
yuuji@1
|
305 printf("入力したメイルアドレスを確認してやり直してください.<br>\n");
|
yuuji@1
|
306 fail();
|
yuuji@1
|
307 }
|
yuuji@1
|
308 if (strchr(user, XADDR_DELIM)) {
|
yuuji@1
|
309 char *p = malloc(1+strlen(user));
|
yuuji@1
|
310 char *q = NULL;
|
yuuji@1
|
311 struct passwd *pwd;
|
yuuji@1
|
312 /* printf("user=[%s]<br>\n", user); */
|
yuuji@1
|
313
|
yuuji@1
|
314 memset(p, '\0', 1+strlen(user));
|
yuuji@1
|
315 strcpy(p, user);
|
yuuji@1
|
316 while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) {
|
yuuji@1
|
317 fflush(stdout);
|
yuuji@1
|
318 *q = '\0';
|
yuuji@1
|
319 }
|
yuuji@1
|
320 if (pwd && q) {
|
yuuji@1
|
321 q = user+(q-p)+1;
|
yuuji@1
|
322 user=p;
|
yuuji@1
|
323 suffix=q;
|
yuuji@1
|
324 }
|
yuuji@1
|
325 }
|
yuuji@1
|
326 if (user[0] && new[0] && new2[0]) {
|
yuuji@1
|
327 int tochild[2], toparent[2];
|
yuuji@1
|
328 pid_t pid;
|
yuuji@1
|
329 int argc=0;
|
yuuji@1
|
330 char **argv;
|
yuuji@1
|
331 struct passwd *pswd;
|
yuuji@1
|
332 char *pstr;
|
yuuji@1
|
333
|
yuuji@1
|
334 if (!(pswd=getpwnam(user))) {
|
yuuji@1
|
335 printf("Unkown user %s.\n", user);
|
yuuji@1
|
336 fflush(stdout);
|
yuuji@1
|
337 fail();
|
yuuji@1
|
338 }
|
yuuji@1
|
339 pstr = pswd->pw_passwd;
|
yuuji@1
|
340 #ifdef SHADOW_PASSWD
|
yuuji@1
|
341 { struct spwd *ss = getspnam(user);
|
yuuji@1
|
342 pstr = (char*)ss->sp_pwdp;
|
yuuji@1
|
343 }
|
yuuji@1
|
344 #endif
|
yuuji@1
|
345 home=pswd->pw_dir;
|
yuuji@1
|
346 argv = (char**)calloc(4, sizeof(char*));
|
yuuji@1
|
347 argv[argc++] = "apoppasswd";
|
yuuji@1
|
348 argv[argc++] = "-s";
|
yuuji@1
|
349 argv[argc++] = "-c";
|
yuuji@1
|
350 /* if old password does not exist,
|
yuuji@1
|
351 then check UNIX password */
|
yuuji@1
|
352 #if 0
|
yuuji@1
|
353 if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */
|
yuuji@1
|
354 /* そのまま */
|
yuuji@1
|
355 } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */
|
yuuji@1
|
356 argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
|
yuuji@1
|
357 argv[argc++] = "-b";
|
yuuji@1
|
358 }
|
yuuji@1
|
359 #endif
|
yuuji@1
|
360 switch (auth) {
|
yuuji@1
|
361 case 'b': case 'B':
|
yuuji@1
|
362 if (apopfile_existp(home, "", pswd->pw_uid)) {
|
yuuji@1
|
363 argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
|
yuuji@1
|
364 argv[argc++] = "-b";
|
yuuji@1
|
365 } else {
|
yuuji@1
|
366 printf("基本アドレスのパスワードファイルがありません<br>\n");
|
yuuji@1
|
367 fail();
|
yuuji@1
|
368 }
|
yuuji@1
|
369 break;
|
yuuji@1
|
370 case 'u': case 'U':
|
yuuji@1
|
371 if (strcmp(pstr, (char*)crypt(pass, pstr))) {
|
yuuji@1
|
372 printf("UNIX Password not correct.<br>\n");
|
yuuji@1
|
373 /* printf("[%s]vs.[%s]<br>\n",
|
yuuji@1
|
374 pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */
|
yuuji@1
|
375 printf("UNIXパスワードと一致しません.<br>\n");
|
yuuji@1
|
376 fflush(stdout);
|
yuuji@1
|
377 fail();
|
yuuji@1
|
378 }
|
yuuji@1
|
379 }
|
yuuji@1
|
380
|
yuuji@1
|
381 if (strlen(new) < 8 || strlen(new2) < 8) {
|
yuuji@1
|
382 printf("New mail password must be more than 7 characters.<br>\n");
|
yuuji@1
|
383 printf("メイルパスワードは8文字以上にしてください。<br>\n");
|
yuuji@1
|
384 fflush(stdout);
|
yuuji@1
|
385 fail();
|
yuuji@1
|
386 }
|
yuuji@1
|
387 if (suffix[0]) {
|
yuuji@1
|
388 argv = (char**)realloc(argv, (argc+3)*sizeof(char*));
|
yuuji@1
|
389 argv[argc++] = "-e";
|
yuuji@1
|
390 argv[argc++] = suffix;
|
yuuji@1
|
391
|
yuuji@1
|
392 }
|
yuuji@1
|
393 argv[argc++] = NULL;
|
yuuji@1
|
394 if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) {
|
yuuji@1
|
395 printf("Cannot switch to %s\n", user);
|
yuuji@1
|
396 printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid);
|
yuuji@1
|
397 printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n");
|
yuuji@1
|
398 printf("お手数ですがこの画面のコピーを添えてシステム管理者");
|
yuuji@1
|
399 printf("まで御連絡下さい。<br>\n");
|
yuuji@1
|
400 fflush(stdout);
|
yuuji@1
|
401 fail();
|
yuuji@1
|
402 }
|
yuuji@1
|
403
|
yuuji@1
|
404 /* OK, start apopasswd */
|
yuuji@1
|
405 if (pipe(tochild)+pipe(toparent)) {
|
yuuji@1
|
406 printf("Cannot create pipe\n");
|
yuuji@1
|
407 fail();
|
yuuji@1
|
408 }
|
yuuji@1
|
409 if ((pid=fork()) > 0) {
|
yuuji@1
|
410 FILE *child = fdopen(tochild[1], "w");
|
yuuji@1
|
411 close(tochild[0]);
|
yuuji@1
|
412 close(toparent[1]);
|
yuuji@1
|
413 fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n",
|
yuuji@1
|
414 pass, new, new2);
|
yuuji@1
|
415 fflush(child);
|
yuuji@1
|
416 fclose(child);
|
yuuji@1
|
417
|
yuuji@1
|
418 } else if (pid == -1) {
|
yuuji@1
|
419 printf("Cannot fork\n");
|
yuuji@1
|
420 fail();
|
yuuji@1
|
421 } else {
|
yuuji@1
|
422 char *pe = malloc(6+strlen(pswd->pw_dir));
|
yuuji@1
|
423 close(tochild[1]);
|
yuuji@1
|
424 close(toparent[0]);
|
yuuji@1
|
425 dup2(tochild[0], 0);
|
yuuji@1
|
426 dup2(toparent[1], 1);
|
yuuji@1
|
427
|
yuuji@1
|
428 /* setuid section */
|
yuuji@1
|
429
|
yuuji@1
|
430 strcpy(pe, "HOME=");
|
yuuji@1
|
431 strcat(pe, pswd->pw_dir);
|
yuuji@1
|
432 if (putenv(pe)) {
|
yuuji@1
|
433 puts("ga-n! arichan gakkari<br>");
|
yuuji@1
|
434 }
|
yuuji@1
|
435 execv(APOPPASSWD, argv);
|
yuuji@1
|
436
|
yuuji@1
|
437 /* setuid section ends */
|
yuuji@1
|
438 fprintf(stderr, "Cannot exec %s\n", APOPPASSWD);
|
yuuji@1
|
439 fail();
|
yuuji@1
|
440 }
|
yuuji@1
|
441 result = fdopen(toparent[0], "r");
|
yuuji@1
|
442 while (fgets(buf, BUFSIZ, result)) {
|
yuuji@1
|
443 printf("%s<br>", buf);
|
yuuji@1
|
444 fflush(stdout);
|
yuuji@1
|
445 if (strstr(buf, "Success!")) {
|
yuuji@1
|
446 printf("<br>Mail Password changed successfully!<br>\n");
|
yuuji@1
|
447 sc++;
|
yuuji@1
|
448 break;
|
yuuji@1
|
449 } else if (strstr(buf, "mismatch")) {
|
yuuji@1
|
450 printf("二個入れた新パスワードが一致しません.<br>\n");
|
yuuji@1
|
451 break;
|
yuuji@1
|
452 } else if (strstr(buf, "Illegal")) {
|
yuuji@1
|
453 printf("照合用パスワードが違います.<br>--\n");
|
yuuji@1
|
454 break;
|
yuuji@1
|
455 } else if (strstr(buf, "does not exist")) {
|
yuuji@1
|
456 /* try_overwrite(user, pass, new, new2, suffix); */
|
yuuji@1
|
457 if (suffix[0]) {
|
yuuji@1
|
458 printf("%s-%s", user, suffix);
|
yuuji@1
|
459 } else {
|
yuuji@1
|
460 printf("%s", user);
|
yuuji@1
|
461 }
|
yuuji@1
|
462 /* ここは来ないことになった(のはず) */
|
yuuji@1
|
463 printf("というメイルアカウントは未作成です<br>\n");
|
yuuji@1
|
464 printf("新規に作る場合はOKボタンをクリック\n");
|
yuuji@1
|
465 put_form(email, pass, new, new2, suffix, 1, 0, 1);
|
yuuji@1
|
466 fflush(stdout);
|
yuuji@1
|
467 }
|
yuuji@1
|
468 }
|
yuuji@1
|
469 fclose(result);
|
yuuji@1
|
470 while (wait(0) != pid) {sleep(1);fputc('.', stderr);}
|
yuuji@1
|
471 if (sc) success(email); else fail();
|
yuuji@1
|
472 } else if (user[0]) {
|
yuuji@1
|
473 struct passwd *pw = getpwnam(user);
|
yuuji@1
|
474 int auth=0;
|
yuuji@1
|
475 if (!pw) {
|
yuuji@1
|
476 printf("そのようなユーザはいません %s<br>\n", user);
|
yuuji@1
|
477 fail();
|
yuuji@1
|
478 }
|
yuuji@1
|
479 home=pw->pw_dir;
|
yuuji@1
|
480
|
yuuji@1
|
481 printf("%s というメイルアドレスの<br>\n", email);
|
yuuji@1
|
482 printf("メイル専用パスワードを変更します.<br>\n");
|
yuuji@1
|
483 printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n");
|
yuuji@1
|
484 printf("新パスワードは8文字以上にしてください.<br>\n");
|
yuuji@1
|
485 printf("New password must be more than or equal to 8 characters.<br>\n");
|
yuuji@1
|
486 if (apopfile_existp(home, suffix, pw->pw_uid)) {
|
yuuji@1
|
487 auth = 0; /* this password file */
|
yuuji@1
|
488 printf("「古いメイルパスワード」には、現在<br>\n");
|
yuuji@1
|
489 printf("<tt>%s</tt><br>\n", email);
|
yuuji@1
|
490 printf("を読むために指定しているパスワードを入力します。");
|
yuuji@1
|
491 } else if (apopfile_existp(home, "", pw->pw_uid)) {
|
yuuji@1
|
492 auth = 1; /* basic mail address password */
|
yuuji@1
|
493 printf("今回は本人認証として基本メイルアドレスのパスワードを");
|
yuuji@1
|
494 printf("入力しますが、新しくパスワードを設定するのは<br>\n");
|
yuuji@1
|
495 printf("<tt>%s</tt><br>\n", email);
|
yuuji@1
|
496 printf("用のパスワードです。基本メイルアドレスのパスワードは");
|
yuuji@1
|
497 printf("変わりませんので注意してください。");
|
yuuji@1
|
498 } else {
|
yuuji@1
|
499 auth = 2; /* UNIX login */
|
yuuji@1
|
500 }
|
yuuji@1
|
501 put_form(email, "", "", "", suffix, 0, auth, 0);
|
yuuji@1
|
502 footer();
|
yuuji@1
|
503 exit(0);
|
yuuji@1
|
504 }
|
yuuji@1
|
505 printf("user=[%s]\n", user);
|
yuuji@1
|
506 }
|
yuuji@1
|
507
|
yuuji@1
|
508 int main(int argc, char* argv[]) {
|
yuuji@1
|
509 char *method = getenv("REQUEST_METHOD");
|
yuuji@1
|
510 char **args;
|
yuuji@1
|
511 myname = argv[0];
|
yuuji@1
|
512 if (method && strcmp(method, "POST") != 0) {
|
yuuji@1
|
513 printf("This program should be used in method:POST.\n");
|
yuuji@1
|
514 fail();
|
yuuji@1
|
515 }
|
yuuji@1
|
516 printf("Content-type: text/html; charset=EUC-JP\n\n");
|
yuuji@1
|
517 printf("<html>\n<head><title>Change Password</title></head>\n");
|
yuuji@1
|
518 printf("<body style=\"background: #f0ffff;\">\n");
|
yuuji@1
|
519 if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) {
|
yuuji@1
|
520 args = decode_post();
|
yuuji@1
|
521 apopcall(args);
|
yuuji@1
|
522 } else {
|
yuuji@1
|
523 printf("This program can be used only via SSL connection.<br>\n");
|
yuuji@1
|
524 printf("このユーティリティはSSL接続時のみ有効です.<br>\n");
|
yuuji@1
|
525 }
|
yuuji@1
|
526 }
|