Commit b5c4df4d b5c4df4d6e798c83c1ac379cf95aa5f03a9d93b4 by Sergey Poznyakoff

Virtual-domain-specific auth functions.

1 parent 7db00198
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <pwd.h>
26 #ifdef HAVE_SHADOW_H
27 # include <shadow.h>
28 #endif
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #ifdef HAVE_STRINGS_H
34 # include <strings.h>
35 #endif
36 #ifdef HAVE_SECURITY_PAM_APPL_H
37 # include <security/pam_appl.h>
38 #endif
39 #ifdef HAVE_CRYPT_H
40 # include <crypt.h>
41 #endif
42
43 #include <mailutils/list.h>
44 #include <mailutils/iterator.h>
45 #include <mailutils/mailbox.h>
46 #include <mailutils/argp.h>
47 #include <mailutils/mu_auth.h>
48
49 #ifdef USE_VIRTUAL_DOMAINS
50 struct passwd *
51 getpwnam_virtual (char *u)
52 {
53 struct passwd *pw = NULL;
54 FILE *pfile;
55 size_t i = 0, len = strlen (u), delim = 0;
56 char *filename;
57
58 mu_virtual_domain = 0;
59 for (i = 0; i < len && delim == 0; i++)
60 if (u[i] == '!' || u[i] == ':' || u[i] == '@')
61 delim = i;
62
63 if (delim == 0)
64 return NULL;
65
66 filename = malloc (strlen (SITE_VIRTUAL_PWDDIR) +
67 strlen (&u[delim + 1]) + 2 /* slash and null byte */);
68 if (filename == NULL)
69 return NULL;
70
71 sprintf (filename, "%s/%s", SITE_VIRTUAL_PWDDIR, &u[delim + 1]);
72 pfile = fopen (filename, "r");
73 free (filename);
74
75 if (pfile)
76 while ((pw = fgetpwent (pfile)) != NULL)
77 {
78 if (strlen (pw->pw_name) == delim && !strncmp (u, pw->pw_name, delim))
79 {
80 mu_virtual_domain = 1;
81 break;
82 }
83 }
84
85 return pw;
86 }
87
88 struct passwd *
89 getpwnam_ip_virtual (const char *u)
90 {
91 struct sockaddr_in addr;
92 struct passwd *pw = NULL;
93 int len = sizeof (addr);
94 char *user = NULL;
95
96 if (getsockname (fileno (ifile), (struct sockaddr *)&addr, &len) == 0)
97 {
98 char *ip;
99 char *user;
100
101 struct hostent *info = gethostbyaddr ((char *)&addr.sin_addr,
102 4, AF_INET);
103
104 if (info)
105 {
106 user = malloc (strlen (info->h_name) + strlen (u) + 2);
107 if (user)
108 {
109 sprintf (user, "%s!%s", u, info->h_name);
110 pw = getpwnam_virtual (user);
111 free (user);
112 }
113 }
114
115 if (!pw)
116 {
117 ip = inet_ntoa (addr.sin_addr);
118 user = malloc (strlen (ip) + strlen (u) + 2);
119 if (user)
120 {
121 sprintf (user, "%s!%s", u, ip);
122 pw = getpwnam_virtual (user);
123 free (user);
124 }
125 }
126 }
127 return pw;
128 }
129
130 /* Virtual domains */
131 int
132 mu_auth_virt_domain_by_name (void *return_data, void *key,
133 void *unused_func_data, void *unused_call_data)
134 {
135 int rc;
136 struct passwd *pw;
137 char *mailbox_name;
138
139 if (!key)
140 {
141 errno = EINVAL;
142 return 1;
143 }
144
145 pw = getpwnam_virtual (key);
146 if (!pw)
147 {
148 pw = getpwnam_ip_virtual (key);
149 if (!pw)
150 return 1;
151 }
152
153 mailbox_name = calloc (strlen (pw->pw_dir) + strlen ("/INBOX"), 1);
154 sprintf (mailbox_name, "%s/INBOX", pw->pw_dir);
155
156 rc = mu_auth_data_alloc ((struct mu_auth_data **) return_data,
157 pw->pw_name,
158 pw->pw_passwd,
159 pw->pw_uid,
160 pw->pw_gid,
161 pw->pw_gecos,
162 pw->pw_dir,
163 pw->pw_shell,
164 mailbox_name,
165 0);
166 free (mailbox_name);
167 return rc;
168 }
169 #else
170 int
171 mu_auth_virt_domain_by_name (void *return_data, void *key,
172 void *unused_func_data, void *unused_call_data)
173 {
174 errno = ENOSYS;
175 return 1;
176 }
177 #endif
178
179 struct mu_auth_module mu_auth_virtual_module = {
180 "virtdomain",
181 NULL,
182 mu_auth_nosupport,
183 NULL,
184 mu_auth_virt_domain_by_name,
185 NULL,
186 mu_auth_nosupport,
187 NULL
188 };
189