Download | Plain Text | Line Numbers


we want to support authentification with aliases but still need to know the real
username. checkpassword will write us the real user back on fd4. we need to read
that and update the smtp auth username accordingly
--- qmail-smtpd.c.orig	2009-01-31 01:43:01.000000000 +0100
+++ qmail-smtpd.c	2010-10-05 14:10:54.000000000 +0200
@@ -859,7 +859,9 @@
 
 char **childargs;
 char ssauthbuf[512];
+char ssauth2buf[512];
 substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf));
+substdio ssauth2 = SUBSTDIO_FDBUF(saferead,4,ssauth2buf,sizeof(ssauth2buf));
 
 int authgetl(void) {
   int i;
@@ -885,6 +887,9 @@
   int child;
   int wstat;
   int pi[2];
+  int piauth[2], i, len;
+  char *arg;
+  static stralloc authout = {0}, authparams = {0};
 
   if (!stralloc_0(&user)) die_nomem();
   if (!stralloc_0(&pass)) die_nomem();
@@ -893,19 +898,24 @@
 #endif
 
   if (pipe(pi) == -1) return err_pipe();
+  if (pipe(piauth) == -1) return err_pipe();
   switch(child = fork()) {
     case -1:
       return err_fork();
     case 0:
       close(pi[1]);
+      close(piauth[0]);
       if(fd_copy(3,pi[0]) == -1) return err_pipe();
+      if(fd_copy(4,piauth[1]) == -1) return err_pipe();
       sig_pipedefault();
         execvp(*childargs, childargs);
       _exit(1);
   }
   close(pi[0]);
+  close(piauth[1]);
 
   substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf);
+  substdio_fdbuf(&ssauth2,read,piauth[0],ssauth2buf,sizeof ssauth2buf);
   if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write();
   if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write();
 #ifdef CRAM_MD5
@@ -914,11 +924,43 @@
   if (substdio_flush(&ssauth) == -1) return err_write();
 
   close(pi[1]);
+
+  if (!stralloc_copys(&authout, "")) die_nomem();
+  for (;;) {
+    if (!stralloc_readyplus(&authout, 1)) die_nomem();
+    i = substdio_get(&ssauth2, authout.s + authout.len, 1);
+    if (i == 0) break;
+    ++authout.len;
+  }
+  authout.s[authout.len] = 0;
+  if (substdio_flush(&ssauth2) == -1) return err_write();
+  close(piauth[0]);
+
+  if (authout.len > 0) {
+    len = authout.len;
+    arg = authout.s;
+    if (!stralloc_copys(&authparams, "")) die_nomem;
+    while (len) {
+      if (*arg == '\0') {
+        if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) {
+          if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem();
+          if (!stralloc_0(&user)) die_nomem();
+        }
+        if (!stralloc_copys(&authparams, "")) die_nomem;
+      }
+      else
+        if (!stralloc_catb(&authparams, arg, 1)) die_nomem;
+      arg++;
+      len--;
+    }
+  }
+
 #ifdef CRAM_MD5
   if (!stralloc_copys(&chal,"")) die_nomem();
   if (!stralloc_copys(&slop,"")) die_nomem();
 #endif
   byte_zero(ssauthbuf,sizeof ssauthbuf);
+  byte_zero(ssauth2buf,sizeof ssauth2buf);
   if (wait_pid(&wstat,child) == -1) return err_child();
   if (wait_crashed(wstat)) return err_child();
   if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */