s/qmail 4.3.20
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-vmailuser.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4#include "global.h"
5#include "qmail.h"
6#include "auto_qmail.h"
7#include "stralloc.h"
8#include "case.h"
9#include "control.h"
10#include "constmap.h"
11#include "direntry.h"
12#include "error.h"
13#include "getoptb.h"
14#include "str.h"
15#include "fmt.h"
16#include "open.h"
17#include "byte.h"
18#include "scan.h"
19#include "str.h"
20#include "error.h"
21
22#define FDAUTH 3
23
34stralloc vdoms = {0};
35stralloc vdomdir = {0};
36stralloc vuser = {0};
37stralloc vuserdir = {0};
38
39int pam_exit(int fail)
40{
41 int i;
42
43 close(FDAUTH);
44 for (i = 0; i < sizeof(inputbuf); ++i) inputbuf[i] = 0;
45 _exit(fail);
46}
47
48int main(int argc,char * const *argv)
49{
50 DIR *dir;
51 char *vdomuser;
52 char *domain = 0;
53 int buflen = 0;
54 int domlen = 0;
55 int flagrespect = 0;
56 int flagvpopmail = 1;
57 int flagvmailmgr = 1;
58 int flagunixuser = 1;
59 int opt;
60 int r;
61 char ch;
62 char *homedir = "/home";
63
64 while ((opt = getoptb(argc,(char **)argv,"cCMPU")) != opteof)
65 switch (opt) {
66 case 'c': flagrespect = 0; break;
67 case 'C': flagrespect = 1; break;
68 case 'M': flagvpopmail = 0; flagunixuser = 0; break; // only vmailmgr
69 case 'P': flagunixuser = 0; flagvmailmgr = 0; break; // only vpopmail
70 case 'U': flagvpopmail = 0; flagvmailmgr = 0; break; // only unix virtual user
71 }
72 argv += optind;
73 argc -= optind;
74
75 if (argv && *argv) {
76 homedir = *argv;
77 dir = opendir(homedir);
78 if (!dir) pam_exit(2);
79 }
80
81 if (chdir(auto_qmail) == -1) pam_exit(110);
82
83 switch (control_readfile(&vdoms,"control/virtualdomains",0)) {
84 case -1: pam_exit(110);
85 case 0: if (!constmap_init(&mapvdoms,"",0,1)) pam_exit(111);
86 case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) pam_exit(111);
87 }
88
89 for (;;) { /* read input */
90 do
91 r = read(FDAUTH,inputbuf + buflen,sizeof(inputbuf) - buflen);
92 while ((r == -1) && (errno == EINTR));
93 if (r == -1) pam_exit(111);
94 if (r == 0) break;
95 buflen += r;
96 if (buflen >= sizeof(inputbuf)) pam_exit(2);
97 }
98 close(FDAUTH);
99
100 if ((r = byte_rchr(inputbuf,buflen,'@'))) /* @domain */
101 if (r < buflen && inputbuf[r] == '@') {
102 domain = inputbuf + r + 1;
103 domlen = str_len(domain);
104 if (!flagrespect)
105 case_lowerb(inputbuf,buflen);
106 else
107 case_lowerb(domain,domlen);
108 }
109 vdomuser = constmap(&mapvdoms,domain,domlen);
110 if (!vdomuser) pam_exit(1);
111
112 if (!stralloc_copys(&vuser,"")) pam_exit(111); /* user */
113 for (int i = 0; i < r; ++i) {
114 ch = inputbuf[i];
115 if (ch == '.') ch = ':';
116 if (!stralloc_append(&vuser,&ch)) pam_exit(111);
117 }
118 if (!stralloc_0(&vuser)) pam_exit(111);
119
120 if (!case_diffs(vdomuser,vuser.s)) pam_exit(1); /* trivial case */
121
122 if (flagvpopmail) { /* vpopmail */
124 if (!stralloc_cats(&vdomdir,"/")) pam_exit(111);
125 if (!stralloc_cats(&vdomdir,"vpopmail")) pam_exit(111);
126 if (!stralloc_copy(&vuserdir,&vdomdir)) pam_exit(111);
127 if (!stralloc_cats(&vuserdir,"/domains/")) pam_exit(111);
128 if (!stralloc_cats(&vuserdir,vdomuser)) pam_exit(111);
129 if (!stralloc_cats(&vuserdir,"/")) pam_exit(111);
130 if (!stralloc_copy(&vdomdir,&vuser)) pam_exit(111);
131 if (!stralloc_0(&vdomdir)) pam_exit(111);
132
133 dir = opendir(vdomdir.s);
134 if (dir) {
135 if (!stralloc_cats(&vuserdir,"/")) pam_exit(111);
136 if (!stralloc_cats(&vuserdir,vuser.s)) pam_exit(111);
137 if (!stralloc_0(&vuserdir)) pam_exit(111);
138
139 dir = opendir(vuserdir.s);
140 if (dir && !errno) pam_exit(0);
141 }
142 pam_exit(1);
143 }
144
145 if (flagvmailmgr) { /* vmailmgr */
147 if (!stralloc_cats(&vdomdir,"/")) pam_exit(111);
148 if (!stralloc_copy(&vuserdir,&vdomdir)) pam_exit(111);
149 if (!stralloc_cats(&vuserdir,vdomuser)) pam_exit(111);
150 if (!stralloc_cats(&vuserdir,"/users/")) pam_exit(111);
151 if (!stralloc_copy(&vdomdir,&vuserdir)) pam_exit(111);
152 if (!stralloc_0(&vdomdir)) pam_exit(111); // /home/vdomuser/users/
153
154 dir = opendir(vdomdir.s);
155 if (dir) {
156 if (!stralloc_cats(&vuserdir,vuser.s)) pam_exit(111);
157 if (!stralloc_0(&vuserdir)) pam_exit(111);
158
159 dir = opendir(vuserdir.s);
160 if (dir) pam_exit(0);
161 }
162 pam_exit(1);
163 }
164
165 if (flagunixuser) { /* standard virtual unix user */
167 if (!stralloc_cats(&vdomdir,"/")) pam_exit(111);
168 if (!stralloc_cats(&vdomdir,vdomuser)) pam_exit(111);
169 if (!stralloc_0(&vdomdir)) pam_exit(111);
170
171 dir = opendir(vdomdir.s);
172 if (dir) pam_exit(0);
173 }
174
175 return pam_exit(1);
176}
char auto_qmail[]
int main()
Definition: chkshsgr.c:6
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
Definition: constmap.c:35
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:87
int stralloc_copys(stralloc *, char const *)
void _exit(int)
stralloc homedir
stralloc vdomdir
stralloc vdoms
stralloc vuser
stralloc vuserdir
char inputbuf[BUFSIZE_AUTH]
#define FDAUTH
int pam_exit(int fail)
struct constmap mapvdoms
#define BUFSIZE_AUTH
Definition: qmail.h:9
stralloc domain
Definition: spf.c:34