Back to index

courier  0.68.2
auth.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2006 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 
00007 /*
00008 */
00009 
00010 #include      "sqwebmail.h"
00011 #include      "config.h"
00012 
00013 #if    HAVE_SYS_STAT_H
00014 #include      <sys/stat.h>
00015 #endif
00016 #if HAVE_SYS_WAIT_H
00017 #include      <sys/wait.h>
00018 #endif
00019 
00020 #if    HAVE_UNISTD_H
00021 #include      <unistd.h>
00022 #endif
00023 
00024 #include      <stdio.h>
00025 #include      <stdlib.h>
00026 #include      <ctype.h>
00027 #include      <courierauth.h>
00028 #if    HAVE_UNISTD_H
00029 #include      <unistd.h>
00030 #endif
00031 #include      <string.h>
00032 #include      <errno.h>
00033 
00034 #include      "maildir/loginexec.h"
00035 #include      "courierauthdebug.h"
00036 #include      "auth.h"
00037 #include      "htmllibdir.h"
00038 
00039 extern int check_sqwebpass(const char *);
00040 
00041 extern char *sqwebmail_content_charset, *sqwebmail_system_charset;
00042 #include      "unicode/unicode.h"
00043 
00044 const char *myhostname()
00045 {
00046 char    buf[512];
00047 static char *my_hostname=0;
00048 FILE   *f;
00049 
00050        if (my_hostname == 0)
00051        {
00052               buf[0]=0;
00053               if ((f=fopen(HOSTNAMEFILE, "r")) != 0)
00054               {
00055               char *p;
00056 
00057                      if (fgets(buf, sizeof(buf), f) == NULL)
00058                             buf[0]=0;
00059 
00060                      fclose(f);
00061 
00062                      if ((p=strchr(buf, '\n')) != 0)
00063                             *p=0;
00064               }
00065 
00066               if (buf[0] == 0 && gethostname(buf, sizeof(buf)-1))
00067                      strcpy(buf, "localhost");
00068 
00069               if ((my_hostname=malloc(strlen(buf)+1)) == 0)
00070                      enomem();
00071               strcpy(my_hostname, buf);
00072        }
00073        return (my_hostname);
00074 }
00075 
00076 static int login_maildir(const char *maildir)
00077 {
00078        if (!maildir || !*maildir)
00079               maildir=getenv("MAILDIRPATH");
00080        if (!maildir || !*maildir)
00081               maildir="Maildir";
00082        if (chdir(maildir))  return (-1);
00083        maildir_loginexec();
00084        return (0);
00085 }
00086 
00087 static int doauthlogin(struct authinfo *a, void *vp)
00088 {
00089        const char *p=auth_getoption(a->options ? a->options:"",
00090                                  "disablewebmail");
00091        const char *c=(const char *)vp;
00092 
00093        static char *authaddr=NULL;
00094        static char *authfullname=NULL;
00095        static char *authoptions=NULL;
00096        static char *authenticated=NULL;
00097        const char *n;
00098        char *b;
00099        int rc;
00100 
00101 
00102        if (p && atoi(p))
00103               return -1;
00104 
00105        if ((rc = auth_callback_default(a)) != 0)
00106        {
00107               if (rc > 0)
00108                      perror("ERR: authentication error");
00109               return -1;
00110        }
00111 
00112        if (login_maildir(a->maildir))
00113        {
00114               error("Unable to open the maildir for this account -- the maildir doesn't exist or has incorrect ownership or permissions.");
00115               return (-1);
00116        }
00117 
00118        b=malloc(sizeof("AUTHADDR=")+strlen(c));
00119 
00120        if (!b)
00121               enomem();
00122        strcat(strcpy(b, "AUTHADDR="), c);
00123        putenv(b);
00124        if (authaddr)
00125               free(authaddr);
00126        authaddr=b;
00127 
00128 
00129        n=a->fullname;
00130        if (!n) n="";
00131        b=malloc(sizeof("AUTHFULLNAME=")+strlen(n));
00132 
00133        if (!b)
00134               enomem();
00135        strcat(strcpy(b, "AUTHFULLNAME="), n);
00136        putenv(b);
00137        if (authfullname)
00138               free(authfullname);
00139        authfullname=b;
00140 
00141        n=a->options;
00142        if (!n) n="";
00143 
00144        b=malloc(sizeof("OPTIONS=")+strlen(n));
00145 
00146        if (!b)
00147               enomem();
00148        strcat(strcpy(b, "OPTIONS="), n);
00149        putenv(b);
00150        if (authoptions)
00151               free(authoptions);
00152        authoptions=b;
00153 
00154        n=a->address;
00155        if (!n) n="";
00156 
00157        b=malloc(sizeof("AUTHENTICATED=")+strlen(n));
00158 
00159        if (!b)
00160               enomem();
00161        strcat(strcpy(b, "AUTHENTICATED="), n);
00162        putenv(b);
00163        if (authenticated)
00164               free(authenticated);
00165        authenticated=b;
00166 
00167        return (0);
00168 }
00169 
00170 const char *do_login(const char *u, const char *p, const char *ip)
00171 {
00172        if (auth_login("webmail", u, p, doauthlogin, (void *)u))
00173        {
00174               courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s]",
00175                               u?u:"", ip);
00176               return NULL;
00177        }
00178 
00179        fprintf(stderr, "INFO: LOGIN, user=%s, ip=[%s]\n", u, ip);
00180        return u;
00181 }
00182 
00183 int nochangepass()
00184 {
00185        if (auth_getoptionenvint("wbnochangepass")) return 1;
00186        if (access(SQWEBPASSWD, X_OK)) return 1;
00187        return 0;
00188 }
00189 
00190 /*
00191 ** login_changepwd tries to call the password change function for the
00192 ** authentication module.
00193 **
00194 ** Returns -1 if authentication module does not have a password change
00195 ** function.
00196 **
00197 ** Returns 0 if the authentication module has a password change function.
00198 **
00199 ** *rc is set to 0 if password was changed, non-zero otherwise
00200 */
00201 
00202 int login_changepwd(const char *u, const char *oldpwd, const char *newpwd,
00203                   int *rc)
00204 {
00205        if (nochangepass())
00206               return -1;
00207 
00208        *rc= -1;
00209 
00210        if (changepw("webmail", u, oldpwd, newpwd) == 0)
00211        {
00212               *rc=0;
00213        }
00214        return 0;
00215 }
00216 
00217 int prelogin(const char *u)
00218 {
00219        return auth_getuserinfo("webmail", u, doauthlogin, (void *)u);
00220 }
00221 
00222 const char *login_returnaddr()
00223 {
00224        static char *addrbuf=0;
00225        const char *p, *domain="";
00226        
00227        if ((p=getenv("AUTHENTICATED")) == NULL || *p == 0)
00228               p=getenv("AUTHADDR");
00229        if (!p)       p="";
00230        if (strchr(p, '@') == 0)
00231               domain=myhostname();
00232 
00233        if (addrbuf)  free(addrbuf);
00234        addrbuf=malloc(strlen(domain)+strlen(p)+2);
00235        if (!addrbuf) enomem();
00236 
00237        strcpy(addrbuf, p);
00238        if (*domain)
00239               strcat(strcat(addrbuf, "@"), domain);
00240        return (addrbuf);
00241 }
00242 
00243 const char *login_fromhdr()
00244 {
00245 const char *address=login_returnaddr();
00246 const char *fullname=getenv("AUTHFULLNAME");
00247 int    l;
00248 const char *p;
00249 char   *q;
00250 
00251 static char *hdrbuf=0;
00252 
00253 FILE *fp;
00254 char authcharset[128];
00255 char *ufullname=0;
00256 static char *uhdrbuf=0;
00257 
00258        if (!fullname || !*fullname)
00259               return (address);    /* That was easy */
00260 
00261        authcharset[0] = 0;
00262        if ((fp=fopen(AUTHCHARSET, "r")))
00263        {
00264               char *p;
00265               if (fgets(authcharset, sizeof(authcharset), fp) == NULL)
00266                      authcharset[0]=0;
00267               fclose(fp);
00268 
00269               if ((p=strchr(authcharset, '\n')))
00270                      *p = '\0';
00271        }
00272 
00273        if (authcharset[0] == 0
00274            && sqwebmail_system_charset && *sqwebmail_system_charset
00275            && strcasecmp(sqwebmail_system_charset, "ASCII"))
00276               strncat(authcharset, sqwebmail_system_charset,
00277                      sizeof(authcharset)-1);
00278 
00279        if (authcharset[0]
00280            && sqwebmail_content_charset && *sqwebmail_content_charset
00281            && (ufullname=libmail_u_convert_toutf8(fullname, authcharset,NULL)))
00282               fullname = ufullname;
00283 
00284        l=sizeof("\"\" <>")+strlen(address)+strlen(fullname);
00285 
00286        for (p=fullname; *p; p++)
00287               if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
00288                      *p == '<' || *p == '>')     ++l;
00289 
00290        for (p=address; *p; p++)
00291               if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
00292                      *p == '<' || *p == '>')     ++l;
00293 
00294        if (hdrbuf)   free(hdrbuf);
00295        hdrbuf=malloc(l);
00296        if (!hdrbuf)  enomem();
00297        q=hdrbuf;
00298        *q++='"';
00299        for (p=fullname; *p; p++)
00300        {
00301               if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
00302                      *p == '<' || *p == '>')     *q++ = '\\';
00303               *q++= *p;
00304        }
00305        *q++='"';
00306        *q++=' ';
00307        *q++='<';
00308        for (p=address; *p; p++)
00309        {
00310               if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
00311                      *p == '<' || *p == '>')     *q++ = '\\';
00312               *q++= *p;
00313        }
00314        *q++='>';
00315        *q=0;
00316 
00317        if (ufullname)       free(ufullname);
00318        if (uhdrbuf)  free(uhdrbuf);
00319        if ((uhdrbuf=libmail_u_convert_fromutf8(hdrbuf,
00320                                           sqwebmail_content_charset,
00321                                           NULL)) != NULL)
00322               return (uhdrbuf);
00323 
00324        return (hdrbuf);
00325 }
00326