summaryrefslogtreecommitdiff
path: root/src/qmail-vmailuser.c
diff options
context:
space:
mode:
authorJannis Hoffmann <jannis@fehcom.de>2024-07-09 11:44:11 +0200
committerJannis Hoffmann <jannis@fehcom.de>2024-07-09 11:44:11 +0200
commitf1b71c9fe7dbb4886588a036399cf5ebe16b7c47 (patch)
treee07786aa479c9fb6ee3e537078470aaab5454f80 /src/qmail-vmailuser.c
parenta293489ee83c8b05d845a162dc2a4de026f3775d (diff)
removed top level directory
Diffstat (limited to 'src/qmail-vmailuser.c')
-rw-r--r--src/qmail-vmailuser.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/qmail-vmailuser.c b/src/qmail-vmailuser.c
new file mode 100644
index 0000000..a65135f
--- /dev/null
+++ b/src/qmail-vmailuser.c
@@ -0,0 +1,148 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "global.h"
+#include "qmail.h"
+#include "auto_qmail.h"
+#include "stralloc.h"
+#include "case.h"
+#include "control.h"
+#include "constmap.h"
+#include "direntry.h"
+#include "error.h"
+#include "str.h"
+#include "fmt.h"
+#include "open.h"
+#include "byte.h"
+#include "scan.h"
+#include "str.h"
+
+#define FDAUTH 3
+#define RESPECT_CASE "-C"
+
+/** @file qmail-vmailuser.c
+ @return 0: virtual user exists
+ 1: virtual user dir not accessible
+ 2: qmail-vmailuser is misused
+ 110: can't read controls
+ 111: temporary problem
+*/
+
+char inputbuf[BUFSIZE_AUTH];
+struct constmap mapvdoms;
+stralloc vdoms = {0};
+stralloc vdomdir = {0};
+stralloc vuser = {0};
+stralloc vuserdir = {0};
+
+void pam_exit(int fail)
+{
+ int i;
+
+ close(FDAUTH);
+ for (i = 0; i < sizeof(inputbuf); ++i) inputbuf[i] = 0;
+ _exit(fail);
+}
+
+int main(int argc,char **argv)
+{
+ DIR *dir;
+ char *vdomuser;
+ char *domain = 0;
+ int buflen = 0;
+ int domlen = 0;
+ int flagrespect = 0;
+ int i, r;
+ char ch;
+ char *homedir = "/home";
+
+ if (argv[1])
+ if (!case_diffs(argv[1],RESPECT_CASE)) {
+ flagrespect = 1;
+ } else {
+ homedir = argv[1];
+ dir = opendir(homedir);
+ if (!dir) pam_exit(2);
+ }
+
+ if (argv[2])
+ if (!case_diffs(argv[2],RESPECT_CASE)) flagrespect = 1;
+
+ if (chdir(auto_qmail) == -1) pam_exit(110);
+
+ switch (control_readfile(&vdoms,"control/virtualdomains",0)) {
+ case -1: pam_exit(110);
+ case 0: if (!constmap_init(&mapvdoms,"",0,1)) pam_exit(111);
+ case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) pam_exit(111);
+ }
+
+ for (;;) { /* read input */
+ do
+ r = read(FDAUTH,inputbuf + buflen,sizeof(inputbuf) - buflen);
+ while ((r == -1) && (errno == EINTR));
+ if (r == -1) pam_exit(111);
+ if (r == 0) break;
+ buflen += r;
+ if (buflen >= sizeof(inputbuf)) pam_exit(2);
+ }
+ close(FDAUTH);
+
+ if ((r = byte_rchr(inputbuf,buflen,'@'))) /* @domain */
+ if (r < buflen && inputbuf[r] == '@') {
+ domain = inputbuf + r + 1;
+ domlen = str_len(domain);
+ if (!flagrespect)
+ case_lowerb(inputbuf,buflen);
+ else
+ case_lowerb(domain,domlen);
+ }
+ vdomuser = constmap(&mapvdoms,domain,domlen);
+ if (!vdomuser) pam_exit(1);
+
+ if (!stralloc_copys(&vuser,"")) pam_exit(111); /* user */
+ for (i = 0; i < r; ++i) {
+ ch = inputbuf[i];
+ if (ch == '.') ch = ':';
+ if (!stralloc_append(&vuser,&ch)) pam_exit(111);
+ }
+ if (!stralloc_0(&vuser)) pam_exit(111);
+
+ if (!stralloc_copys(&vdomdir,homedir)) pam_exit(111); /* vpopmail */
+ if (!stralloc_cats(&vdomdir,"/")) pam_exit(111);
+ if (!stralloc_cats(&vdomdir,"vpopmail")) pam_exit(111);
+ if (!stralloc_copy(&vuserdir,&vdomdir)) pam_exit(111);
+ if (!stralloc_cats(&vuserdir,"/domains/")) pam_exit(111);
+ if (!stralloc_cats(&vuserdir,vdomuser)) pam_exit(111);
+ if (!stralloc_copy(&vdomdir,&vuserdir)) pam_exit(111);
+ if (!stralloc_0(&vdomdir)) pam_exit(111);
+
+ dir = opendir(vdomdir.s);
+ if (dir) {
+ if (!stralloc_cats(&vuserdir,"/")) pam_exit(111);
+ if (!stralloc_cat(&vuserdir,&vuser)) pam_exit(111);
+ if (!stralloc_0(&vuserdir)) pam_exit(111);
+
+ dir = opendir(vuserdir.s);
+ if (dir) pam_exit(0);
+ }
+
+ if (!stralloc_copys(&vdomdir,homedir)) pam_exit(111); /* vmailmgr */
+ if (!stralloc_cats(&vdomdir,"/")) pam_exit(111);
+ if (!stralloc_copy(&vuserdir,&vdomdir)) pam_exit(111);
+ if (!stralloc_cats(&vuserdir,vdomuser)) pam_exit(111);
+ if (!stralloc_cats(&vuserdir,"/users")) pam_exit(111);
+ if (!stralloc_copy(&vdomdir,&vuserdir)) pam_exit(111);
+ if (!stralloc_0(&vdomdir)) pam_exit(111);
+
+ dir = opendir(vdomdir.s);
+ if (dir) {
+ if (!stralloc_cats(&vuserdir,"/")) pam_exit(111);
+ if (!stralloc_cat(&vuserdir,&vuser)) pam_exit(111);
+ if (!stralloc_0(&vuserdir)) pam_exit(111);
+
+ dir = opendir(vuserdir.s);
+ if (dir) pam_exit(0);
+ }
+
+ pam_exit(1);
+}