courier reading virtusertable?

Discussion in 'Tips/Tricks/Mods' started by lerra, Jun 22, 2006.

  1. lerra

    lerra New Member

    Is it not posseble to do this? Login with username@domain? Yes i know that ISPconfig uses system accounts and not sql based for example.
    But how about make courier read from virtusertable and match it to the system account?
    Is it not posseble to doit with authdaemon? authdaemon does all the accounts checkup, right?
    So i was woundering if sombody have lookt in to this and saw that it was imposseble.
    I see authcustom in authmodule..

    Thanks ISPconfig devteam for all the work! great package!
     
  2. falko

    falko Super Moderator

    It will be hard because even if you make Courier look up the email address in the ISPConfig database, the password is missing because it is in /etc/shadow...
     
  3. aod

    aod New Member

    Sorry to bump this old thread, but I am in the process of trying to do the exact same thing that the OP is asking about. Courier must already be authenticating against /etc/shadow as it sits now. All that needs to be done is have courier check the virtusertable so when someone wants to login as user@domain, it maps it to the correct system account and authenticates via that system account. Pretty much exactly how webmail, roundcube, and squirrelmail are doing it now. I'm assuming a change would have to be made to authdaemon in order for this to work. I'm doing some searching for any patches out there, but am having no luck. I'd think that someone else out there has needed this functionality even before ISPConfig was created. I'm pretty well versed in C programming, so I may just have to create my own patch. If I do, I'll post it up here.

    Thanks for the great work you guys are doing on the ISPConfig project! Keep it up! :)
     
  4. falko

    falko Super Moderator

    That sounds interesting. :)
     
  5. aod

    aod New Member

    Well, here it is. It is kind of a mess because I don't know how to modify configure files in order to tell it to include LIBS=-ldb in the Makefile, so I just added it to the Makefile before compiling. If you use this patch, you should run configure first, then patch everything, then compile. I did this on OpenSUSE 10.0, so you may need to make other changes to get it to work if you aren't using OpenSUSE 10.0. When configuring, I had to use the --with-authdaemonvar=/var/run/authdaemon.courier-imap/ option in order to tell it to put the socket file in there. After compiling and installing (make; make install), I had to copy authdaemond from /usr/local/libexec/courier-authlib/ to /usr/lib/courier-authlib/authdaemond (if you are running courier-authdaemon, it will need to be stopped before copying. /etc/init.d/courier-authdaemon stop). After copying, restart it with /etc/init.d/courier-authdaemon start. That's it, you should now be able to login to POP3 and IMAP with the person's email address. :) Hopefully someone can fix up the configure script to make this an easier/nicer install. You can download version 0.58 of the authlib here: http://www.courier-mta.org/?download.php and apply the patch to it after configuring.

    Patch is below:

    Code:
    diff -u'rNF^function' courier-authlib-0.58/Makefile courier-authlib-0.58-virt/Makefile
    --- courier-authlib-0.58/Makefile       2006-09-09 23:48:31.000000000 -0700
    +++ courier-authlib-0.58-virt/Makefile  2006-09-09 20:51:48.000000000 -0700
    @@ -309,7 +309,7 @@
     LIBLTDL = -lltdl
     LIBM = -lm
     LIBOBJS =
    -LIBS =
    +LIBS = -ldb
     LIBTOOL = $(SHELL) $(top_builddir)/libtool
     LN_S = ln -s
     LTDLINCL =
    diff -u'rNF^function' courier-authlib-0.58/courier_auth_config.h courier-authlib-0.58-virt/courier_auth_config.h
    --- courier-authlib-0.58/courier_auth_config.h  2006-09-09 23:48:31.000000000 -0700
    +++ courier-authlib-0.58-virt/courier_auth_config.h     2006-09-09 22:05:19.000000000 -0700
    @@ -168,3 +168,6 @@
    
     /* Define to `int' if <sys/types.h> doesn't define. */
     /* #undef uid_t */
    +
    +/* Set this to where your virtusertable.db is */
    +#define VIRTUSERTABLE "/etc/postfix/virtusertable.db"
    diff -u'rNF^function' courier-authlib-0.58/preauthpwd.c courier-authlib-0.58-virt/preauthpwd.c
    --- courier-authlib-0.58/preauthpwd.c   2004-10-20 17:10:49.000000000 -0700
    +++ courier-authlib-0.58-virt/preauthpwd.c      2006-09-10 02:22:04.000000000 -0700
    @@ -11,6 +11,7 @@
     #include       <string.h>
     #include       <errno.h>
     #include       <pwd.h>
    +#include       <db.h>
     #if    HAVE_UNISTD_H
     #include       <unistd.h>
     #endif
    @@ -26,19 +27,65 @@
     {
     struct authinfo auth;
     struct passwd *pw;
    +DB *dbp;
    +DBT key, data;
    +char *useridptr=0;
    
            memset(&auth, 0, sizeof(auth));
    
            if ((pw=getpwnam(userid)) == 0)
            {
    -               if (errno == ENOMEM)    return (1);
    -               return (-1);
    +               if (errno == ENOMEM)    return 1;
    +
    +               /* Translate /etc/postfix/virtusertable to system account */
    +               if ((db_create(&dbp, NULL, 0)))
    +                       return 1;
    +
    +               if ((dbp->open(dbp, NULL, VIRTUSERTABLE, NULL, DB_HASH, DB_RDONLY, 0600)))
    +               {
    +                       dbp->close(dbp, 0);
    +                       return 1;
    +               }
    +
    +               memset(&key, 0, sizeof(key));
    +               memset(&data, 0, sizeof(data));
    +
    +               useridptr = strdup(userid);
    +
    +               key.data = useridptr;
    +               key.size = strlen(useridptr)+1;
    +
    +               if ((dbp->get(dbp, NULL, &key, &data, 0)))
    +               {
    +                       dbp->close(dbp, 0);
    +                       return -1;
    +               }
    +
    +               if ((pw=getpwnam(data.data)) == 0)
    +               {
    +                       dbp->close(dbp, 0);
    +                       return -1;
    +               }
    +
    +               free(useridptr);
    +               useridptr = strdup(data.data);
    +
    +               dbp->close(dbp, 0);
    +       }
    +
    +       if (useridptr)
    +       {
    +               auth.sysusername=useridptr;
    +               auth.address=useridptr;
    +       }
    +       else
    +       {
    +               auth.sysusername=userid;
    +               auth.address=userid;
            }
    
    -       auth.sysusername=userid;
            auth.sysgroupid=pw->pw_gid;
            auth.homedir=pw->pw_dir;
    -       auth.address=userid;
            auth.fullname=pw->pw_gecos;
            auth.passwd=pw->pw_passwd;
    
    diff -u'rNF^function' courier-authlib-0.58/preauthshadow.c courier-authlib-0.58-virt/preauthshadow.c
    --- courier-authlib-0.58/preauthshadow.c        2005-11-16 18:29:03.000000000 -0700
    +++ courier-authlib-0.58-virt/preauthshadow.c   2006-09-10 02:22:42.000000000 -0700
    @@ -18,7 +18,7 @@
     #if    HAVE_SHADOW_H
     #include       <shadow.h>
     #endif
    -
    +#include       <db.h>
    
     #include       "auth.h"
     #include       "courierauthdebug.h"
    @@ -33,16 +33,58 @@
     struct passwd *pw;
     struct spwd *spw;
     long today;
    +DB *dbp;
    +DBT key, data;
    +char *useridptr=0;
    
            memset(&auth, 0, sizeof(auth));
    
            if ((pw=getpwnam(userid)) == NULL)
            {
                    if (errno == ENOMEM)    return 1;
    -               return -1;
    +
    +               /* Translate /etc/postfix/virtusertable to system account */
    +               if ((db_create(&dbp, NULL, 0)))
    +                       return 1;
    +
    +               if ((dbp->open(dbp, NULL, VIRTUSERTABLE, NULL, DB_HASH, DB_RDONLY, 0600)))
    +               {
    +                       dbp->close(dbp, 0);
    +                       return 1;
    +               }
    +
    +               memset(&key, 0, sizeof(key));
    +               memset(&data, 0, sizeof(data));
    +
    +               useridptr = strdup(userid);
    +
    +               key.data = useridptr;
    +               key.size = strlen(useridptr)+1;
    +
    +               if ((dbp->get(dbp, NULL, &key, &data, 0)))
    +               {
    +                       dbp->close(dbp, 0);
    +                       return -1;
    +               }
    +
    +               if ((pw=getpwnam(data.data)) == 0)
    +               {
    +                       dbp->close(dbp, 0);
    +                       return -1;
    +               }
    +
    +               free(useridptr);
    +               useridptr = strdup(data.data);
    +
    +               dbp->close(dbp, 0);
            }
    
    -       if ((spw=getspnam(userid)) == NULL)
    +       if ((useridptr) && ((spw=getspnam(useridptr)) == NULL))
    +       {
    +               if (errno == ENOMEM)    return 1;
    +               return -1;
    +       }
    +       else if ((!useridptr) && ((spw=getspnam(userid)) == NULL))
            {
                    if (errno == ENOMEM)    return 1;
                    return -1;
    @@ -63,10 +105,18 @@
                    return -1;                      /* password expired */
            }
    
    -       auth.sysusername=userid;
    +       if (useridptr)
    +       {
    +               auth.sysusername=useridptr;
    +               auth.address=useridptr;
    +       }
    +       else
    +       {
    +               auth.sysusername=userid;
    +               auth.address=userid;
    +       }
            auth.sysgroupid=pw->pw_gid;
            auth.homedir=pw->pw_dir;
    -       auth.address=userid;
            auth.fullname=pw->pw_gecos;
            auth.passwd=spw->sp_pwdp;
    Enjoy!

    P.S. One last thing that would need to be changed in the configure script is putting that VIRTUSERTABLE define in the courier_auth_config.h file.
     
    Last edited: Sep 10, 2006
  6. aod

    aod New Member

    Well, one thing I've noticed now is that auth on postfix cannot authenticate via email address either. Has anyone gotten that authentication working via email address instead of system account?

    Thanks.
     

Share This Page