imapext-2007

diff APOPtools/apopcall.c @ 4:d741b3ecc917

imapext-2007f
author HIROSE Yuuji <yuuji@gentei.org>
date Thu, 30 Oct 2014 00:03:05 +0900
parents 28a55bc1110c
children
line diff
     1.1 --- a/APOPtools/apopcall.c	Mon Sep 14 19:23:11 2009 +0900
     1.2 +++ b/APOPtools/apopcall.c	Thu Oct 30 00:03:05 2014 +0900
     1.3 @@ -524,3 +524,529 @@
     1.4          printf("このユーティリティはSSL接続時のみ有効です.<br>\n");
     1.5      }
     1.6  }
     1.7 +#include <stdio.h>
     1.8 +#include <stdlib.h>
     1.9 +#include <string.h>
    1.10 +#include <unistd.h>
    1.11 +#include <sys/types.h>
    1.12 +#include <sys/wait.h>
    1.13 +#include <sys/stat.h>
    1.14 +#include <pwd.h>
    1.15 +#ifdef SHADOW_PASSWD
    1.16 +#include <shadow.h>
    1.17 +#endif
    1.18 +
    1.19 +#ifndef APOPPASSWD
    1.20 +#define APOPPASSWD "/usr/local/bin/apoppasswd"
    1.21 +#endif
    1.22 +#ifndef APOPFILEBASE
    1.23 +#define APOPFILEBASE ".apop"
    1.24 +#endif
    1.25 +#ifndef XADDR_DELIM
    1.26 +#define XADDR_DELIM ('-')
    1.27 +#endif
    1.28 +
    1.29 +char *myname;
    1.30 +
    1.31 +int ishexa(int c) {
    1.32 +    strchr("0123456789ABCDFabcdef", c) ? 1 : 0;
    1.33 +}
    1.34 +
    1.35 +put_form(email, pass, new, new2, suffix, hidden, auth, force)
    1.36 +     char *email, *pass, *new, *new2, *suffix;
    1.37 +     int hidden, auth, force;
    1.38 +     /* auth = 0: old password
    1.39 +               1: base addresse's mail password
    1.40 +               2: unix password */
    1.41 +{
    1.42 +    char *authtype[] = {"old", "base", "unix"};
    1.43 +    char *var[] = {"email", "pass", "new", "new2", "auth", ""};
    1.44 +    char *val[] = {email, pass, new, new2, authtype[auth]};
    1.45 +    char *prm[] = {"",  /* "ユーザ名", */
    1.46 +                   auth ? 
    1.47 +                   ((auth==1)
    1.48 +                    ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address"
    1.49 +                    : "UNIXログインパスワード<br>UNIX login Password")
    1.50 +                   : "古いメイルパスワード<br>Old Mail Password",
    1.51 +                   "新しいメイルパスワード<br>New Mail Password",
    1.52 +                   "新パスワードをもう一回(確認)<br>New Mail Password Again",
    1.53 +		   ""};
    1.54 +    int h=0, i;
    1.55 +
    1.56 +    printf("<form method=POST action\"./%s\">\n", myname);
    1.57 +    printf(" <table border=1>\n");
    1.58 +    for (i=0; var[i][0]; i++) {
    1.59 +        h = hidden || strstr("email,suffix,auth", var[i]);
    1.60 +	if (prm[i][0]) {
    1.61 +            printf("<tr><td>%s</td><td>", prm[i]);
    1.62 +	} else {
    1.63 +	}
    1.64 +        printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n",
    1.65 +               var[i],
    1.66 +               h ? "type=hidden "
    1.67 +               : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"),
    1.68 +               val[i]);
    1.69 +        if (!strcmp(var[i], "suffix")) {
    1.70 +            /* ここでは suffix を入れさせない方がいいかも */
    1.71 +	    /* 表向きのメイルアドレスを表示しておく */
    1.72 +            printf("%s", email);
    1.73 +            /* if (suffix[0]) {
    1.74 +                printf("-%s", suffix);
    1.75 +            } */
    1.76 +            if (auth)
    1.77 +                printf("<br>(新規作成:New Account)");
    1.78 +        }
    1.79 +	if (prm[i][0])
    1.80 +          printf("</td></tr>");
    1.81 +	printf("\n");
    1.82 +    }
    1.83 +    
    1.84 +    printf("</table>\n");
    1.85 +    if (force)
    1.86 +        printf("<input name=force type=hidden value=ON>\n");
    1.87 +    if (auth) {
    1.88 +        char *a[] = {"basic", "unix"};
    1.89 +        printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]);
    1.90 +    }
    1.91 +    printf("<input name=OK value=OK type=submit>\n");
    1.92 +    printf("<input name=RESET value=RESET type=reset>\n");
    1.93 +    printf("</form>\n");
    1.94 +    fflush(stdout);
    1.95 +}
    1.96 +
    1.97 +char *decode(char *code) {
    1.98 +    int l=1+strlen(code);
    1.99 +    int i, c, d;
   1.100 +    char *ret = (char*)malloc(l*sizeof(char));
   1.101 +    char *p = code;
   1.102 +    memset(ret, 0, l);
   1.103 +    for (i=0; i<strlen(code); i++) {
   1.104 +	if (code[i] == '+') code[i] = ' ';
   1.105 +    }
   1.106 +    while (code[0] && (p=strchr(code, '%'))
   1.107 +           && ishexa(*(p+1)) && ishexa(*(p+2))) {
   1.108 +        *(p++) = '\0';
   1.109 +        strncat(ret, code, l);
   1.110 +        c = (islower(*p) ? toupper(*p) : *p) - '0';
   1.111 +        p++;
   1.112 +        d = (islower(*p) ? toupper(*p) : *p) - '0';
   1.113 +        if (c > 9) c -= ('A'-'9'-1);
   1.114 +        if (d > 9) d -= ('A'-'9'-1);
   1.115 +        ret[strlen(ret)] = c*16+d;
   1.116 +        code = p+1;
   1.117 +    }
   1.118 +    if (code[0]) strncat(ret, code, l);
   1.119 +    return ret;
   1.120 +}
   1.121 +
   1.122 +#define BSIZE	8192
   1.123 +char **decode_post() {
   1.124 +    char *buf = (char*)malloc(BSIZE*sizeof(char));
   1.125 +    char **post, *p = buf;
   1.126 +    int n=0, i;
   1.127 +    post = (char**)calloc(1, sizeof(char*));
   1.128 +    *buf = '\0';
   1.129 +    fgets(buf, BSIZE, stdin);
   1.130 +    if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */
   1.131 +        buf[strlen(buf)-1] = '\0';
   1.132 +    while (buf[0] && NULL != (p=strchr(buf, '&'))) {
   1.133 +        *p = '\0';
   1.134 +        post[n] = (char*)malloc((p-buf+1)*sizeof(char));
   1.135 +        strcpy(post[n], buf);
   1.136 +        n++;
   1.137 +        post = (char**)realloc(post, (1+n)*sizeof(char*));
   1.138 +        buf = 1+p;
   1.139 +    }
   1.140 +    if (buf[0]) post[n++] = buf;
   1.141 +    /* decode URL encoded */
   1.142 +    for (i=0; i < n; i++) {
   1.143 +        char *p;
   1.144 +        p=post[i];
   1.145 +        post[i] = decode(p);
   1.146 +    }
   1.147 +    post[i] = "";               /* terminator */
   1.148 +    return post;
   1.149 +}
   1.150 +
   1.151 +void footer() {
   1.152 +    puts("</body>\n</html>");
   1.153 +    fflush(stdout);
   1.154 +}
   1.155 +
   1.156 +void fail() {
   1.157 +    printf("パスワード更新に失敗しました<br>\n");
   1.158 +    printf("<a href=\"./\">やり直し</a><br>\n");
   1.159 +    footer();
   1.160 +    exit(1);
   1.161 +}
   1.162 +void success(char *email) {
   1.163 +    printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n",
   1.164 +           email);
   1.165 +    footer();
   1.166 +    exit(0);
   1.167 +}
   1.168 +
   1.169 +int apopfile_existp(char *home, char *suffix, uid_t uid) {
   1.170 +    struct stat st;
   1.171 +    int s;
   1.172 +    int len = strlen(home) + 1
   1.173 +        + strlen(APOPFILEBASE) + strlen(suffix) + 3;
   1.174 +    char *apopfile = (char*)malloc(len);
   1.175 +    if (suffix[0]) {
   1.176 +        snprintf(apopfile, len, "%s/%s%c%s%c",
   1.177 +                 home, APOPFILEBASE, XADDR_DELIM, suffix, 0);
   1.178 +    } else {
   1.179 +        snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0);
   1.180 +    }
   1.181 +    seteuid(uid);
   1.182 +    s = stat(apopfile, &st);
   1.183 +    seteuid(0);
   1.184 +    memset(apopfile, '\0', strlen(apopfile));
   1.185 +    free(apopfile);
   1.186 +    return !s;
   1.187 +}
   1.188 +
   1.189 +#ifndef QMAILCONTROL
   1.190 +# define QMAILCONTROL "/var/qmail/control"
   1.191 +#endif
   1.192 +#ifndef MAILTMPLEN
   1.193 +# define MAILTMPLEN 1024
   1.194 +#endif
   1.195 +
   1.196 +/* Convert virtual domain user
   1.197 + */
   1.198 +char* conv_virtualdomain(char *account) {
   1.199 +  char *dom = strchr(account, '@'), *p;
   1.200 +  char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1];
   1.201 +  FILE *vdfd;
   1.202 +  int match=0;
   1.203 +  char buf[MAILTMPLEN+1], *s;
   1.204 +  snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains");
   1.205 +  if (NULL == dom) return account;
   1.206 +  dom++;		/* set position of domain part beginning */
   1.207 +  if (dom && NULL != (vdfd = fopen (vd, "r"))) {
   1.208 +    int l = strlen(dom);
   1.209 +    int L = strlen(account);
   1.210 +    while ((s=fgets(buf, MAILTMPLEN, vdfd))) {
   1.211 +      if (p=strchr(s, '#'))
   1.212 +        *p = '\0';			/* zap comments */
   1.213 +      if (!strchr(buf, ':'))
   1.214 +        continue;
   1.215 +      while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' ')))
   1.216 +        s[strlen(s)-1] = '\0';
   1.217 +      if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */
   1.218 +	match = 3;
   1.219 +        snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account);
   1.220 +	break;
   1.221 +      }
   1.222 +      if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */
   1.223 +        match = 2;
   1.224 +	snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account);
   1.225 +	continue;
   1.226 +      }
   1.227 +      if (match < 2 && s[0] == '.') { /* if domain described in wildcard */
   1.228 +        if (p=strchr(s, ':')) {
   1.229 +	  *p = '\0';
   1.230 +	  if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) {
   1.231 +	    if (match == 0
   1.232 +	        || strlen(previous) < strlen(s)) {
   1.233 +	      match = 1;
   1.234 +	      strncpy(previous, s, MAILTMPLEN);
   1.235 +	      snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account);
   1.236 +	    }
   1.237 +	  }
   1.238 +	}
   1.239 +      }
   1.240 +    }
   1.241 +    fclose(vdfd);
   1.242 +    if (match) {
   1.243 +      p = strchr(rewrite, '@');
   1.244 +      /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */
   1.245 +      if (p) {
   1.246 +        *p = '\0';
   1.247 +      }
   1.248 +      /* fprintf(stderr, "rwr=[%s]\n", rewrite); */
   1.249 +      s = malloc(strlen(rewrite)+1);
   1.250 +      strncpy(s, rewrite, strlen(rewrite)+1);
   1.251 +      memset(vd, 0, sizeof(vd));
   1.252 +      memset(rewrite, 0, sizeof(rewrite));
   1.253 +      memset(previous, 0, sizeof(previous));
   1.254 +      return s;
   1.255 +    }
   1.256 +  }
   1.257 +  /* Then, compare with locals */
   1.258 +  snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals");
   1.259 +  if (NULL != (vdfd=fopen(vd, "r"))) {
   1.260 +    while (s=fgets(buf, MAILTMPLEN, vdfd)) {
   1.261 +      if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */
   1.262 +	while (*s && (strrchr(s, '\r')||strrchr(s, '\n')
   1.263 +			||strrchr(s, ' ')||strrchr(s, '\t'))) {
   1.264 +	  *(s+strlen(s)-1) = '\0';
   1.265 +	}
   1.266 +	while (*s && (*s == '\t' || *s == ' ')) s++;
   1.267 +	if (!strncmp(s, dom, strlen(s))) {	/* matches with local domain */
   1.268 +	  int len = dom-account-1;
   1.269 +	  p = (char*)malloc(len+1);
   1.270 +	  memset(p, '\0', len+1);
   1.271 +	  strncpy(p, account, len);
   1.272 +	  return p;
   1.273 +	}
   1.274 +      }
   1.275 +  }
   1.276 +  return NULL; /* invalid domain */
   1.277 +  /* return account; return itself */
   1.278 +}
   1.279 +
   1.280 +void apopcall(char **args) {
   1.281 +    int i=0, sc=0;
   1.282 +    pid_t pid;
   1.283 +    char *email="", *suffix="", *pass="", *new="", *new2 = "", *home="";
   1.284 +    char buf[BUFSIZ], auth, *user;
   1.285 +    FILE *child, *result;
   1.286 +    while (args[i][0]) {
   1.287 +        /* printf("[%s]<br>\n", args[i]); */
   1.288 +        if (!strncmp("email=", args[i], 6)) {
   1.289 +            email = args[i]+6;
   1.290 +        } else if (!strncmp("suffix=", args[i], 7)) {
   1.291 +            suffix = args[i]+7;
   1.292 +        } else if (!strncmp("pass=", args[i], 5)) {
   1.293 +            pass = args[i]+5;
   1.294 +        } else if (!strncmp("new=", args[i], 4)) {
   1.295 +            new = args[i]+4;
   1.296 +        } else if (!strncmp("new2=", args[i], 5)) {
   1.297 +            new2 = args[i]+5;
   1.298 +        } else if (!strncmp("auth=", args[i], 5)) {
   1.299 +            /* "this" or "base" or "unix" */
   1.300 +            auth = args[i][5];
   1.301 +        }
   1.302 +        i++;
   1.303 +    }
   1.304 +    /* Make a backup of original e-mail address */
   1.305 +    /* user = (char*)malloc(1+strlen(email));
   1.306 +       strcpy(user, email);
   1.307 +     */
   1.308 +    user = conv_virtualdomain(email);
   1.309 +    if (NULL == user) {
   1.310 +      printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@'));
   1.311 +      printf("入力したメイルアドレスを確認してやり直してください.<br>\n");
   1.312 +      fail();
   1.313 +    }
   1.314 +    if (strchr(user, XADDR_DELIM)) {
   1.315 +	char *p = malloc(1+strlen(user));
   1.316 +	char *q = NULL;
   1.317 +	struct passwd *pwd;
   1.318 +	    /* printf("user=[%s]<br>\n", user); */
   1.319 +
   1.320 +	memset(p, '\0', 1+strlen(user));
   1.321 +	strcpy(p, user);
   1.322 +	while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) {
   1.323 +	    fflush(stdout);
   1.324 +	    *q = '\0';
   1.325 +	}
   1.326 +	if (pwd && q) {
   1.327 +	    q = user+(q-p)+1;
   1.328 +	    user=p;
   1.329 +	    suffix=q;
   1.330 +	}
   1.331 +    }
   1.332 +    if (user[0] && new[0] && new2[0]) {
   1.333 +        int tochild[2], toparent[2];
   1.334 +        pid_t pid;
   1.335 +        int argc=0;
   1.336 +        char **argv;
   1.337 +        struct passwd *pswd;
   1.338 +	char *pstr;
   1.339 +
   1.340 +        if (!(pswd=getpwnam(user))) {
   1.341 +            printf("Unkown user %s.\n", user);
   1.342 +            fflush(stdout);
   1.343 +            fail();
   1.344 +        }
   1.345 +	pstr = pswd->pw_passwd;
   1.346 +#ifdef SHADOW_PASSWD
   1.347 +	{  struct spwd *ss = getspnam(user);
   1.348 +	   pstr = (char*)ss->sp_pwdp;
   1.349 +	}
   1.350 +#endif
   1.351 +        home=pswd->pw_dir;
   1.352 +        argv = (char**)calloc(4, sizeof(char*));
   1.353 +        argv[argc++] = "apoppasswd";
   1.354 +        argv[argc++] = "-s";
   1.355 +        argv[argc++] = "-c";
   1.356 +        /* if old password does not exist,
   1.357 +           then check UNIX password */
   1.358 +#if 0
   1.359 +        if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */
   1.360 +            /* そのまま */
   1.361 +        } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */
   1.362 +            argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
   1.363 +            argv[argc++] = "-b";
   1.364 +        }
   1.365 +#endif
   1.366 +        switch (auth) {
   1.367 +        case 'b': case 'B':
   1.368 +            if (apopfile_existp(home, "", pswd->pw_uid)) {
   1.369 +                argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
   1.370 +                argv[argc++] = "-b";
   1.371 +            } else {
   1.372 +                printf("基本アドレスのパスワードファイルがありません<br>\n");
   1.373 +                fail();
   1.374 +            }
   1.375 +            break;
   1.376 +        case 'u': case 'U':
   1.377 +            if (strcmp(pstr, (char*)crypt(pass, pstr))) {
   1.378 +                printf("UNIX Password not correct.<br>\n");
   1.379 +                /* printf("[%s]vs.[%s]<br>\n",
   1.380 +                   pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */
   1.381 +                printf("UNIXパスワードと一致しません.<br>\n");
   1.382 +                fflush(stdout);
   1.383 +                fail();
   1.384 +            }
   1.385 +        }
   1.386 +
   1.387 +        if (strlen(new) < 8 || strlen(new2) < 8) {
   1.388 +            printf("New mail password must be more than 7 characters.<br>\n");
   1.389 +            printf("メイルパスワードは8文字以上にしてください。<br>\n");
   1.390 +            fflush(stdout);
   1.391 +            fail();
   1.392 +        }
   1.393 +        if (suffix[0]) {
   1.394 +            argv = (char**)realloc(argv, (argc+3)*sizeof(char*));
   1.395 +            argv[argc++] = "-e";
   1.396 +            argv[argc++] = suffix;
   1.397 +                
   1.398 +        }
   1.399 +        argv[argc++] = NULL;
   1.400 +        if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) {
   1.401 +            printf("Cannot switch to %s\n", user);
   1.402 +	    printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid);
   1.403 +	    printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n");
   1.404 +	    printf("お手数ですがこの画面のコピーを添えてシステム管理者");
   1.405 +	    printf("まで御連絡下さい。<br>\n");
   1.406 +            fflush(stdout);
   1.407 +            fail();
   1.408 +        }
   1.409 +
   1.410 +        /* OK, start apopasswd */
   1.411 +        if (pipe(tochild)+pipe(toparent)) {
   1.412 +            printf("Cannot create pipe\n");
   1.413 +            fail();
   1.414 +        }
   1.415 +        if ((pid=fork()) > 0) {
   1.416 +            FILE *child = fdopen(tochild[1], "w");
   1.417 +            close(tochild[0]);
   1.418 +            close(toparent[1]);
   1.419 +            fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n",
   1.420 +                    pass, new, new2);
   1.421 +            fflush(child);
   1.422 +            fclose(child);
   1.423 +            
   1.424 +        } else if (pid == -1) {
   1.425 +            printf("Cannot fork\n");
   1.426 +            fail();
   1.427 +        } else {
   1.428 +            char *pe = malloc(6+strlen(pswd->pw_dir));
   1.429 +            close(tochild[1]);
   1.430 +            close(toparent[0]);
   1.431 +            dup2(tochild[0], 0);
   1.432 +            dup2(toparent[1], 1);
   1.433 +
   1.434 +            /* setuid section */
   1.435 +
   1.436 +			strcpy(pe, "HOME=");
   1.437 +			strcat(pe, pswd->pw_dir);
   1.438 +            if (putenv(pe)) {
   1.439 +				puts("ga-n! arichan gakkari<br>");
   1.440 +			}
   1.441 +            execv(APOPPASSWD, argv);
   1.442 +
   1.443 +            /* setuid section ends */
   1.444 +            fprintf(stderr, "Cannot exec %s\n", APOPPASSWD);
   1.445 +            fail();
   1.446 +        }
   1.447 +        result = fdopen(toparent[0], "r");
   1.448 +        while (fgets(buf, BUFSIZ, result)) {
   1.449 +            printf("%s<br>", buf);
   1.450 +            fflush(stdout);
   1.451 +            if (strstr(buf, "Success!")) {
   1.452 +                printf("<br>Mail Password changed successfully!<br>\n");
   1.453 +                sc++;
   1.454 +                break;
   1.455 +            } else if (strstr(buf, "mismatch")) {
   1.456 +                printf("二個入れた新パスワードが一致しません.<br>\n");
   1.457 +                break;
   1.458 +            } else if (strstr(buf, "Illegal")) {
   1.459 +                printf("照合用パスワードが違います.<br>--\n");
   1.460 +                break;
   1.461 +            } else if (strstr(buf, "does not exist")) {
   1.462 +                /* try_overwrite(user, pass, new, new2, suffix); */
   1.463 +                if (suffix[0]) {
   1.464 +                    printf("%s-%s", user, suffix);
   1.465 +                } else {
   1.466 +                    printf("%s", user);
   1.467 +                }
   1.468 +                /* ここは来ないことになった(のはず) */
   1.469 +                printf("というメイルアカウントは未作成です<br>\n");
   1.470 +                printf("新規に作る場合はOKボタンをクリック\n");
   1.471 +                put_form(email, pass, new, new2, suffix, 1, 0, 1);
   1.472 +                fflush(stdout);
   1.473 +            }
   1.474 +        }
   1.475 +        fclose(result);
   1.476 +        while (wait(0) != pid) {sleep(1);fputc('.', stderr);}
   1.477 +        if (sc) success(email); else fail();
   1.478 +    } else if (user[0]) {
   1.479 +        struct passwd *pw = getpwnam(user);
   1.480 +        int auth=0;
   1.481 +        if (!pw) {
   1.482 +            printf("そのようなユーザはいません %s<br>\n", user);
   1.483 +            fail();
   1.484 +        }
   1.485 +	home=pw->pw_dir;
   1.486 +        
   1.487 +	printf("%s というメイルアドレスの<br>\n", email);
   1.488 +        printf("メイル専用パスワードを変更します.<br>\n");
   1.489 +        printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n");
   1.490 +        printf("新パスワードは8文字以上にしてください.<br>\n");
   1.491 +        printf("New password must be more than or equal to 8 characters.<br>\n");
   1.492 +        if (apopfile_existp(home, suffix, pw->pw_uid)) {
   1.493 +            auth = 0;           /* this password file */
   1.494 +	    printf("「古いメイルパスワード」には、現在<br>\n");
   1.495 +	    printf("<tt>%s</tt><br>\n", email);
   1.496 +	    printf("を読むために指定しているパスワードを入力します。");
   1.497 +        } else if (apopfile_existp(home, "", pw->pw_uid)) {
   1.498 +            auth = 1;           /* basic mail address password */
   1.499 +	    printf("今回は本人認証として基本メイルアドレスのパスワードを");
   1.500 +	    printf("入力しますが、新しくパスワードを設定するのは<br>\n");
   1.501 +	    printf("<tt>%s</tt><br>\n", email);
   1.502 +	    printf("用のパスワードです。基本メイルアドレスのパスワードは");
   1.503 +	    printf("変わりませんので注意してください。");
   1.504 +        } else {
   1.505 +            auth = 2;           /* UNIX login */
   1.506 +        }
   1.507 +        put_form(email, "", "", "", suffix, 0, auth, 0);
   1.508 +        footer();
   1.509 +        exit(0);
   1.510 +    }
   1.511 +    printf("user=[%s]\n", user);
   1.512 +}
   1.513 +
   1.514 +int main(int argc, char* argv[]) {
   1.515 +    char *method = getenv("REQUEST_METHOD");
   1.516 +    char **args;
   1.517 +    myname = argv[0];
   1.518 +    if (method && strcmp(method, "POST") != 0) {
   1.519 +        printf("This program should be used in method:POST.\n");
   1.520 +        fail();
   1.521 +    }
   1.522 +    printf("Content-type: text/html; charset=EUC-JP\n\n");
   1.523 +    printf("<html>\n<head><title>Change Password</title></head>\n");
   1.524 +    printf("<body style=\"background: #f0ffff;\">\n");
   1.525 +    if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) {
   1.526 +        args = decode_post();
   1.527 +        apopcall(args);
   1.528 +    } else {
   1.529 +        printf("This program can be used only via SSL connection.<br>\n");
   1.530 +        printf("このユーティリティはSSL接続時のみ有効です.<br>\n");
   1.531 +    }
   1.532 +}

UW-IMAP'd extensions by yuuji