Commit 33737423 3373742327451a83f03946e47d0dd512295303f0 by Sergey Poznyakoff

Switched to the new authentication/authorization functions.

1 parent 257c5cda
...@@ -585,27 +585,19 @@ change_user (const char *user) ...@@ -585,27 +585,19 @@ change_user (const char *user)
585 char * 585 char *
586 mailbox_path (const char *user) 586 mailbox_path (const char *user)
587 { 587 {
588 struct passwd *pw; 588 struct mu_auth_data *auth;
589 char *mailbox_name; 589 char *mailbox_name;
590 590
591 pw = mu_getpwnam (user); 591 auth = mu_get_auth_by_name (user);
592 if (!pw) 592
593 if (!auth)
593 { 594 {
594 syslog (LOG_ALERT, "user nonexistent: %s", user); 595 syslog (LOG_ALERT, "user nonexistent: %s", user);
595 return NULL; 596 return NULL;
596 } 597 }
597 598
598 if (!mu_virtual_domain) 599 mailbox_name = strdup (auth->mailbox);
599 { 600 mu_auth_data_free (auth);
600 mailbox_name = calloc (strlen (mu_path_maildir) + 1 +
601 strlen (pw->pw_name) + 1, 1);
602 sprintf (mailbox_name, "%s%s", mu_path_maildir, pw->pw_name);
603 }
604 else
605 {
606 mailbox_name = calloc (strlen (pw->pw_dir) + strlen ("/INBOX"), 1);
607 sprintf (mailbox_name, "%s/INBOX", pw->pw_dir);
608 }
609 return mailbox_name; 601 return mailbox_name;
610 } 602 }
611 603
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
65 (define (sieve-expand-filename filename) 65 (define (sieve-expand-filename filename)
66 (case (string-ref filename 0) 66 (case (string-ref filename 0)
67 ((#\~) 67 ((#\~)
68 (let ((pw (mu_getpwuid (geteuid)))) 68 (let ((pw (mu-getpwuid (geteuid))))
69 (if (and (vector? pw) 69 (if (and (vector? pw)
70 (let ((dir (vector-ref pw 5))) 70 (let ((dir (vector-ref pw 5)))
71 (and 71 (and
......
...@@ -29,7 +29,7 @@ struct imap_auth { ...@@ -29,7 +29,7 @@ struct imap_auth {
29 { NULL, NULL } 29 { NULL, NULL }
30 }; 30 };
31 31
32 int 32 void
33 imap4d_auth_capability () 33 imap4d_auth_capability ()
34 { 34 {
35 struct imap_auth *ap; 35 struct imap_auth *ap;
...@@ -59,18 +59,18 @@ imap4d_authenticate (struct imap4d_command *command, char *arg) ...@@ -59,18 +59,18 @@ imap4d_authenticate (struct imap4d_command *command, char *arg)
59 59
60 if (username) 60 if (username)
61 { 61 {
62 struct passwd *pw = mu_getpwnam (username); 62 auth_data = mu_get_auth_by_name (username);
63 if (pw == NULL) 63 if (auth_data == NULL)
64 return util_finish (command, RESP_NO, 64 return util_finish (command, RESP_NO,
65 "User name or passwd rejected"); 65 "User name or passwd rejected");
66 66
67 if (pw->pw_uid > 0 && !mu_virtual_domain) 67 if (auth_data->change_uid)
68 setuid (pw->pw_uid); 68 setuid (auth_data->uid);
69 69
70 homedir = mu_normalize_path (strdup (pw->pw_dir), "/"); 70 homedir = mu_normalize_path (strdup (auth_data->dir), "/");
71 /* FIXME: Check for errors. */ 71 /* FIXME: Check for errors. */
72 chdir (homedir); 72 chdir (homedir);
73 namespace_init(pw->pw_dir); 73 namespace_init (homedir);
74 syslog (LOG_INFO, "User '%s' logged in", username); 74 syslog (LOG_INFO, "User '%s' logged in", username);
75 return 0; 75 return 0;
76 } 76 }
......
...@@ -27,10 +27,7 @@ imap4d_bye (int reason) ...@@ -27,10 +27,7 @@ imap4d_bye (int reason)
27 int 27 int
28 imap4d_bye0 (int reason, struct imap4d_command *command) 28 imap4d_bye0 (int reason, struct imap4d_command *command)
29 { 29 {
30 struct passwd *pw = mu_getpwuid (getuid ());
31 const char *username;
32 int status = EXIT_FAILURE; 30 int status = EXIT_FAILURE;
33 username = (pw) ? pw->pw_name : "Unknown";
34 31
35 if (mbox) 32 if (mbox)
36 { 33 {
...@@ -57,7 +54,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) ...@@ -57,7 +54,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command)
57 if (state == STATE_NONAUTH) 54 if (state == STATE_NONAUTH)
58 syslog (LOG_INFO, "Session timed out for no user"); 55 syslog (LOG_INFO, "Session timed out for no user");
59 else 56 else
60 syslog (LOG_INFO, "Session timed out for user: %s", username); 57 syslog (LOG_INFO, "Session timed out for user: %s", auth_data->name);
61 break; 58 break;
62 59
63 case ERR_NO_OFILE: 60 case ERR_NO_OFILE:
...@@ -69,7 +66,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) ...@@ -69,7 +66,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command)
69 if (state == STATE_NONAUTH) 66 if (state == STATE_NONAUTH)
70 syslog (LOG_INFO, "Session terminating"); 67 syslog (LOG_INFO, "Session terminating");
71 else 68 else
72 syslog (LOG_INFO, "Session terminating for user: %s", username); 69 syslog (LOG_INFO, "Session terminating for user: %s", auth_data->name);
73 status = EXIT_SUCCESS; 70 status = EXIT_SUCCESS;
74 break; 71 break;
75 72
......
...@@ -16,9 +16,6 @@ ...@@ -16,9 +16,6 @@
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17 17
18 #include "imap4d.h" 18 #include "imap4d.h"
19 #ifdef HAVE_MYSQL
20 # include "../MySql/MySql.h"
21 #endif
22 19
23 FILE *ifile; 20 FILE *ifile;
24 FILE *ofile; 21 FILE *ofile;
...@@ -26,6 +23,7 @@ mailbox_t mbox; ...@@ -26,6 +23,7 @@ mailbox_t mbox;
26 char *homedir; 23 char *homedir;
27 int state = STATE_NONAUTH; 24 int state = STATE_NONAUTH;
28 int debug_mode = 0; 25 int debug_mode = 0;
26 struct mu_auth_data *auth_data;
29 27
30 struct daemon_param daemon_param = { 28 struct daemon_param daemon_param = {
31 MODE_INTERACTIVE, /* Start in interactive (inetd) mode */ 29 MODE_INTERACTIVE, /* Start in interactive (inetd) mode */
...@@ -107,6 +105,7 @@ main (int argc, char **argv) ...@@ -107,6 +105,7 @@ main (int argc, char **argv)
107 105
108 state = STATE_NONAUTH; /* Starting state in non-auth. */ 106 state = STATE_NONAUTH; /* Starting state in non-auth. */
109 107
108 MU_AUTH_REGISTER_ALL_MODULES();
110 mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); 109 mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param);
111 110
112 #ifdef USE_LIBPAM 111 #ifdef USE_LIBPAM
...@@ -145,14 +144,6 @@ main (int argc, char **argv) ...@@ -145,14 +144,6 @@ main (int argc, char **argv)
145 list_append (bookie, path_record); 144 list_append (bookie, path_record);
146 } 145 }
147 146
148 #ifdef HAVE_MYSQL
149 mu_register_getpwnam (getMpwnam);
150 mu_register_getpwuid (getMpwuid);
151 #endif
152 #ifdef USE_VIRTUAL_DOMAINS
153 mu_register_getpwnam (getpwnam_virtual);
154 #endif
155
156 /* Set the signal handlers. */ 147 /* Set the signal handlers. */
157 signal (SIGINT, imap4d_signal); 148 signal (SIGINT, imap4d_signal);
158 signal (SIGQUIT, imap4d_signal); 149 signal (SIGQUIT, imap4d_signal);
......
...@@ -17,73 +17,11 @@ ...@@ -17,73 +17,11 @@
17 17
18 #include "imap4d.h" 18 #include "imap4d.h"
19 19
20 #ifdef HAVE_MYSQL
21 #include "../MySql/MySql.h"
22 #endif
23
24 #ifdef USE_LIBPAM
25 #define COPY_STRING(s) (s) ? strdup(s) : NULL
26
27 static char *_pwd;
28 static char *_user;
29 static int _perr = 0;
30
31 static int
32 PAM_gnuimap4d_conv (int num_msg, const struct pam_message **msg,
33 struct pam_response **resp, void *appdata_ptr)
34 {
35 int replies = 0;
36 struct pam_response *reply = NULL;
37
38 reply = malloc (sizeof (*reply) * num_msg);
39 if (!reply)
40 return PAM_CONV_ERR;
41 for (replies = 0; replies < num_msg; replies++)
42 {
43 switch (msg[replies]->msg_style)
44 {
45 case PAM_PROMPT_ECHO_ON:
46 reply[replies].resp_retcode = PAM_SUCCESS;
47 reply[replies].resp = COPY_STRING (_user);
48 /* PAM frees resp */
49 break;
50
51 case PAM_PROMPT_ECHO_OFF:
52 reply[replies].resp_retcode = PAM_SUCCESS;
53 reply[replies].resp = COPY_STRING (_pwd);
54 /* PAM frees resp */
55 break;
56
57 case PAM_TEXT_INFO:
58 case PAM_ERROR_MSG:
59 reply[replies].resp_retcode = PAM_SUCCESS;
60 reply[replies].resp = NULL;
61 break;
62
63 default:
64 free (reply);
65 _perr = 1;
66 return PAM_CONV_ERR;
67 }
68 }
69 *resp = reply;
70 return PAM_SUCCESS;
71 }
72
73 static struct pam_conv PAM_conversation = { &PAM_gnuimap4d_conv, NULL };
74 #endif /* USE_LIBPAM */
75
76 #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) goto pam_errlab;
77
78 int 20 int
79 imap4d_login (struct imap4d_command *command, char *arg) 21 imap4d_login (struct imap4d_command *command, char *arg)
80 { 22 {
81 struct passwd *pw;
82 char *sp = NULL, *username, *pass; 23 char *sp = NULL, *username, *pass;
83 #ifdef USE_LIBPAM 24 int rc;
84 pam_handle_t *pamh;
85 int pamerror;
86 #endif /* !USE_LIBPAM */
87 25
88 username = util_getword (arg, &sp); 26 username = util_getword (arg, &sp);
89 pass = util_getword (NULL, &sp); 27 pass = util_getword (NULL, &sp);
...@@ -97,56 +35,29 @@ imap4d_login (struct imap4d_command *command, char *arg) ...@@ -97,56 +35,29 @@ imap4d_login (struct imap4d_command *command, char *arg)
97 else if (util_getword (NULL, &sp)) 35 else if (util_getword (NULL, &sp))
98 return util_finish (command, RESP_NO, "Too many args"); 36 return util_finish (command, RESP_NO, "Too many args");
99 37
100 pw = mu_getpwnam (username); 38 auth_data = mu_get_auth_by_name (username);
101 if (pw == NULL)
102 return util_finish (command, RESP_NO, "User name or passwd rejected");
103 39
104 #ifndef USE_LIBPAM 40 if (auth_data == NULL)
105 if (pw->pw_uid < 1)
106 return util_finish (command, RESP_NO, "User name or passwd rejected");
107 if (strcmp (pw->pw_passwd, (char *)crypt (pass, pw->pw_passwd)))
108 { 41 {
109 #ifdef HAVE_SHADOW_H 42 syslog (LOG_INFO, "User '%s': nonexistent", arg);
110 struct spwd *spw;
111 spw = getspnam (username);
112 if (spw == NULL || strcmp (spw->sp_pwdp, (char *)crypt (pass, spw->sp_pwdp)))
113 #ifdef HAVE_MYSQL
114 {
115 spw = getMspnam (username);
116 if (spw == NULL || strcmp (spw->sp_pwdp, (char *)crypt (pass, spw->sp_pwdp)))
117 return util_finish (command, RESP_NO, "User name or passwd rejected");
118 }
119 #else /* HAVE_MYSQL */
120 #endif /* HAVE_SHADOW_H */
121 return util_finish (command, RESP_NO, "User name or passwd rejected"); 43 return util_finish (command, RESP_NO, "User name or passwd rejected");
122 #endif /* HAVE_MYSQL */
123 } 44 }
124 45
125 #else /* !USE_LIBPAM */ 46 rc = mu_authenticate (auth_data, pass);
126 _user = (char *) username;
127 _pwd = pass;
128 /* libpam doesn't log to LOG_MAIL */
129 closelog ();
130 pamerror = pam_start (pam_service, username, &PAM_conversation, &pamh);
131 PAM_ERROR;
132 pamerror = pam_authenticate (pamh, 0);
133 PAM_ERROR;
134 pamerror = pam_acct_mgmt (pamh, 0);
135 PAM_ERROR;
136 pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
137 pam_errlab:
138 pam_end (pamh, PAM_SUCCESS);
139 openlog ("gnu-imap4d", LOG_PID, log_facility); 47 openlog ("gnu-imap4d", LOG_PID, log_facility);
140 if (_perr || (pamerror != PAM_SUCCESS)) 48 if (rc)
49 {
50 syslog (LOG_INFO, "Login failed: %s", arg);
141 return util_finish (command, RESP_NO, "User name or passwd rejected"); 51 return util_finish (command, RESP_NO, "User name or passwd rejected");
142 #endif /* USE_LIBPAM */ 52 }
143 53
144 if (pw->pw_uid > 0 && !mu_virtual_domain) 54 if (auth_data->change_uid)
145 setuid (pw->pw_uid); 55 setuid (auth_data->uid);
146 56
147 homedir = mu_normalize_path (strdup (pw->pw_dir), "/"); 57 homedir = mu_normalize_path (strdup (auth_data->dir), "/");
148 chdir (homedir); 58 chdir (homedir);
149 namespace_init (pw->pw_dir); 59 namespace_init (homedir);
150 syslog (LOG_INFO, "User '%s' logged in", username); 60 syslog (LOG_INFO, "User '%s' logged in", username);
151 return util_finish (command, RESP_OK, "Completed"); 61 return util_finish (command, RESP_OK, "Completed");
152 } 62 }
63
......
...@@ -197,29 +197,13 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim) ...@@ -197,29 +197,13 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim)
197 char * 197 char *
198 namespace_getfullpath (char *name, const char *delim) 198 namespace_getfullpath (char *name, const char *delim)
199 { 199 {
200 if (strcasecmp (name, "INBOX") == 0 && !mu_virtual_domain) 200 if (strcasecmp (name, "INBOX") == 0 && auth_data->change_uid)
201 { 201 name = strdup (auth_data->mailbox);
202 struct passwd *pw = mu_getpwuid (getuid ());
203 if (pw)
204 {
205 name = malloc (strlen (mu_path_maildir) +
206 strlen (pw->pw_name) + 1);
207 if (!name)
208 {
209 syslog (LOG_ERR, "Not enough memory");
210 return NULL;
211 }
212 sprintf (name, "%s%s", mu_path_maildir, pw->pw_name);
213 }
214 else
215 name = strdup ("/dev/null");
216 }
217 else 202 else
218 name = namespace_checkfullpath (name, NULL, delim); 203 name = namespace_checkfullpath (name, NULL, delim);
219 return name; 204 return name;
220 } 205 }
221 206
222
223 int 207 int
224 namespace_init(char *path) 208 namespace_init(char *path)
225 { 209 {
......
...@@ -68,8 +68,9 @@ imap4d_rename (struct imap4d_command *command, char *arg) ...@@ -68,8 +68,9 @@ imap4d_rename (struct imap4d_command *command, char *arg)
68 if (strcasecmp (oldname, "INBOX") == 0) 68 if (strcasecmp (oldname, "INBOX") == 0)
69 { 69 {
70 mailbox_t newmbox = NULL; 70 mailbox_t newmbox = NULL;
71 mailbox_t inbox = NULL;
71 char *name; 72 char *name;
72 struct passwd *pw; 73
73 if (S_ISDIR(newst.st_mode)) 74 if (S_ISDIR(newst.st_mode))
74 { 75 {
75 free (newname); 76 free (newname);
...@@ -86,11 +87,8 @@ imap4d_rename (struct imap4d_command *command, char *arg) ...@@ -86,11 +87,8 @@ imap4d_rename (struct imap4d_command *command, char *arg)
86 } 87 }
87 free (name); 88 free (name);
88 free (newname); 89 free (newname);
89 pw = mu_getpwuid (getuid ()); 90
90 if (pw) 91 if (mailbox_create_default (&inbox, auth_data->name) == 0 &&
91 {
92 mailbox_t inbox = NULL;
93 if (mailbox_create_default (&inbox, pw->pw_name) == 0 &&
94 mailbox_open (inbox, MU_STREAM_RDWR) == 0) 92 mailbox_open (inbox, MU_STREAM_RDWR) == 0)
95 { 93 {
96 size_t no; 94 size_t no;
...@@ -111,7 +109,6 @@ imap4d_rename (struct imap4d_command *command, char *arg) ...@@ -111,7 +109,6 @@ imap4d_rename (struct imap4d_command *command, char *arg)
111 mailbox_close (inbox); 109 mailbox_close (inbox);
112 mailbox_destroy (&inbox); 110 mailbox_destroy (&inbox);
113 } 111 }
114 }
115 mailbox_close (newmbox); 112 mailbox_close (newmbox);
116 mailbox_destroy (&newmbox); 113 mailbox_destroy (&newmbox);
117 return util_finish (command, RESP_OK, "Already exist"); 114 return util_finish (command, RESP_OK, "Already exist");
......
...@@ -16,54 +16,52 @@ ...@@ -16,54 +16,52 @@
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17 17
18 #include "mu_scm.h" 18 #include "mu_scm.h"
19 #include <pwd.h> 19 #include <mailutils/mu_auth.h>
20 20
21 SCM_DEFINE (mu_scm_getpwuid, "mu_getpwuid", 0, 1, 0, 21 SCM_DEFINE (mu_scm_getpwuid, "mu-getpwuid", 1, 0, 0,
22 (SCM USER), 22 (SCM USER),
23 "Look up an entry in the user database. USER can be an integer,\n" 23 "Look up an entry in the user database. USER can be an integer,\n"
24 "a string, or omitted, giving the behaviour of mu_getpwuid, mu_getpwnam\n" 24 "or a string, giving the behaviour of mu_get_auth_by_uid or mu_get_auth_by_name\n"
25 "or (system) getpwent respectively.\n" 25 "respectively.\n"
26 "Returns a vector with fields corresponding to those of the passwd\n" 26 "Returns a vector with fields corresponding to those of the mu_auth_data\n"
27 "entry in question. If no matching entry was found, returns #f.\n") 27 "entry in question. If no matching entry was found, returns #f.\n")
28 #define FUNC_NAME s_mu_scm_getpwuid 28 #define FUNC_NAME s_mu_scm_getpwuid
29 { 29 {
30 SCM result; 30 SCM result;
31 struct passwd *entry; 31 struct mu_auth_data *entry;
32 SCM *ve; 32 SCM *ve;
33 33
34 result = scm_make_vector (SCM_MAKINUM (7), SCM_UNSPECIFIED); 34 result = scm_make_vector (SCM_MAKINUM (8), SCM_UNSPECIFIED);
35 ve = SCM_VELTS (result); 35 ve = SCM_VELTS (result);
36 if (SCM_UNBNDP (USER) || SCM_FALSEP (USER)) 36 if (SCM_INUMP (USER))
37 { 37 {
38 entry = getpwent (); 38 entry = mu_get_auth_by_uid (SCM_INUM (USER));
39 }
40 else if (SCM_INUMP (USER))
41 {
42 entry = mu_getpwuid (SCM_INUM (USER));
43 } 39 }
44 else 40 else
45 { 41 {
46 SCM_VALIDATE_ROSTRING (1, USER); 42 SCM_VALIDATE_ROSTRING (1, USER);
47 if (SCM_SUBSTRP (USER)) 43 if (SCM_SUBSTRP (USER))
48 USER = scm_makfromstr (SCM_ROCHARS (USER), SCM_ROLENGTH (USER), 0); 44 USER = scm_makfromstr (SCM_ROCHARS (USER), SCM_ROLENGTH (USER), 0);
49 entry = mu_getpwnam (SCM_ROCHARS (USER)); 45 entry = mu_get_auth_by_name (SCM_ROCHARS (USER));
50 } 46 }
51 if (!entry) 47 if (!entry)
52 return SCM_BOOL_F; 48 return SCM_BOOL_F;
53 49
54 ve[0] = scm_makfrom0str (entry->pw_name); 50 ve[0] = scm_makfrom0str (entry->name);
55 ve[1] = scm_makfrom0str (entry->pw_passwd); 51 ve[1] = scm_makfrom0str (entry->passwd);
56 ve[2] = scm_ulong2num ((unsigned long) entry->pw_uid); 52 ve[2] = scm_ulong2num ((unsigned long) entry->uid);
57 ve[3] = scm_ulong2num ((unsigned long) entry->pw_gid); 53 ve[3] = scm_ulong2num ((unsigned long) entry->gid);
58 ve[4] = scm_makfrom0str (entry->pw_gecos); 54 ve[4] = scm_makfrom0str (entry->gecos);
59 if (!entry->pw_dir) 55 if (!entry->dir)
60 ve[5] = scm_makfrom0str (""); 56 ve[5] = scm_makfrom0str ("");
61 else 57 else
62 ve[5] = scm_makfrom0str (entry->pw_dir); 58 ve[5] = scm_makfrom0str (entry->dir);
63 if (!entry->pw_shell) 59 if (!entry->shell)
64 ve[6] = scm_makfrom0str (""); 60 ve[6] = scm_makfrom0str ("");
65 else 61 else
66 ve[6] = scm_makfrom0str (entry->pw_shell); 62 ve[6] = scm_makfrom0str (entry->shell);
63 ve[7] = scm_makfrom0str (entry->mailbox);
64 mu_auth_data_free (entry);
67 return result; 65 return result;
68 } 66 }
69 #undef FUNC_NAME 67 #undef FUNC_NAME
......
...@@ -176,7 +176,7 @@ main (int argc, char *argv[]) ...@@ -176,7 +176,7 @@ main (int argc, char *argv[])
176 umask (0077); 176 umask (0077);
177 177
178 mu_argp_error_code = EX_CONFIG; 178 mu_argp_error_code = EX_CONFIG;
179 179 MU_AUTH_REGISTER_ALL_MODULES();
180 mu_argp_parse (&argp, &argc, &argv, 0, argp_capa, &arg_index, NULL); 180 mu_argp_parse (&argp, &argc, &argv, 0, argp_capa, &arg_index, NULL);
181 181
182 openlog ("mail.local", LOG_PID, log_facility); 182 openlog ("mail.local", LOG_PID, log_facility);
...@@ -193,16 +193,6 @@ main (int argc, char *argv[]) ...@@ -193,16 +193,6 @@ main (int argc, char *argv[])
193 return EX_USAGE; 193 return EX_USAGE;
194 } 194 }
195 195
196 #ifdef HAVE_MYSQL
197 mu_register_getpwnam (getMpwnam);
198 mu_register_getpwuid (getMpwuid);
199 #endif
200 #ifdef USE_VIRTUAL_DOMAINS
201 mu_register_getpwnam (getpwnam_virtual);
202 mu_register_getpwnam (getpwnam_ip_virtual);
203 mu_register_getpwnam (getpwnam_host_virtual);
204 #endif
205
206 /* Register local mbox formats. */ 196 /* Register local mbox formats. */
207 { 197 {
208 list_t bookie; 198 list_t bookie;
...@@ -308,11 +298,12 @@ make_tmp (const char *from, char **tempfile) ...@@ -308,11 +298,12 @@ make_tmp (const char *from, char **tempfile)
308 { 298 {
309 if (memcmp (buf, "From ", 5)) 299 if (memcmp (buf, "From ", 5))
310 { 300 {
301 struct mu_auth_data *auth;
311 if (!from) 302 if (!from)
312 { 303 {
313 struct passwd *pw = mu_getpwuid (uid); 304 auth = mu_get_auth_by_uid (uid);
314 if (pw) 305 if (auth)
315 from = pw->pw_name; 306 from = auth->name;
316 } 307 }
317 if (from) 308 if (from)
318 { 309 {
...@@ -324,6 +315,8 @@ make_tmp (const char *from, char **tempfile) ...@@ -324,6 +315,8 @@ make_tmp (const char *from, char **tempfile)
324 mailer_err ("Can't determine sender address"); 315 mailer_err ("Can't determine sender address");
325 exit (EX_UNAVAILABLE); 316 exit (EX_UNAVAILABLE);
326 } 317 }
318 if (auth)
319 mu_auth_data_free (auth);
327 } 320 }
328 } 321 }
329 else if (!memcmp (buf, "From ", 5)) 322 else if (!memcmp (buf, "From ", 5))
...@@ -353,7 +346,7 @@ deliver (FILE *fp, char *name) ...@@ -353,7 +346,7 @@ deliver (FILE *fp, char *name)
353 url_t url = NULL; 346 url_t url = NULL;
354 size_t n = 0; 347 size_t n = 0;
355 locker_t lock; 348 locker_t lock;
356 struct passwd *pw; 349 struct mu_auth_data *auth;
357 int status; 350 int status;
358 stream_t stream; 351 stream_t stream;
359 size_t size; 352 size_t size;
...@@ -362,15 +355,15 @@ deliver (FILE *fp, char *name) ...@@ -362,15 +355,15 @@ deliver (FILE *fp, char *name)
362 struct stat sb; 355 struct stat sb;
363 #endif 356 #endif
364 357
365 pw = mu_getpwnam (name); 358 auth = mu_get_auth_by_name (name);
366 if (!pw) 359 if (!auth)
367 { 360 {
368 mailer_err ("%s: no such user", name); 361 mailer_err ("%s: no such user", name);
369 exit_code = EX_UNAVAILABLE; 362 exit_code = EX_UNAVAILABLE;
370 return; 363 return;
371 } 364 }
372 365
373 path = malloc (strlen (mu_path_maildir) + strlen (name) + 1); 366 path = strdup (auth->mailbox);
374 if (!path) 367 if (!path)
375 { 368 {
376 mailer_err ("Out of memory"); 369 mailer_err ("Out of memory");
...@@ -393,7 +386,7 @@ deliver (FILE *fp, char *name) ...@@ -393,7 +386,7 @@ deliver (FILE *fp, char *name)
393 /* Actually open the mailbox. Switch to the user's euid to make 386 /* Actually open the mailbox. Switch to the user's euid to make
394 sure the maildrop file will have right privileges, in case it 387 sure the maildrop file will have right privileges, in case it
395 will be created */ 388 will be created */
396 if (switch_user_id (pw->pw_uid)) 389 if (switch_user_id (auth->uid))
397 return; 390 return;
398 status = mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT); 391 status = mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT);
399 if (switch_user_id (0)) 392 if (switch_user_id (0))
...@@ -463,7 +456,7 @@ deliver (FILE *fp, char *name) ...@@ -463,7 +456,7 @@ deliver (FILE *fp, char *name)
463 } 456 }
464 #endif 457 #endif
465 458
466 if (!failed && switch_user_id (pw->pw_uid) == 0) 459 if (!failed && switch_user_id (auth->uid) == 0)
467 { 460 {
468 off_t off = size; 461 off_t off = size;
469 size_t nwr; 462 size_t nwr;
...@@ -490,6 +483,7 @@ deliver (FILE *fp, char *name) ...@@ -490,6 +483,7 @@ deliver (FILE *fp, char *name)
490 483
491 locker_unlock (lock); 484 locker_unlock (lock);
492 485
486 mu_auth_data_free (auth);
493 mailbox_close (mbox); 487 mailbox_close (mbox);
494 mailbox_destroy (&mbox); 488 mailbox_destroy (&mbox);
495 } 489 }
......
...@@ -73,15 +73,16 @@ mda_init (void *data) ...@@ -73,15 +73,16 @@ mda_init (void *data)
73 static void 73 static void
74 mda_switch_to_user (struct mda_data *md) 74 mda_switch_to_user (struct mda_data *md)
75 { 75 {
76 struct passwd *pw = NULL; 76 struct mu_auth_data *auth = NULL;
77 77
78 if (md && *md->argv != NULL) 78 if (md && *md->argv != NULL)
79 pw = mu_getpwnam (*md->argv); 79 auth = mu_get_auth_by_name (*md->argv);
80 80
81 if (pw) 81 if (auth)
82 { 82 {
83 switch_user_id (pw->pw_uid); 83 switch_user_id (auth->uid);
84 chdir (pw->pw_dir); 84 chdir (auth->dir);
85 mu_auth_data_free (auth);
85 } 86 }
86 else 87 else
87 { 88 {
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
34 #include <mailutils/mutil.h> 34 #include <mailutils/mutil.h>
35 #include <mailutils/error.h> 35 #include <mailutils/error.h>
36 #include <mailutils/errno.h> 36 #include <mailutils/errno.h>
37 #include <mailutils/mu_auth.h>
37 38
38 const char *mu_path_maildir = MU_PATH_MAILDIR; 39 const char *mu_path_maildir = MU_PATH_MAILDIR;
39 40
...@@ -93,12 +94,13 @@ static const char * ...@@ -93,12 +94,13 @@ static const char *
93 get_homedir (const char *user) 94 get_homedir (const char *user)
94 { 95 {
95 const char *homedir = NULL; 96 const char *homedir = NULL;
96 struct passwd *pw = NULL; 97 struct mu_auth_data *auth = NULL;
98
97 if (user) 99 if (user)
98 { 100 {
99 pw = mu_getpwnam (user); 101 auth = mu_get_auth_by_name (user);
100 if (pw) 102 if (auth)
101 homedir = pw->pw_dir; 103 homedir = auth->dir;
102 } 104 }
103 else 105 else
104 { 106 {
...@@ -107,16 +109,20 @@ get_homedir (const char *user) ...@@ -107,16 +109,20 @@ get_homedir (const char *user)
107 homedir = getenv ("HOME"); 109 homedir = getenv ("HOME");
108 if (homedir == NULL) 110 if (homedir == NULL)
109 { 111 {
110 pw = mu_getpwuid (getuid ()); 112 auth = mu_get_auth_by_name (user);
111 if (pw) 113 if (auth)
112 homedir = pw->pw_dir; 114 homedir = auth->dir;
113 } 115 }
114 #else 116 #else
115 pw = mu_getpwuid (getuid ()); 117 auth = mu_get_auth_by_name (user);
116 if (pw) 118 if (auth)
117 homedir = pw->pw_dir; 119 homedir = auth->dir;
118 #endif 120 #endif
119 } 121 }
122
123 if (homedir)
124 homedir = strdup (homedir);
125 mu_auth_data_free (auth);
120 return homedir; 126 return homedir;
121 } 127 }
122 128
...@@ -136,22 +142,27 @@ user_mailbox_name (const char *user, char **mailbox_name) ...@@ -136,22 +142,27 @@ user_mailbox_name (const char *user, char **mailbox_name)
136 if (!user) 142 if (!user)
137 user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER"); 143 user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER");
138 #endif 144 #endif
139 if (user == NULL) 145
146 if (user)
140 { 147 {
141 struct passwd *pw; 148 *mailbox_name = malloc (strlen (user) + strlen (mu_path_maildir) + 2);
142 pw = mu_getpwuid (getuid ()); 149 if (*mailbox_name == NULL)
143 if (pw) 150 return ENOMEM;
144 user = pw->pw_name; 151 sprintf (*mailbox_name, "%s%s", mu_path_maildir, user);
152 }
145 else 153 else
146 { 154 {
155 struct mu_auth_data *auth = mu_get_auth_by_uid (getuid ());
156
157 if (!auth)
158 {
147 mu_error ("Who am I ?\n"); 159 mu_error ("Who am I ?\n");
148 return EINVAL; 160 return EINVAL;
149 } 161 }
162 *mailbox_name = strdup (auth->mailbox);
163 mu_auth_data_free (auth);
150 } 164 }
151 *mailbox_name = malloc (strlen (user) + strlen (mu_path_maildir) + 2); 165
152 if (*mailbox_name == NULL)
153 return ENOMEM;
154 sprintf (*mailbox_name, "%s%s", mu_path_maildir, user);
155 return 0; 166 return 0;
156 } 167 }
157 168
...@@ -188,6 +199,7 @@ plus_expand (const char *file, char **buf) ...@@ -188,6 +199,7 @@ plus_expand (const char *file, char **buf)
188 (*buf)[len-1] = 0; 199 (*buf)[len-1] = 0;
189 free (user); 200 free (user);
190 free (path); 201 free (path);
202 free (home);
191 return 0; 203 return 0;
192 } 204 }
193 205
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
47 #include <mailutils/mutil.h> 47 #include <mailutils/mutil.h>
48 #include <mailutils/observer.h> 48 #include <mailutils/observer.h>
49 #include <mailutils/stream.h> 49 #include <mailutils/stream.h>
50 #include <mailutils/mu_auth.h>
50 51
51 #define MESSAGE_MODIFIED 0x10000; 52 #define MESSAGE_MODIFIED 0x10000;
52 53
...@@ -971,18 +972,18 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) ...@@ -971,18 +972,18 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
971 972
972 /* oops! We are still here */ 973 /* oops! We are still here */
973 { 974 {
974 struct passwd *pw; 975 struct mu_auth_data *auth = mu_get_auth_by_uid (getuid ());
975 const char *sender; 976 const char *sender = auth ? auth->name : "unknown";
976 pw = mu_getpwuid (getuid ());
977 sender = (pw) ? pw->pw_name : "unknown";
978 n = strlen (sender); 977 n = strlen (sender);
979 if (buf && len > 0) 978 if (buf && len > 0)
980 { 979 {
981 len--; /* One for the null. */ 980 len--; /* One for the null. */
982 n = (n < len) ? n : len; 981 n = (n < len) ? n : len;
983 memcpy (buf, pw->pw_name, n); 982 memcpy (buf, auth->name, n);
984 buf[n] = '\0'; 983 buf[n] = '\0';
985 } 984 }
985 if (auth)
986 mu_auth_data_free (auth);
986 } 987 }
987 988
988 if (pnwrite) 989 if (pnwrite)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
30 30
31 #include <mailutils/errno.h> 31 #include <mailutils/errno.h>
32 #include <mailutils/mutil.h> 32 #include <mailutils/mutil.h>
33 #include <mailutils/mu_auth.h>
33 34
34 #include <auth0.h> 35 #include <auth0.h>
35 #include <url0.h> 36 #include <url0.h>
...@@ -399,10 +400,11 @@ get_user (url_t url, const char *filename, char **user) ...@@ -399,10 +400,11 @@ get_user (url_t url, const char *filename, char **user)
399 } 400 }
400 else 401 else
401 { 402 {
402 struct passwd *pw = mu_getpwuid (getuid ()); 403 struct mu_auth_data *auth = mu_get_auth_by_uid (getuid ());
403 if (pw && pw->pw_name) 404 if (auth)
404 { 405 {
405 u = strdup (pw->pw_name); 406 u = strdup (auth->name);
407 mu_auth_data_free (auth);
406 if (!u) 408 if (!u)
407 return ENOMEM; 409 return ENOMEM;
408 } 410 }
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
17 17
18 #include "pop3d.h" 18 #include "pop3d.h"
19 19
20 #ifdef HAVE_MYSQL
21 # include "../MySql/MySql.h"
22 #endif
23
24 mailbox_t mbox; 20 mailbox_t mbox;
25 int state; 21 int state;
26 char *username; 22 char *username;
...@@ -91,6 +87,7 @@ main (int argc, char **argv) ...@@ -91,6 +87,7 @@ main (int argc, char **argv)
91 struct group *gr; 87 struct group *gr;
92 int status = OK; 88 int status = OK;
93 89
90 MU_AUTH_REGISTER_ALL_MODULES();
94 mu_argp_parse (&argp, &argc, &argv, 0, pop3d_argp_capa, NULL, &daemon_param); 91 mu_argp_parse (&argp, &argc, &argv, 0, pop3d_argp_capa, NULL, &daemon_param);
95 92
96 #ifdef USE_LIBPAM 93 #ifdef USE_LIBPAM
...@@ -127,16 +124,6 @@ main (int argc, char **argv) ...@@ -127,16 +124,6 @@ main (int argc, char **argv)
127 list_append (bookie, path_record); 124 list_append (bookie, path_record);
128 } 125 }
129 126
130 #ifdef HAVE_MYSQL
131 mu_register_getpwnam (getMpwnam);
132 mu_register_getpwuid (getMpwuid);
133 #endif
134 #ifdef USE_VIRTUAL_DOMAINS
135 mu_register_getpwnam (getpwnam_virtual);
136 mu_register_getpwnam (getpwnam_ip_virtual);
137 mu_register_getpwnam (getpwnam_host_virtual);
138 #endif
139
140 /* Set the signal handlers. */ 127 /* Set the signal handlers. */
141 signal (SIGINT, pop3d_signal); 128 signal (SIGINT, pop3d_signal);
142 signal (SIGQUIT, pop3d_signal); 129 signal (SIGQUIT, pop3d_signal);
......
...@@ -17,79 +17,13 @@ ...@@ -17,79 +17,13 @@
17 17
18 #include "pop3d.h" 18 #include "pop3d.h"
19 19
20 #ifdef HAVE_MYSQL
21 # include "../MySql/MySql.h"
22 #endif
23
24 #ifdef USE_LIBPAM
25 #define COPY_STRING(s) (s) ? strdup(s) : NULL
26
27 static char *_pwd;
28 static char *_user;
29 static int _perr = 0;
30
31 #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \
32 goto pam_errlab;
33
34 static int
35 PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg,
36 struct pam_response **resp, void *appdata_ptr)
37 {
38 int replies = 0;
39 struct pam_response *reply = NULL;
40 (void)appdata_ptr;
41
42 reply = malloc (sizeof (*reply) * num_msg);
43 if (!reply)
44 return PAM_CONV_ERR;
45
46 for (replies = 0; replies < num_msg; replies++)
47 {
48 switch (msg[replies]->msg_style)
49 {
50 case PAM_PROMPT_ECHO_ON:
51 reply[replies].resp_retcode = PAM_SUCCESS;
52 reply[replies].resp = COPY_STRING (_user);
53 /* PAM frees resp */
54 break;
55
56 case PAM_PROMPT_ECHO_OFF:
57 reply[replies].resp_retcode = PAM_SUCCESS;
58 reply[replies].resp = COPY_STRING (_pwd);
59 /* PAM frees resp */
60 break;
61
62 case PAM_TEXT_INFO:
63 case PAM_ERROR_MSG:
64 reply[replies].resp_retcode = PAM_SUCCESS;
65 reply[replies].resp = NULL;
66 break;
67
68 default:
69 free (reply);
70 _perr = 1;
71 return PAM_CONV_ERR;
72 }
73 }
74 *resp = reply;
75 return PAM_SUCCESS;
76 }
77
78 static struct pam_conv PAM_conversation = { &PAM_gnupop3d_conv, NULL };
79 #endif /* USE_LIBPAM */
80
81 /* Basic user authentication. This also takes the PASS command and verifies
82 the user name and password. Calls setuid() upon successful verification,
83 otherwise it will (likely) return ERR_BAD_LOGIN */
84
85 int 20 int
86 pop3d_user (const char *arg) 21 pop3d_user (const char *arg)
87 { 22 {
88 char *buf, pass[POP_MAXCMDLEN], *tmp, *cmd; 23 char *buf, pass[POP_MAXCMDLEN], *tmp, *cmd;
89 struct passwd *pw;
90 int status; 24 int status;
91 int lockit = 1; 25 int lockit = 1;
92 char *mailbox_name = NULL; 26 struct mu_auth_data *auth_data;
93 27
94 if (state != AUTHORIZATION) 28 if (state != AUTHORIZATION)
95 return ERR_WRONG_STATE; 29 return ERR_WRONG_STATE;
...@@ -118,14 +52,10 @@ pop3d_user (const char *arg) ...@@ -118,14 +52,10 @@ pop3d_user (const char *arg)
118 free (tmp); 52 free (tmp);
119 } 53 }
120 54
121 if (strlen (cmd) > 4) 55 if (strcasecmp (cmd, "PASS") == 0)
122 { 56 {
123 free (cmd); 57 int rc;
124 return ERR_BAD_CMD;
125 }
126 58
127 if ((strcasecmp (cmd, "PASS") == 0))
128 {
129 free (cmd); 59 free (cmd);
130 60
131 #ifdef _USE_APOP 61 #ifdef _USE_APOP
...@@ -139,79 +69,40 @@ pop3d_user (const char *arg) ...@@ -139,79 +69,40 @@ pop3d_user (const char *arg)
139 } 69 }
140 #endif 70 #endif
141 71
142 pw = mu_getpwnam (arg); 72 auth_data = mu_get_auth_by_name (arg);
143 73
144 if (pw == NULL) 74 if (auth_data == NULL)
145 { 75 {
146 syslog (LOG_INFO, "User '%s': nonexistent", arg); 76 syslog (LOG_INFO, "User '%s': nonexistent", arg);
147 return ERR_BAD_LOGIN; 77 return ERR_BAD_LOGIN;
148 } 78 }
149 79
150 #ifndef USE_LIBPAM 80 rc = mu_authenticate (auth_data, pass);
151 if (pw->pw_uid < 1)
152 return ERR_BAD_LOGIN;
153 if (strcmp (pw->pw_passwd, (char *) crypt (pass, pw->pw_passwd)))
154 {
155 #ifdef HAVE_SHADOW_H
156 struct spwd *spw;
157 spw = getspnam ((char *) arg);
158 #ifdef HAVE_MYSQL
159 if (spw == NULL)
160 spw = getMspnam (arg);
161 #endif /* HAVE_MYSQL */
162 if (spw == NULL || strcmp (spw->sp_pwdp,
163 (char *) crypt (pass, spw->sp_pwdp)))
164 #endif /* HAVE_SHADOW_H */
165 {
166 syslog (LOG_INFO, "User '%s': authentication failed", arg);
167 return ERR_BAD_LOGIN;
168 }
169 }
170 #else /* !USE_LIBPAM */
171 {
172 pam_handle_t *pamh;
173 int pamerror;
174 _user = (char *) arg;
175 _pwd = pass;
176 /* libpam doesn't log to LOG_MAIL */
177 closelog ();
178 pamerror = pam_start (pam_service, arg, &PAM_conversation, &pamh);
179 PAM_ERROR;
180 pamerror = pam_authenticate (pamh, 0);
181 PAM_ERROR;
182 pamerror = pam_acct_mgmt (pamh, 0);
183 PAM_ERROR;
184 pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
185 pam_errlab:
186 pam_end (pamh, PAM_SUCCESS);
187 openlog ("gnu-pop3d", LOG_PID, log_facility); 81 openlog ("gnu-pop3d", LOG_PID, log_facility);
188 if (pamerror != PAM_SUCCESS) 82
83 if (rc)
189 { 84 {
190 syslog (LOG_INFO, "User '%s': authentication failed", _user); 85 syslog (LOG_INFO, "User '%s': authentication failed", arg);
86 mu_auth_data_free (auth_data);
191 return ERR_BAD_LOGIN; 87 return ERR_BAD_LOGIN;
192 } 88 }
193 } 89 }
194 #endif /* USE_LIBPAM */ 90 else if (strcasecmp (cmd, "QUIT") == 0)
195
196 if (pw->pw_uid > 0 && !mu_virtual_domain)
197 {
198 setuid (pw->pw_uid);
199 mailbox_name = malloc (strlen (mu_path_maildir) +
200 strlen (pw->pw_name) + 1);
201 if (!mailbox_name)
202 { 91 {
203 syslog (LOG_ERR, "Not enough memory"); 92 syslog (LOG_INFO, "Possible probe of account '%s'", arg);
204 return ERR_UNKNOWN; 93 free (cmd);
205 } 94 return pop3d_quit (pass);
206 sprintf (mailbox_name, "%s%s", mu_path_maildir, pw->pw_name);
207 } 95 }
208 else if (mu_virtual_domain) 96 else
209 { 97 {
210 mailbox_name = calloc (strlen (pw->pw_dir) + strlen ("/INBOX"), 1); 98 free (cmd);
211 sprintf (mailbox_name, "%s/INBOX", pw->pw_dir); 99 return ERR_BAD_CMD;
212 } 100 }
213 101
214 if ((status = mailbox_create (&mbox, mailbox_name)) != 0 102 if (auth_data->change_uid)
103 setuid (auth_data->uid);
104
105 if ((status = mailbox_create (&mbox, auth_data->mailbox)) != 0
215 || (status = mailbox_open (mbox, MU_STREAM_RDWR)) != 0) 106 || (status = mailbox_open (mbox, MU_STREAM_RDWR)) != 0)
216 { 107 {
217 mailbox_destroy (&mbox); 108 mailbox_destroy (&mbox);
...@@ -222,33 +113,35 @@ pop3d_user (const char *arg) ...@@ -222,33 +113,35 @@ pop3d_user (const char *arg)
222 || mailbox_open (mbox, MU_STREAM_READ) != 0) 113 || mailbox_open (mbox, MU_STREAM_READ) != 0)
223 { 114 {
224 state = AUTHORIZATION; 115 state = AUTHORIZATION;
225 free (mailbox_name); 116 mu_auth_data_free (auth_data);
226 return ERR_UNKNOWN; 117 return ERR_UNKNOWN;
227 } 118 }
228 } 119 }
229 else 120 else
230 { 121 {
231 state = AUTHORIZATION; 122 state = AUTHORIZATION;
232 free (mailbox_name); 123 mu_auth_data_free (auth_data);
233 return ERR_MBOX_LOCK; 124 return ERR_MBOX_LOCK;
234 } 125 }
235 lockit = 0; /* Do not attempt to lock /dev/null ! */ 126 lockit = 0; /* Do not attempt to lock /dev/null ! */
236 } 127 }
237 free (mailbox_name);
238 128
239 if (lockit && pop3d_lock ()) 129 if (lockit && pop3d_lock ())
240 { 130 {
241 mailbox_close (mbox); 131 mailbox_close (mbox);
242 mailbox_destroy (&mbox); 132 mailbox_destroy (&mbox);
133 mu_auth_data_free (auth_data);
243 state = AUTHORIZATION; 134 state = AUTHORIZATION;
244 return ERR_MBOX_LOCK; 135 return ERR_MBOX_LOCK;
245 } 136 }
246 137
247 username = strdup (pw->pw_name); 138 username = strdup (auth_data->name);
248 if (username == NULL) 139 if (username == NULL)
249 pop3d_abquit (ERR_NO_MEM); 140 pop3d_abquit (ERR_NO_MEM);
250 state = TRANSACTION; 141 state = TRANSACTION;
251 142
143 mu_auth_data_free (auth_data);
144
252 pop3d_outf ("+OK opened mailbox for %s\r\n", username); 145 pop3d_outf ("+OK opened mailbox for %s\r\n", username);
253 146
254 /* mailbox name */ 147 /* mailbox name */
...@@ -261,14 +154,8 @@ pop3d_user (const char *arg) ...@@ -261,14 +154,8 @@ pop3d_user (const char *arg)
261 username, url_to_string (url), total); 154 username, url_to_string (url), total);
262 } 155 }
263 return OK; 156 return OK;
264 }
265 else if (strcasecmp (cmd, "QUIT") == 0)
266 {
267 syslog (LOG_INFO, "Possible probe of account '%s'", arg);
268 free (cmd);
269 return pop3d_quit (pass);
270 }
271 157
272 free (cmd);
273 return ERR_BAD_LOGIN;
274 } 158 }
159
160
161
......