[tpop3d-discuss]pure virtual tpop3d authentication patch

Markus Lidel Markus.Lidel at shadowconnect.com
Fri, 02 Apr 2004 12:27:57 +0200


This is a multi-part message in MIME format.
--------------090802090009080908070401
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hello,

if you are using mysql or perl to authenticate a user, and you don't 
have an user in /etc/passwd, the user won't authenticate at all, because 
the getpwuid() call fails. So here is a patch, witch allows the 
authentication of a user with only mysql or perl.

If you have further questions, please feel free to contact me.

Best regards,


Markus Lidel
------------------------------------------
Markus Lidel (Senior IT Consultant)

Shadow Connect GmbH
Carl-Reisch-Weg 12
D-86381 Krumbach
Germany

Phone:  +49 82 82/99 51-0
Fax:    +49 82 82/99 51-11

E-Mail: Markus.Lidel@shadowconnect.com
URL:    http://www.shadowconnect.com


--------------090802090009080908070401
Content-Type: text/plain;
 name="tpop3d-1.5.3-virtual.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tpop3d-1.5.3-virtual.patch"

diff -ur tpop3d-1.5.2.old/auth_mysql.c tpop3d-1.5.2.new/auth_mysql.c
--- tpop3d-1.5.2.old/auth_mysql.c	2003-07-15 01:31:20.000000000 +0200
+++ tpop3d-1.5.2.new/auth_mysql.c	2004-04-02 12:50:18.000000000 +0200
@@ -232,8 +232,8 @@
             goto fail;
         }
 
-        if (mysql_field_count(mysql) != 4) {
-            log_print(LOG_ERR, _("auth_mysql_new_apop: %d fields returned by query, should be 4: mailbox location, password hash, unix user, mailbox type"), mysql_field_count(mysql));
+        if ((mysql_field_count(mysql) < 4) || (mysql_field_count(mysql) > 5)) {
+            log_print(LOG_ERR, "auth_mysql_new_apop: %d fields returned by query, should be 4 or 5: mailbox location, password hash, unix user, mailbox type [, home directory]", mysql_field_count(mysql));
             goto fail;
         }
 
@@ -243,8 +243,10 @@
         case 1: {
                 MYSQL_ROW row;
                 unsigned long *lengths;
-                struct passwd *pw;
+                struct passwd *pw = NULL;
+                char *home = NULL;
                 uid_t uid;
+                gid_t gid;
                 
                 row = mysql_fetch_row(result);
                 /* These are "can't happen" errors */
@@ -271,14 +273,29 @@
                     break;
                 }
 
-                pw = getpwuid(uid);
+                if (mysql_field_count(mysql) == 5) {
+                    home = (char *)row[4];
+                } else {
+                    pw = getpwuid(uid);
+                    if (!pw) {
+                        log_print(LOG_ERR, "auth_mysql_new_apop: getpwuid(%d): %m", (int)uid);
+                        break;
+                    }
+                    home = pw->pw_dir;
+                }
 
-                if (!pw) {
-                    log_print(LOG_ERR, "auth_mysql_new_apop: getpwuid(%d): %m", (int)uid);
-                    break;
+                if (use_gid) gid = mail_gid; else {
+                    if (!pw) {
+                        pw = getpwuid(uid);
+                        if (!pw) {
+                            log_print(LOG_ERR, "auth_mysql_new_apop: getpwuid(%d): %m", (int)uid);
+                            break;
+                        }
+                        gid = pw->pw_gid;
+                    }
                 }
 
-                a = authcontext_new(pw->pw_uid, use_gid ? mail_gid : pw->pw_gid, row[3], row[0], pw->pw_dir);
+                a = authcontext_new(uid, gid, row[3], row[0], home);
 
                 break;
             }
@@ -332,8 +349,8 @@
             goto fail;
         }
 
-        if (mysql_field_count(mysql) != 4) {
-            log_print(LOG_ERR, _("auth_mysql_new_user_pass: %d fields returned by query, should be 4: mailbox location, password hash, unix user, mailbox type"), mysql_field_count(mysql));
+        if ((mysql_field_count(mysql) < 4) || (mysql_field_count(mysql) > 5)) {
+            log_print(LOG_ERR, "auth_mysql_new_user_pass: %d fields returned by query, should be 4 or 5: mailbox location, password hash, unix user, mailbox type [, home directory]", mysql_field_count(mysql));
             goto fail;
         }
 
@@ -343,8 +360,10 @@
         case 1: {
                 MYSQL_ROW row;
                 unsigned long *lengths;
-                struct passwd *pw;
+                struct passwd *pw = NULL;
+                char *home = NULL;
                 uid_t uid;
+                gid_t gid;
                 
                 row = mysql_fetch_row(result);
 
@@ -371,14 +390,30 @@
                     break;
                 }
 
-                pw = getpwuid(uid);
+                if (mysql_field_count(mysql) == 5) {
+                    home = (char *)row[4];
+                } else {
+                    pw = getpwuid(uid);
+                    if (!pw) {
+                        log_print(LOG_ERR, "auth_mysql_new_user_pass: getpwuid(%d): %m", (int)uid);
+                        break;
+                    }
+                    home = pw->pw_dir;
+                }
 
-                if (!pw) {
-                    log_print(LOG_ERR, "auth_mysql_new_user_pass: getpwuid(%d): %m", (int)uid);
-                    break;
+                if (use_gid) gid = mail_gid; else {
+                    if (!pw) {
+                        pw = getpwuid(uid);
+                        if (!pw) {
+                            log_print(LOG_ERR, "auth_mysql_new_user_pass: getpwuid(%d): %m", (int)uid);
+                            break;
+                        }
+                        gid = pw->pw_gid;
+                    }
                 }
 
-                a = authcontext_new(pw->pw_uid, use_gid ? mail_gid : pw->pw_gid, row[3], row[0], pw->pw_dir);
+                a = authcontext_new(uid, gid, row[3], row[0], home);
+
                 break;
             }
 
diff -ur tpop3d-1.5.2.old/auth_other.c tpop3d-1.5.2.new/auth_other.c
--- tpop3d-1.5.2.old/auth_other.c	2003-07-15 01:31:20.000000000 +0200
+++ tpop3d-1.5.2.new/auth_other.c	2004-04-02 12:56:20.000000000 +0200
@@ -24,6 +24,7 @@
  *  result      YES or NO
  *  uid         username/uid with which to access mailspool
  *  gid         groupname/gid with which to access mailspool
+ *  home        (optional) home directory used for variable $(home)
  *  domain      (optional) domain in which the user has been authenticated
  *  mailbox     (optional) location of mailbox
  *  mboxtype    (optional) name of mailbox driver
@@ -505,16 +506,13 @@
     if (strcmp((char*)I->v, "YES") == 0) {
         uid_t uid;
         gid_t gid;
-        struct passwd *pw;
-        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL;
+        struct passwd *pw = NULL;
+        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL, *home = NULL;
 
         I = stringmap_find(S, "uid");
         if (!I) MISSING("uid");
         else if (!parse_uid(I->v, &uid)) INVALID("uid", (char*)I->v);
  
-        pw = getpwuid(uid);
-        if (!pw) INVALID("uid", (char*)I->v);
-       
         I = stringmap_find(S, "gid");
         if (!I) MISSING("gid");
         else if (!parse_gid(I->v, &gid)) INVALID("gid", (char*)I->v);
@@ -528,7 +526,14 @@
         I = stringmap_find(S, "domain");
         if (I) domain = (char*)I->v;
 
-        a = authcontext_new(uid, gid, mboxdrv, mailbox, pw->pw_dir);
+        I = stringmap_find(S, "home");
+        if (I) home = (char*)I->v; else {
+            pw = getpwuid(uid);
+            if (!pw) INVALID("uid", (char*)I->v);
+            home = pw->pw_dir;
+        }
+
+        a = authcontext_new(uid, gid, mboxdrv, mailbox, home);
     } else if (strcmp((char*)I->v, "NO") != 0) INVALID("result", (char*)I->v);
         
 fail:
@@ -567,16 +572,13 @@
     if (strcmp((char*)I->v, "YES") == 0) {
         uid_t uid;
         gid_t gid;
-        struct passwd *pw;
-        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL;
+        struct passwd *pw = NULL;
+        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL, *home = NULL;
 
         I = stringmap_find(S, "uid");
         if (!I) MISSING("uid");
         else if (!parse_uid(I->v, &uid)) INVALID("uid", (char*)I->v);
  
-        pw = getpwuid(uid);
-        if (!pw) INVALID("uid", (char*)I->v);
-       
         I = stringmap_find(S, "gid");
         if (!I) MISSING("gid");
         else if (!parse_gid(I->v, &gid)) INVALID("gid", (char*)I->v);
@@ -590,7 +592,14 @@
         I = stringmap_find(S, "domain");
         if (I) domain = (char*)I->v;
 
-        a = authcontext_new(uid, gid, mboxdrv, mailbox, pw->pw_dir);
+        I = stringmap_find(S, "home");
+        if (I) home = (char*)I->v; else {
+            pw = getpwuid(uid);
+            if (!pw) INVALID("uid", (char*)I->v);
+            home = pw->pw_dir;
+        }
+
+        a = authcontext_new(uid, gid, mboxdrv, mailbox, home);
     } else if (strcmp((char*)I->v, "NO") != 0) INVALID("result", (char*)I->v);
         
 fail:
diff -ur tpop3d-1.5.2.old/auth_perl.c tpop3d-1.5.2.new/auth_perl.c
--- tpop3d-1.5.2.old/auth_perl.c	2003-08-25 19:51:25.000000000 +0200
+++ tpop3d-1.5.2.new/auth_perl.c	2004-04-02 12:57:55.000000000 +0200
@@ -263,16 +263,13 @@
     if (strcmp((char*)I->v, "YES") == 0) {
         uid_t uid;
         gid_t gid;
-        struct passwd *pw;
-        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL;
+        struct passwd *pw = NULL;
+        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL, *home = NULL;
 
         I = stringmap_find(S, "uid");
         if (!I) MISSING("uid");
         else if (!parse_uid(I->v, &uid)) INVALID("uid", (char*)I->v);
  
-        pw = getpwuid(uid);
-        if (!pw) INVALID("uid", (char*)I->v);
-       
         I = stringmap_find(S, "gid");
         if (!I) MISSING("gid");
         else if (!parse_gid(I->v, &gid)) INVALID("gid", (char*)I->v);
@@ -286,7 +283,14 @@
         I = stringmap_find(S, "domain");
         if (I) domain = (char*)I->v;
 
-        a = authcontext_new(uid, gid, mboxdrv, mailbox, pw->pw_dir);
+        I = stringmap_find(S, "home");
+        if (I) home = (char*)I->v; else {
+            pw = getpwuid(uid);
+            if (!pw) INVALID("uid", (char*)I->v);
+            home = pw->pw_dir;
+        }
+
+        a = authcontext_new(uid, gid, mboxdrv, mailbox, home);
     } else if (strcmp((char*)I->v, "NO") != 0) INVALID("result", (char*)I->v);
         
 fail:
@@ -322,16 +326,13 @@
     if (strcmp((char*)I->v, "YES") == 0) {
         uid_t uid;
         gid_t gid;
-        struct passwd *pw;
-        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL;
+        struct passwd *pw = NULL;
+        char *mailbox = NULL, *mboxdrv = NULL, *domain = NULL, *home = NULL;
 
         I = stringmap_find(S, "uid");
         if (!I) MISSING("uid");
         else if (!parse_uid(I->v, &uid)) INVALID("uid", (char*)I->v);
  
-        pw = getpwuid(uid);
-        if (!pw) INVALID("uid", (char*)I->v);
-       
         I = stringmap_find(S, "gid");
         if (!I) MISSING("gid");
         else if (!parse_gid(I->v, &gid)) INVALID("gid", (char*)I->v);
@@ -345,7 +346,14 @@
         I = stringmap_find(S, "domain");
         if (I) domain = (char*)I->v;
 
-        a = authcontext_new(uid, gid, mboxdrv, mailbox, pw->pw_dir);
+        I = stringmap_find(S, "home");
+        if (I) home = (char*)I->v; else {
+            pw = getpwuid(uid);
+            if (!pw) INVALID("uid", (char*)I->v);
+            home = pw->pw_dir;
+        }
+
+        a = authcontext_new(uid, gid, mboxdrv, mailbox, home);
     } else if (strcmp((char*)I->v, "NO") != 0) INVALID("result", (char*)I->v);
         
 fail:
diff -ur tpop3d-1.5.2.old/tpop3d.conf.5 tpop3d-1.5.2.new/tpop3d.conf.5
--- tpop3d-1.5.2.old/tpop3d.conf.5	2003-08-26 01:54:27.000000000 +0200
+++ tpop3d-1.5.2.new/tpop3d.conf.5	2004-04-02 12:58:50.000000000 +0200
@@ -690,6 +690,9 @@
 \fBdomain\fP = \fIdomain\fP
 The domain in which the user has been authenticated.
 .TP
+\fBhome\fP = \fIhome\fP
+The home directory to be used for $(home).
+.TP
 \fBmailbox\fP = \fIpath\fP
 Path of this user's mailbox.
 .TP

--------------090802090009080908070401--