Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
33737423
...
3373742327451a83f03946e47d0dd512295303f0
authored
2002-08-13 13:24:57 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Switched to the new authentication/authorization functions.
1 parent
257c5cda
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
212 additions
and
458 deletions
comsat/comsat.c
guimb/scm/sieve-core.scm
imap4d/authenticate.c
imap4d/bye.c
imap4d/imap4d.c
imap4d/login.c
imap4d/namespace.c
imap4d/rename.c
libmu_scm/mu_util.c
mail.local/main.c
mail.local/script.c
mailbox/mbx_default.c
mailbox/message.c
mailbox/wicket.c
pop3d/pop3d.c
pop3d/user.c
comsat/comsat.c
View file @
3373742
...
...
@@ -585,27 +585,19 @@ change_user (const char *user)
char
*
mailbox_path
(
const
char
*
user
)
{
struct
passwd
*
pw
;
struct
mu_auth_data
*
auth
;
char
*
mailbox_name
;
pw
=
mu_getpwnam
(
user
);
if
(
!
pw
)
auth
=
mu_get_auth_by_name
(
user
);
if
(
!
auth
)
{
syslog
(
LOG_ALERT
,
"user nonexistent: %s"
,
user
);
return
NULL
;
}
if
(
!
mu_virtual_domain
)
{
mailbox_name
=
calloc
(
strlen
(
mu_path_maildir
)
+
1
+
strlen
(
pw
->
pw_name
)
+
1
,
1
);
sprintf
(
mailbox_name
,
"%s%s"
,
mu_path_maildir
,
pw
->
pw_name
);
}
else
{
mailbox_name
=
calloc
(
strlen
(
pw
->
pw_dir
)
+
strlen
(
"/INBOX"
),
1
);
sprintf
(
mailbox_name
,
"%s/INBOX"
,
pw
->
pw_dir
);
}
mailbox_name
=
strdup
(
auth
->
mailbox
);
mu_auth_data_free
(
auth
);
return
mailbox_name
;
}
...
...
guimb/scm/sieve-core.scm
View file @
3373742
...
...
@@ -65,7 +65,7 @@
(
define
(
sieve-expand-filename
filename
)
(
case
(
string-ref
filename
0
)
((
#
\
~
)
(
let
((
pw
(
mu
_
getpwuid
(
geteuid
))))
(
let
((
pw
(
mu
-
getpwuid
(
geteuid
))))
(
if
(
and
(
vector?
pw
)
(
let
((
dir
(
vector-ref
pw
5
)))
(
and
...
...
imap4d/authenticate.c
View file @
3373742
...
...
@@ -29,7 +29,7 @@ struct imap_auth {
{
NULL
,
NULL
}
};
int
void
imap4d_auth_capability
()
{
struct
imap_auth
*
ap
;
...
...
@@ -59,18 +59,18 @@ imap4d_authenticate (struct imap4d_command *command, char *arg)
if
(
username
)
{
struct
passwd
*
pw
=
mu_getpwnam
(
username
);
if
(
pw
==
NULL
)
auth_data
=
mu_get_auth_by_name
(
username
);
if
(
auth_data
==
NULL
)
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
if
(
pw
->
pw_uid
>
0
&&
!
mu_virtual_domain
)
setuid
(
pw
->
pw_
uid
);
if
(
auth_data
->
change_uid
)
setuid
(
auth_data
->
uid
);
homedir
=
mu_normalize_path
(
strdup
(
pw
->
pw_
dir
),
"/"
);
homedir
=
mu_normalize_path
(
strdup
(
auth_data
->
dir
),
"/"
);
/* FIXME: Check for errors. */
chdir
(
homedir
);
namespace_init
(
pw
->
pw_
dir
);
namespace_init
(
home
dir
);
syslog
(
LOG_INFO
,
"User '%s' logged in"
,
username
);
return
0
;
}
...
...
imap4d/bye.c
View file @
3373742
...
...
@@ -27,10 +27,7 @@ imap4d_bye (int reason)
int
imap4d_bye0
(
int
reason
,
struct
imap4d_command
*
command
)
{
struct
passwd
*
pw
=
mu_getpwuid
(
getuid
());
const
char
*
username
;
int
status
=
EXIT_FAILURE
;
username
=
(
pw
)
?
pw
->
pw_name
:
"Unknown"
;
if
(
mbox
)
{
...
...
@@ -57,7 +54,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command)
if
(
state
==
STATE_NONAUTH
)
syslog
(
LOG_INFO
,
"Session timed out for no user"
);
else
syslog
(
LOG_INFO
,
"Session timed out for user: %s"
,
user
name
);
syslog
(
LOG_INFO
,
"Session timed out for user: %s"
,
auth_data
->
name
);
break
;
case
ERR_NO_OFILE
:
...
...
@@ -69,7 +66,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command)
if
(
state
==
STATE_NONAUTH
)
syslog
(
LOG_INFO
,
"Session terminating"
);
else
syslog
(
LOG_INFO
,
"Session terminating for user: %s"
,
user
name
);
syslog
(
LOG_INFO
,
"Session terminating for user: %s"
,
auth_data
->
name
);
status
=
EXIT_SUCCESS
;
break
;
...
...
imap4d/imap4d.c
View file @
3373742
...
...
@@ -16,9 +16,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "imap4d.h"
#ifdef HAVE_MYSQL
# include "../MySql/MySql.h"
#endif
FILE
*
ifile
;
FILE
*
ofile
;
...
...
@@ -26,6 +23,7 @@ mailbox_t mbox;
char
*
homedir
;
int
state
=
STATE_NONAUTH
;
int
debug_mode
=
0
;
struct
mu_auth_data
*
auth_data
;
struct
daemon_param
daemon_param
=
{
MODE_INTERACTIVE
,
/* Start in interactive (inetd) mode */
...
...
@@ -104,9 +102,10 @@ main (int argc, char **argv)
{
struct
group
*
gr
;
int
status
=
EXIT_SUCCESS
;
state
=
STATE_NONAUTH
;
/* Starting state in non-auth. */
MU_AUTH_REGISTER_ALL_MODULES
();
mu_argp_parse
(
&
argp
,
&
argc
,
&
argv
,
0
,
imap4d_capa
,
NULL
,
&
daemon_param
);
#ifdef USE_LIBPAM
...
...
@@ -145,14 +144,6 @@ main (int argc, char **argv)
list_append
(
bookie
,
path_record
);
}
#ifdef HAVE_MYSQL
mu_register_getpwnam
(
getMpwnam
);
mu_register_getpwuid
(
getMpwuid
);
#endif
#ifdef USE_VIRTUAL_DOMAINS
mu_register_getpwnam
(
getpwnam_virtual
);
#endif
/* Set the signal handlers. */
signal
(
SIGINT
,
imap4d_signal
);
signal
(
SIGQUIT
,
imap4d_signal
);
...
...
imap4d/login.c
View file @
3373742
...
...
@@ -17,73 +17,11 @@
#include "imap4d.h"
#ifdef HAVE_MYSQL
#include "../MySql/MySql.h"
#endif
#ifdef USE_LIBPAM
#define COPY_STRING(s) (s) ? strdup(s) : NULL
static
char
*
_pwd
;
static
char
*
_user
;
static
int
_perr
=
0
;
static
int
PAM_gnuimap4d_conv
(
int
num_msg
,
const
struct
pam_message
**
msg
,
struct
pam_response
**
resp
,
void
*
appdata_ptr
)
{
int
replies
=
0
;
struct
pam_response
*
reply
=
NULL
;
reply
=
malloc
(
sizeof
(
*
reply
)
*
num_msg
);
if
(
!
reply
)
return
PAM_CONV_ERR
;
for
(
replies
=
0
;
replies
<
num_msg
;
replies
++
)
{
switch
(
msg
[
replies
]
->
msg_style
)
{
case
PAM_PROMPT_ECHO_ON
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
COPY_STRING
(
_user
);
/* PAM frees resp */
break
;
case
PAM_PROMPT_ECHO_OFF
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
COPY_STRING
(
_pwd
);
/* PAM frees resp */
break
;
case
PAM_TEXT_INFO
:
case
PAM_ERROR_MSG
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
NULL
;
break
;
default:
free
(
reply
);
_perr
=
1
;
return
PAM_CONV_ERR
;
}
}
*
resp
=
reply
;
return
PAM_SUCCESS
;
}
static
struct
pam_conv
PAM_conversation
=
{
&
PAM_gnuimap4d_conv
,
NULL
};
#endif
/* USE_LIBPAM */
#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) goto pam_errlab;
int
imap4d_login
(
struct
imap4d_command
*
command
,
char
*
arg
)
{
struct
passwd
*
pw
;
char
*
sp
=
NULL
,
*
username
,
*
pass
;
#ifdef USE_LIBPAM
pam_handle_t
*
pamh
;
int
pamerror
;
#endif
/* !USE_LIBPAM */
int
rc
;
username
=
util_getword
(
arg
,
&
sp
);
pass
=
util_getword
(
NULL
,
&
sp
);
...
...
@@ -97,56 +35,29 @@ imap4d_login (struct imap4d_command *command, char *arg)
else
if
(
util_getword
(
NULL
,
&
sp
))
return
util_finish
(
command
,
RESP_NO
,
"Too many args"
);
pw
=
mu_getpwnam
(
username
);
if
(
pw
==
NULL
)
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
auth_data
=
mu_get_auth_by_name
(
username
);
#ifndef USE_LIBPAM
if
(
pw
->
pw_uid
<
1
)
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
if
(
strcmp
(
pw
->
pw_passwd
,
(
char
*
)
crypt
(
pass
,
pw
->
pw_passwd
)))
if
(
auth_data
==
NULL
)
{
#ifdef HAVE_SHADOW_H
struct
spwd
*
spw
;
spw
=
getspnam
(
username
);
if
(
spw
==
NULL
||
strcmp
(
spw
->
sp_pwdp
,
(
char
*
)
crypt
(
pass
,
spw
->
sp_pwdp
)))
#ifdef HAVE_MYSQL
{
spw
=
getMspnam
(
username
);
if
(
spw
==
NULL
||
strcmp
(
spw
->
sp_pwdp
,
(
char
*
)
crypt
(
pass
,
spw
->
sp_pwdp
)))
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
}
#else
/* HAVE_MYSQL */
#endif
/* HAVE_SHADOW_H */
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
#endif
/* HAVE_MYSQL */
syslog
(
LOG_INFO
,
"User '%s': nonexistent"
,
arg
);
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
}
#else
/* !USE_LIBPAM */
_user
=
(
char
*
)
username
;
_pwd
=
pass
;
/* libpam doesn't log to LOG_MAIL */
closelog
();
pamerror
=
pam_start
(
pam_service
,
username
,
&
PAM_conversation
,
&
pamh
);
PAM_ERROR
;
pamerror
=
pam_authenticate
(
pamh
,
0
);
PAM_ERROR
;
pamerror
=
pam_acct_mgmt
(
pamh
,
0
);
PAM_ERROR
;
pamerror
=
pam_setcred
(
pamh
,
PAM_ESTABLISH_CRED
);
pam_errlab:
pam_end
(
pamh
,
PAM_SUCCESS
);
openlog
(
"gnu-imap4d"
,
LOG_PID
,
log_facility
);
if
(
_perr
||
(
pamerror
!=
PAM_SUCCESS
))
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
#endif
/* USE_LIBPAM */
if
(
pw
->
pw_uid
>
0
&&
!
mu_virtual_domain
)
setuid
(
pw
->
pw_uid
);
rc
=
mu_authenticate
(
auth_data
,
pass
);
openlog
(
"gnu-imap4d"
,
LOG_PID
,
log_facility
);
if
(
rc
)
{
syslog
(
LOG_INFO
,
"Login failed: %s"
,
arg
);
return
util_finish
(
command
,
RESP_NO
,
"User name or passwd rejected"
);
}
if
(
auth_data
->
change_uid
)
setuid
(
auth_data
->
uid
);
homedir
=
mu_normalize_path
(
strdup
(
pw
->
pw_
dir
),
"/"
);
homedir
=
mu_normalize_path
(
strdup
(
auth_data
->
dir
),
"/"
);
chdir
(
homedir
);
namespace_init
(
pw
->
pw_
dir
);
namespace_init
(
home
dir
);
syslog
(
LOG_INFO
,
"User '%s' logged in"
,
username
);
return
util_finish
(
command
,
RESP_OK
,
"Completed"
);
}
...
...
imap4d/namespace.c
View file @
3373742
...
...
@@ -197,29 +197,13 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim)
char
*
namespace_getfullpath
(
char
*
name
,
const
char
*
delim
)
{
if
(
strcasecmp
(
name
,
"INBOX"
)
==
0
&&
!
mu_virtual_domain
)
{
struct
passwd
*
pw
=
mu_getpwuid
(
getuid
());
if
(
pw
)
{
name
=
malloc
(
strlen
(
mu_path_maildir
)
+
strlen
(
pw
->
pw_name
)
+
1
);
if
(
!
name
)
{
syslog
(
LOG_ERR
,
"Not enough memory"
);
return
NULL
;
}
sprintf
(
name
,
"%s%s"
,
mu_path_maildir
,
pw
->
pw_name
);
}
else
name
=
strdup
(
"/dev/null"
);
}
if
(
strcasecmp
(
name
,
"INBOX"
)
==
0
&&
auth_data
->
change_uid
)
name
=
strdup
(
auth_data
->
mailbox
);
else
name
=
namespace_checkfullpath
(
name
,
NULL
,
delim
);
return
name
;
}
int
namespace_init
(
char
*
path
)
{
...
...
imap4d/rename.c
View file @
3373742
...
...
@@ -68,8 +68,9 @@ imap4d_rename (struct imap4d_command *command, char *arg)
if
(
strcasecmp
(
oldname
,
"INBOX"
)
==
0
)
{
mailbox_t
newmbox
=
NULL
;
mailbox_t
inbox
=
NULL
;
char
*
name
;
struct
passwd
*
pw
;
if
(
S_ISDIR
(
newst
.
st_mode
))
{
free
(
newname
);
...
...
@@ -86,31 +87,27 @@ imap4d_rename (struct imap4d_command *command, char *arg)
}
free
(
name
);
free
(
newname
);
pw
=
mu_getpwuid
(
getuid
());
if
(
pw
)
if
(
mailbox_create_default
(
&
inbox
,
auth_data
->
name
)
==
0
&&
mailbox_open
(
inbox
,
MU_STREAM_RDWR
)
==
0
)
{
mailbox_t
inbox
=
NULL
;
if
(
mailbox_create_default
(
&
inbox
,
pw
->
pw_name
)
==
0
&&
mailbox_open
(
inbox
,
MU_STREAM_RDWR
)
==
0
)
size_t
no
;
size_t
total
=
0
;
mailbox_messages_count
(
inbox
,
&
total
);
for
(
no
=
1
;
no
<=
total
;
no
++
)
{
size_t
no
;
size_t
total
=
0
;
mailbox_messages_count
(
inbox
,
&
total
);
for
(
no
=
1
;
no
<=
total
;
no
++
)
message_t
message
;
if
(
mailbox_get_message
(
inbox
,
no
,
&
message
)
==
0
)
{
message_t
message
;
if
(
mailbox_get_message
(
inbox
,
no
,
&
message
)
==
0
)
{
attribute_t
attr
=
NULL
;
mailbox_append_message
(
newmbox
,
message
);
message_get_attribute
(
message
,
&
attr
);
attribute_set_deleted
(
attr
);
}
attribute_t
attr
=
NULL
;
mailbox_append_message
(
newmbox
,
message
);
message_get_attribute
(
message
,
&
attr
);
attribute_set_deleted
(
attr
);
}
mailbox_expunge
(
inbox
);
mailbox_close
(
inbox
);
mailbox_destroy
(
&
inbox
);
}
mailbox_expunge
(
inbox
);
mailbox_close
(
inbox
);
mailbox_destroy
(
&
inbox
);
}
mailbox_close
(
newmbox
);
mailbox_destroy
(
&
newmbox
);
...
...
libmu_scm/mu_util.c
View file @
3373742
...
...
@@ -16,54 +16,52 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "mu_scm.h"
#include <
pwd
.h>
#include <
mailutils/mu_auth
.h>
SCM_DEFINE
(
mu_scm_getpwuid
,
"mu
_getpwuid"
,
0
,
1
,
0
,
SCM_DEFINE
(
mu_scm_getpwuid
,
"mu
-getpwuid"
,
1
,
0
,
0
,
(
SCM
USER
),
"Look up an entry in the user database. USER can be an integer,
\n
"
"
a string, or omitted, giving the behaviour of mu_getpwuid, mu_getpwnam
\n
"
"
or (system) getpwent
respectively.
\n
"
"Returns a vector with fields corresponding to those of the
passwd
\n
"
"
or a string, giving the behaviour of mu_get_auth_by_uid or mu_get_auth_by_name
\n
"
"respectively.
\n
"
"Returns a vector with fields corresponding to those of the
mu_auth_data
\n
"
"entry in question. If no matching entry was found, returns #f.
\n
"
)
#define FUNC_NAME s_mu_scm_getpwuid
{
SCM
result
;
struct
passwd
*
entry
;
struct
mu_auth_data
*
entry
;
SCM
*
ve
;
result
=
scm_make_vector
(
SCM_MAKINUM
(
7
),
SCM_UNSPECIFIED
);
result
=
scm_make_vector
(
SCM_MAKINUM
(
8
),
SCM_UNSPECIFIED
);
ve
=
SCM_VELTS
(
result
);
if
(
SCM_
UNBNDP
(
USER
)
||
SCM_FALSE
P
(
USER
))
if
(
SCM_
INUM
P
(
USER
))
{
entry
=
getpwent
();
}
else
if
(
SCM_INUMP
(
USER
))
{
entry
=
mu_getpwuid
(
SCM_INUM
(
USER
));
entry
=
mu_get_auth_by_uid
(
SCM_INUM
(
USER
));
}
else
{
SCM_VALIDATE_ROSTRING
(
1
,
USER
);
if
(
SCM_SUBSTRP
(
USER
))
USER
=
scm_makfromstr
(
SCM_ROCHARS
(
USER
),
SCM_ROLENGTH
(
USER
),
0
);
entry
=
mu_get
pwnam
(
SCM_ROCHARS
(
USER
));
entry
=
mu_get
_auth_by_name
(
SCM_ROCHARS
(
USER
));
}
if
(
!
entry
)
return
SCM_BOOL_F
;
ve
[
0
]
=
scm_makfrom0str
(
entry
->
pw_
name
);
ve
[
1
]
=
scm_makfrom0str
(
entry
->
p
w_p
asswd
);
ve
[
2
]
=
scm_ulong2num
((
unsigned
long
)
entry
->
pw_
uid
);
ve
[
3
]
=
scm_ulong2num
((
unsigned
long
)
entry
->
pw_
gid
);
ve
[
4
]
=
scm_makfrom0str
(
entry
->
pw_
gecos
);
if
(
!
entry
->
pw_
dir
)
ve
[
0
]
=
scm_makfrom0str
(
entry
->
name
);
ve
[
1
]
=
scm_makfrom0str
(
entry
->
passwd
);
ve
[
2
]
=
scm_ulong2num
((
unsigned
long
)
entry
->
uid
);
ve
[
3
]
=
scm_ulong2num
((
unsigned
long
)
entry
->
gid
);
ve
[
4
]
=
scm_makfrom0str
(
entry
->
gecos
);
if
(
!
entry
->
dir
)
ve
[
5
]
=
scm_makfrom0str
(
""
);
else
ve
[
5
]
=
scm_makfrom0str
(
entry
->
pw_
dir
);
if
(
!
entry
->
pw_
shell
)
ve
[
5
]
=
scm_makfrom0str
(
entry
->
dir
);
if
(
!
entry
->
shell
)
ve
[
6
]
=
scm_makfrom0str
(
""
);
else
ve
[
6
]
=
scm_makfrom0str
(
entry
->
pw_shell
);
ve
[
6
]
=
scm_makfrom0str
(
entry
->
shell
);
ve
[
7
]
=
scm_makfrom0str
(
entry
->
mailbox
);
mu_auth_data_free
(
entry
);
return
result
;
}
#undef FUNC_NAME
...
...
mail.local/main.c
View file @
3373742
...
...
@@ -176,7 +176,7 @@ main (int argc, char *argv[])
umask
(
0077
);
mu_argp_error_code
=
EX_CONFIG
;
MU_AUTH_REGISTER_ALL_MODULES
();
mu_argp_parse
(
&
argp
,
&
argc
,
&
argv
,
0
,
argp_capa
,
&
arg_index
,
NULL
);
openlog
(
"mail.local"
,
LOG_PID
,
log_facility
);
...
...
@@ -193,16 +193,6 @@ main (int argc, char *argv[])
return
EX_USAGE
;
}
#ifdef HAVE_MYSQL
mu_register_getpwnam
(
getMpwnam
);
mu_register_getpwuid
(
getMpwuid
);
#endif
#ifdef USE_VIRTUAL_DOMAINS
mu_register_getpwnam
(
getpwnam_virtual
);
mu_register_getpwnam
(
getpwnam_ip_virtual
);
mu_register_getpwnam
(
getpwnam_host_virtual
);
#endif
/* Register local mbox formats. */
{
list_t
bookie
;
...
...
@@ -308,11 +298,12 @@ make_tmp (const char *from, char **tempfile)
{
if
(
memcmp
(
buf
,
"From "
,
5
))
{
struct
mu_auth_data
*
auth
;
if
(
!
from
)
{
struct
passwd
*
pw
=
mu_getpw
uid
(
uid
);
if
(
pw
)
from
=
pw
->
pw_
name
;
auth
=
mu_get_auth_by_
uid
(
uid
);
if
(
auth
)
from
=
auth
->
name
;
}
if
(
from
)
{
...
...
@@ -324,6 +315,8 @@ make_tmp (const char *from, char **tempfile)
mailer_err
(
"Can't determine sender address"
);
exit
(
EX_UNAVAILABLE
);
}
if
(
auth
)
mu_auth_data_free
(
auth
);
}
}
else
if
(
!
memcmp
(
buf
,
"From "
,
5
))
...
...
@@ -353,7 +346,7 @@ deliver (FILE *fp, char *name)
url_t
url
=
NULL
;
size_t
n
=
0
;
locker_t
lock
;
struct
passwd
*
pw
;
struct
mu_auth_data
*
auth
;
int
status
;
stream_t
stream
;
size_t
size
;
...
...
@@ -362,15 +355,15 @@ deliver (FILE *fp, char *name)
struct
stat
sb
;
#endif
pw
=
mu_getpwnam
(
name
);
if
(
!
pw
)
auth
=
mu_get_auth_by_name
(
name
);
if
(
!
auth
)
{
mailer_err
(
"%s: no such user"
,
name
);
exit_code
=
EX_UNAVAILABLE
;
return
;
}
path
=
malloc
(
strlen
(
mu_path_maildir
)
+
strlen
(
name
)
+
1
);
path
=
strdup
(
auth
->
mailbox
);
if
(
!
path
)
{
mailer_err
(
"Out of memory"
);
...
...
@@ -393,7 +386,7 @@ deliver (FILE *fp, char *name)
/* Actually open the mailbox. Switch to the user's euid to make
sure the maildrop file will have right privileges, in case it
will be created */
if
(
switch_user_id
(
pw
->
pw_
uid
))
if
(
switch_user_id
(
auth
->
uid
))
return
;
status
=
mailbox_open
(
mbox
,
MU_STREAM_RDWR
|
MU_STREAM_CREAT
);
if
(
switch_user_id
(
0
))
...
...
@@ -463,7 +456,7 @@ deliver (FILE *fp, char *name)
}
#endif
if
(
!
failed
&&
switch_user_id
(
pw
->
pw_
uid
)
==
0
)
if
(
!
failed
&&
switch_user_id
(
auth
->
uid
)
==
0
)
{
off_t
off
=
size
;
size_t
nwr
;
...
...
@@ -490,6 +483,7 @@ deliver (FILE *fp, char *name)
locker_unlock
(
lock
);
mu_auth_data_free
(
auth
);
mailbox_close
(
mbox
);
mailbox_destroy
(
&
mbox
);
}
...
...
mail.local/script.c
View file @
3373742
...
...
@@ -73,15 +73,16 @@ mda_init (void *data)
static
void
mda_switch_to_user
(
struct
mda_data
*
md
)
{
struct
passwd
*
pw
=
NULL
;
struct
mu_auth_data
*
auth
=
NULL
;
if
(
md
&&
*
md
->
argv
!=
NULL
)
pw
=
mu_getpwnam
(
*
md
->
argv
);
auth
=
mu_get_auth_by_name
(
*
md
->
argv
);
if
(
pw
)
if
(
auth
)
{
switch_user_id
(
pw
->
pw_uid
);
chdir
(
pw
->
pw_dir
);
switch_user_id
(
auth
->
uid
);
chdir
(
auth
->
dir
);
mu_auth_data_free
(
auth
);
}
else
{
...
...
mailbox/mbx_default.c
View file @
3373742
...
...
@@ -34,6 +34,7 @@
#include <mailutils/mutil.h>
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/mu_auth.h>
const
char
*
mu_path_maildir
=
MU_PATH_MAILDIR
;
...
...
@@ -93,12 +94,13 @@ static const char *
get_homedir
(
const
char
*
user
)
{
const
char
*
homedir
=
NULL
;
struct
passwd
*
pw
=
NULL
;
struct
mu_auth_data
*
auth
=
NULL
;
if
(
user
)
{
pw
=
mu_getpwnam
(
user
);
if
(
pw
)
homedir
=
pw
->
pw_
dir
;
auth
=
mu_get_auth_by_name
(
user
);
if
(
auth
)
homedir
=
auth
->
dir
;
}
else
{
...
...
@@ -107,16 +109,20 @@ get_homedir (const char *user)
homedir
=
getenv
(
"HOME"
);
if
(
homedir
==
NULL
)
{
pw
=
mu_getpwuid
(
getuid
()
);
if
(
pw
)
homedir
=
pw
->
pw_
dir
;
auth
=
mu_get_auth_by_name
(
user
);
if
(
auth
)
homedir
=
auth
->
dir
;
}
#else
pw
=
mu_getpwuid
(
getuid
()
);
if
(
pw
)
homedir
=
pw
->
pw_
dir
;
auth
=
mu_get_auth_by_name
(
user
);
if
(
auth
)
homedir
=
auth
->
dir
;
#endif
}
if
(
homedir
)
homedir
=
strdup
(
homedir
);
mu_auth_data_free
(
auth
);
return
homedir
;
}
...
...
@@ -136,22 +142,27 @@ user_mailbox_name (const char *user, char **mailbox_name)
if
(
!
user
)
user
=
(
getenv
(
"LOGNAME"
))
?
getenv
(
"LOGNAME"
)
:
getenv
(
"USER"
);
#endif
if
(
user
==
NULL
)
if
(
user
)
{
struct
passwd
*
pw
;
pw
=
mu_getpwuid
(
getuid
());
if
(
pw
)
user
=
pw
->
pw_name
;
else
*
mailbox_name
=
malloc
(
strlen
(
user
)
+
strlen
(
mu_path_maildir
)
+
2
);
if
(
*
mailbox_name
==
NULL
)
return
ENOMEM
;
sprintf
(
*
mailbox_name
,
"%s%s"
,
mu_path_maildir
,
user
);
}
else
{
struct
mu_auth_data
*
auth
=
mu_get_auth_by_uid
(
getuid
());
if
(
!
auth
)
{
mu_error
(
"Who am I ?
\n
"
);
return
EINVAL
;
}
*
mailbox_name
=
strdup
(
auth
->
mailbox
);
mu_auth_data_free
(
auth
);
}
*
mailbox_name
=
malloc
(
strlen
(
user
)
+
strlen
(
mu_path_maildir
)
+
2
);
if
(
*
mailbox_name
==
NULL
)
return
ENOMEM
;
sprintf
(
*
mailbox_name
,
"%s%s"
,
mu_path_maildir
,
user
);
return
0
;
}
...
...
@@ -188,6 +199,7 @@ plus_expand (const char *file, char **buf)
(
*
buf
)[
len
-
1
]
=
0
;
free
(
user
);
free
(
path
);
free
(
home
);
return
0
;
}
...
...
mailbox/message.c
View file @
3373742
...
...
@@ -47,6 +47,7 @@
#include <mailutils/mutil.h>
#include <mailutils/observer.h>
#include <mailutils/stream.h>
#include <mailutils/mu_auth.h>
#define MESSAGE_MODIFIED 0x10000;
...
...
@@ -971,18 +972,18 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
/* oops! We are still here */
{
struct
passwd
*
pw
;
const
char
*
sender
;
pw
=
mu_getpwuid
(
getuid
());
sender
=
(
pw
)
?
pw
->
pw_name
:
"unknown"
;
struct
mu_auth_data
*
auth
=
mu_get_auth_by_uid
(
getuid
());
const
char
*
sender
=
auth
?
auth
->
name
:
"unknown"
;
n
=
strlen
(
sender
);
if
(
buf
&&
len
>
0
)
{
len
--
;
/* One for the null. */
n
=
(
n
<
len
)
?
n
:
len
;
memcpy
(
buf
,
pw
->
pw_
name
,
n
);
memcpy
(
buf
,
auth
->
name
,
n
);
buf
[
n
]
=
'\0'
;
}
if
(
auth
)
mu_auth_data_free
(
auth
);
}
if
(
pnwrite
)
...
...
mailbox/wicket.c
View file @
3373742
...
...
@@ -30,6 +30,7 @@
#include <mailutils/errno.h>
#include <mailutils/mutil.h>
#include <mailutils/mu_auth.h>
#include <auth0.h>
#include <url0.h>
...
...
@@ -399,10 +400,11 @@ get_user (url_t url, const char *filename, char **user)
}
else
{
struct
passwd
*
pw
=
mu_getpw
uid
(
getuid
());
if
(
pw
&&
pw
->
pw_name
)
struct
mu_auth_data
*
auth
=
mu_get_auth_by_
uid
(
getuid
());
if
(
auth
)
{
u
=
strdup
(
pw
->
pw_name
);
u
=
strdup
(
auth
->
name
);
mu_auth_data_free
(
auth
);
if
(
!
u
)
return
ENOMEM
;
}
...
...
pop3d/pop3d.c
View file @
3373742
...
...
@@ -17,10 +17,6 @@
#include "pop3d.h"
#ifdef HAVE_MYSQL
# include "../MySql/MySql.h"
#endif
mailbox_t
mbox
;
int
state
;
char
*
username
;
...
...
@@ -91,6 +87,7 @@ main (int argc, char **argv)
struct
group
*
gr
;
int
status
=
OK
;
MU_AUTH_REGISTER_ALL_MODULES
();
mu_argp_parse
(
&
argp
,
&
argc
,
&
argv
,
0
,
pop3d_argp_capa
,
NULL
,
&
daemon_param
);
#ifdef USE_LIBPAM
...
...
@@ -127,16 +124,6 @@ main (int argc, char **argv)
list_append
(
bookie
,
path_record
);
}
#ifdef HAVE_MYSQL
mu_register_getpwnam
(
getMpwnam
);
mu_register_getpwuid
(
getMpwuid
);
#endif
#ifdef USE_VIRTUAL_DOMAINS
mu_register_getpwnam
(
getpwnam_virtual
);
mu_register_getpwnam
(
getpwnam_ip_virtual
);
mu_register_getpwnam
(
getpwnam_host_virtual
);
#endif
/* Set the signal handlers. */
signal
(
SIGINT
,
pop3d_signal
);
signal
(
SIGQUIT
,
pop3d_signal
);
...
...
pop3d/user.c
View file @
3373742
...
...
@@ -17,80 +17,14 @@
#include "pop3d.h"
#ifdef HAVE_MYSQL
# include "../MySql/MySql.h"
#endif
#ifdef USE_LIBPAM
#define COPY_STRING(s) (s) ? strdup(s) : NULL
static
char
*
_pwd
;
static
char
*
_user
;
static
int
_perr
=
0
;
#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \
goto pam_errlab;
static
int
PAM_gnupop3d_conv
(
int
num_msg
,
const
struct
pam_message
**
msg
,
struct
pam_response
**
resp
,
void
*
appdata_ptr
)
{
int
replies
=
0
;
struct
pam_response
*
reply
=
NULL
;
(
void
)
appdata_ptr
;
reply
=
malloc
(
sizeof
(
*
reply
)
*
num_msg
);
if
(
!
reply
)
return
PAM_CONV_ERR
;
for
(
replies
=
0
;
replies
<
num_msg
;
replies
++
)
{
switch
(
msg
[
replies
]
->
msg_style
)
{
case
PAM_PROMPT_ECHO_ON
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
COPY_STRING
(
_user
);
/* PAM frees resp */
break
;
case
PAM_PROMPT_ECHO_OFF
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
COPY_STRING
(
_pwd
);
/* PAM frees resp */
break
;
case
PAM_TEXT_INFO
:
case
PAM_ERROR_MSG
:
reply
[
replies
].
resp_retcode
=
PAM_SUCCESS
;
reply
[
replies
].
resp
=
NULL
;
break
;
default:
free
(
reply
);
_perr
=
1
;
return
PAM_CONV_ERR
;
}
}
*
resp
=
reply
;
return
PAM_SUCCESS
;
}
static
struct
pam_conv
PAM_conversation
=
{
&
PAM_gnupop3d_conv
,
NULL
};
#endif
/* USE_LIBPAM */
/* Basic user authentication. This also takes the PASS command and verifies
the user name and password. Calls setuid() upon successful verification,
otherwise it will (likely) return ERR_BAD_LOGIN */
int
pop3d_user
(
const
char
*
arg
)
{
char
*
buf
,
pass
[
POP_MAXCMDLEN
],
*
tmp
,
*
cmd
;
struct
passwd
*
pw
;
int
status
;
int
lockit
=
1
;
char
*
mailbox_name
=
NULL
;
struct
mu_auth_data
*
auth_data
;
if
(
state
!=
AUTHORIZATION
)
return
ERR_WRONG_STATE
;
...
...
@@ -118,14 +52,10 @@ pop3d_user (const char *arg)
free
(
tmp
);
}
if
(
str
len
(
cmd
)
>
4
)
if
(
str
casecmp
(
cmd
,
"PASS"
)
==
0
)
{
free
(
cmd
);
return
ERR_BAD_CMD
;
}
int
rc
;
if
((
strcasecmp
(
cmd
,
"PASS"
)
==
0
))
{
free
(
cmd
);
#ifdef _USE_APOP
...
...
@@ -139,136 +69,93 @@ pop3d_user (const char *arg)
}
#endif
pw
=
mu_getpwnam
(
arg
);
auth_data
=
mu_get_auth_by_name
(
arg
);
if
(
pw
==
NULL
)
if
(
auth_data
==
NULL
)
{
syslog
(
LOG_INFO
,
"User '%s': nonexistent"
,
arg
);
return
ERR_BAD_LOGIN
;
}
#ifndef USE_LIBPAM
if
(
pw
->
pw_uid
<
1
)
return
ERR_BAD_LOGIN
;
if
(
strcmp
(
pw
->
pw_passwd
,
(
char
*
)
crypt
(
pass
,
pw
->
pw_passwd
)))
{
#ifdef HAVE_SHADOW_H
struct
spwd
*
spw
;
spw
=
getspnam
((
char
*
)
arg
);
#ifdef HAVE_MYSQL
if
(
spw
==
NULL
)
spw
=
getMspnam
(
arg
);
#endif
/* HAVE_MYSQL */
if
(
spw
==
NULL
||
strcmp
(
spw
->
sp_pwdp
,
(
char
*
)
crypt
(
pass
,
spw
->
sp_pwdp
)))
#endif
/* HAVE_SHADOW_H */
{
syslog
(
LOG_INFO
,
"User '%s': authentication failed"
,
arg
);
return
ERR_BAD_LOGIN
;
}
}
#else
/* !USE_LIBPAM */
{
pam_handle_t
*
pamh
;
int
pamerror
;
_user
=
(
char
*
)
arg
;
_pwd
=
pass
;
/* libpam doesn't log to LOG_MAIL */
closelog
();
pamerror
=
pam_start
(
pam_service
,
arg
,
&
PAM_conversation
,
&
pamh
);
PAM_ERROR
;
pamerror
=
pam_authenticate
(
pamh
,
0
);
PAM_ERROR
;
pamerror
=
pam_acct_mgmt
(
pamh
,
0
);
PAM_ERROR
;
pamerror
=
pam_setcred
(
pamh
,
PAM_ESTABLISH_CRED
);
pam_errlab:
pam_end
(
pamh
,
PAM_SUCCESS
);
openlog
(
"gnu-pop3d"
,
LOG_PID
,
log_facility
);
if
(
pamerror
!=
PAM_SUCCESS
)
{
syslog
(
LOG_INFO
,
"User '%s': authentication failed"
,
_user
);
return
ERR_BAD_LOGIN
;
}
}
#endif
/* USE_LIBPAM */
rc
=
mu_authenticate
(
auth_data
,
pass
);
openlog
(
"gnu-pop3d"
,
LOG_PID
,
log_facility
);
if
(
pw
->
pw_uid
>
0
&&
!
mu_virtual_domain
)
if
(
rc
)
{
setuid
(
pw
->
pw_uid
);
mailbox_name
=
malloc
(
strlen
(
mu_path_maildir
)
+
strlen
(
pw
->
pw_name
)
+
1
);
if
(
!
mailbox_name
)
{
syslog
(
LOG_ERR
,
"Not enough memory"
);
return
ERR_UNKNOWN
;
}
sprintf
(
mailbox_name
,
"%s%s"
,
mu_path_maildir
,
pw
->
pw_name
);
}
else
if
(
mu_virtual_domain
)
{
mailbox_name
=
calloc
(
strlen
(
pw
->
pw_dir
)
+
strlen
(
"/INBOX"
),
1
);
sprintf
(
mailbox_name
,
"%s/INBOX"
,
pw
->
pw_dir
);
syslog
(
LOG_INFO
,
"User '%s': authentication failed"
,
arg
);
mu_auth_data_free
(
auth_data
);
return
ERR_BAD_LOGIN
;
}
}
else
if
(
strcasecmp
(
cmd
,
"QUIT"
)
==
0
)
{
syslog
(
LOG_INFO
,
"Possible probe of account '%s'"
,
arg
);
free
(
cmd
);
return
pop3d_quit
(
pass
);
}
else
{
free
(
cmd
);
return
ERR_BAD_CMD
;
}
if
((
status
=
mailbox_create
(
&
mbox
,
mailbox_name
))
!=
0
||
(
status
=
mailbox_open
(
mbox
,
MU_STREAM_RDWR
))
!=
0
)
if
(
auth_data
->
change_uid
)
setuid
(
auth_data
->
uid
);
if
((
status
=
mailbox_create
(
&
mbox
,
auth_data
->
mailbox
))
!=
0
||
(
status
=
mailbox_open
(
mbox
,
MU_STREAM_RDWR
))
!=
0
)
{
mailbox_destroy
(
&
mbox
);
/* For non existent mailbox, we fake. */
if
(
status
==
ENOENT
)
{
mailbox_destroy
(
&
mbox
);
/* For non existent mailbox, we fake. */
if
(
status
==
ENOENT
)
{
if
(
mailbox_create
(
&
mbox
,
"/dev/null"
)
!=
0
||
mailbox_open
(
mbox
,
MU_STREAM_READ
)
!=
0
)
{
state
=
AUTHORIZATION
;
free
(
mailbox_name
);
return
ERR_UNKNOWN
;
}
}
else
if
(
mailbox_create
(
&
mbox
,
"/dev/null"
)
!=
0
||
mailbox_open
(
mbox
,
MU_STREAM_READ
)
!=
0
)
{
state
=
AUTHORIZATION
;
free
(
mailbox_name
);
return
ERR_
MBOX_LOCK
;
mu_auth_data_free
(
auth_data
);
return
ERR_
UNKNOWN
;
}
lockit
=
0
;
/* Do not attempt to lock /dev/null ! */
}
free
(
mailbox_name
);
if
(
lockit
&&
pop3d_lock
())
else
{
mailbox_close
(
mbox
);
mailbox_destroy
(
&
mbox
);
state
=
AUTHORIZATION
;
mu_auth_data_free
(
auth_data
);
return
ERR_MBOX_LOCK
;
}
username
=
strdup
(
pw
->
pw_name
);
if
(
username
==
NULL
)
pop3d_abquit
(
ERR_NO_MEM
);
state
=
TRANSACTION
;
pop3d_outf
(
"+OK opened mailbox for %s
\r\n
"
,
username
);
/* mailbox name */
{
url_t
url
=
NULL
;
size_t
total
=
0
;
mailbox_get_url
(
mbox
,
&
url
);
mailbox_messages_count
(
mbox
,
&
total
);
syslog
(
LOG_INFO
,
"User '%s' logged in with mailbox '%s' (%d msgs)"
,
username
,
url_to_string
(
url
),
total
);
}
return
OK
;
lockit
=
0
;
/* Do not attempt to lock /dev/null ! */
}
else
if
(
strcasecmp
(
cmd
,
"QUIT"
)
==
0
)
if
(
lockit
&&
pop3d_lock
())
{
syslog
(
LOG_INFO
,
"Possible probe of account '%s'"
,
arg
);
free
(
cmd
);
return
pop3d_quit
(
pass
);
mailbox_close
(
mbox
);
mailbox_destroy
(
&
mbox
);
mu_auth_data_free
(
auth_data
);
state
=
AUTHORIZATION
;
return
ERR_MBOX_LOCK
;
}
username
=
strdup
(
auth_data
->
name
);
if
(
username
==
NULL
)
pop3d_abquit
(
ERR_NO_MEM
);
state
=
TRANSACTION
;
mu_auth_data_free
(
auth_data
);
pop3d_outf
(
"+OK opened mailbox for %s
\r\n
"
,
username
);
/* mailbox name */
{
url_t
url
=
NULL
;
size_t
total
=
0
;
mailbox_get_url
(
mbox
,
&
url
);
mailbox_messages_count
(
mbox
,
&
total
);
syslog
(
LOG_INFO
,
"User '%s' logged in with mailbox '%s' (%d msgs)"
,
username
,
url_to_string
(
url
),
total
);
}
return
OK
;
free
(
cmd
);
return
ERR_BAD_LOGIN
;
}
...
...
Please
register
or
sign in
to post a comment