sbr/context_find.c sbr/context_foil.c sbr/context_read.c \
sbr/context_replace.c sbr/context_save.c \
sbr/copy.c sbr/copyip.c sbr/cpydata.c \
- sbr/cpydgst.c sbr/crawl_folders.c sbr/discard.c \
- sbr/done.c sbr/dtimep.l sbr/dtime.c \
+ sbr/cpydgst.c sbr/crawl_folders.c sbr/credentials.c \
+ sbr/discard.c sbr/done.c sbr/dtimep.l sbr/dtime.c \
sbr/escape_addresses.c \
sbr/error.c sbr/ext_hook.c sbr/fdcompare.c \
sbr/folder_addmsg.c sbr/folder_delmsgs.c \
/* default name of user profile */
char *mh_profile = ".mh_profile";
+/* name of credentials file, defaults to .netrc in either Path or $HOME. */
+char *credentials_file;
+
/* name of current message "sequence" */
char *current = "cur";
- Removed the artificial limit of 1000 messages at a time for rmmproc.
- Fixed decoding of header fields when they contain a character that
can't be converted.
+- post(8) -sasl now honours username in .netrc [Bug #23168]. whom(1),
+ send(1), inc(1), and msgchk(1) also benefit from this fix. And, nmh
+ now supports specification of any valid filename in place of
+ $HOME/.netrc.
#define NMH_ATTACH_HEADER "Nmh-Attachment" /* Default header for -attach */
+/*
+ * credentials management
+ */
+struct nmh_creds {
+ char *host;
+ char *user;
+ char *password;
+};
+
+typedef struct nmh_creds *nmh_creds_t;
+
/*
* miscellaneous macros
*/
extern char *components;
extern char *context;
extern char *current;
+extern char *credentials_file;
extern char *defaultfolder;
extern char *digestcomps;
extern char *distcomps;
char *r1bindex(char *, int);
void readconfig (struct node **, FILE *, char *, int);
int refile (char **, char *);
-void ruserpass(char *, char **, char **);
+void ruserpass (char *, char **, char **);
int remdir (char *);
void scan_detect_mbox_style (FILE *);
void scan_finished ();
int WhatNow(int, char **);
int writeBase64aux(FILE *, FILE *);
int writeBase64 (unsigned char *, size_t, unsigned char *);
+
+/*
+ * credentials management
+ */
+void init_credentials_file ();
+int nmh_get_credentials (char *, char *, int, nmh_creds_t);
-.TH INC %manext1% "February 16, 2013" "%nmhversion%"
+.TH INC %manext1% "April 14, 2013" "%nmhversion%"
.\"
.\" %nmhwarning%
.\"
switch specifies the port name or number used to connect to the POP
server. If unspecified the default is \*(lqpop3\*(rq.
.PP
-The default is for
-.B inc
-to assume that your account name on
-the POP server is the same as your current username. To specify
-a different username, use the
+To specify a username for authentication with the POP server, use the
.B \-user
.I username
-switch.
-.PP
-When using POP, you will normally need to type the password for
-your account on the POP server, in order to retrieve your messages.
-It is possible to automate this process by creating a
-.RI \*(lq .netrc \*(rq
-file containing your login account information for this POP server.
-For each POP server, this file should have a line of the following
-form. Replace the words
-.IR mypopserver ,
-.IR mylogin ,
-and
-.I mypassword
-with your own account information.
-.PP
-.RS 5
-.B machine
-.I mypopserver
-.B login
-.I mylogin
-.B password
-.I mypassword
-.RE
-.PP
-This
-.RI \*(lq .netrc \*(rq
-file should be owned and readable only by you.
+switch. The credentials profile entry in the mh_profile(5) man page
+describes the ways to supply a username and password.
.PP
If passed the
.B \-proxy
switch will enable
the use of SASL authentication. Depending on the SASL mechanism used, this
may require an additional password prompt from the user (but the
-.RI \*(lq .netrc \*(rq
-file can be used to store this password). The
+.I netrc
+file can be used to store this password, as described in the
+mh-profile(5) man page). The
.B \-saslmech
switch can be used to select a particular SASL mechanism.
.PP
.IR mhmail (1),
.IR scan (1),
.IR mh\-mail (5),
+.IR mh\-profile (5),
.IR post (8),
.IR rcvstore (1)
.SH DEFAULTS
-.TH MH-PROFILE %manext5% "March 18, 2013" "%nmhversion%"
+.TH MH-PROFILE %manext5% "April 14, 2013" "%nmhversion%"
.\"
.\" %nmhwarning%
.\"
signature text. The \*(lqLocal\-Mailbox\*(rq profile component
supersedes all of this. (profile, no default)
.RE
+.PP
+.BR credentials :
+\&legacy
+.RS 5
+Indicates how the username and password credentials will be retrieved
+for access to external servers, such as those that provide SMTP or POP
+service. The supported entry values are \*(lqlegacy\*(rq and
+.RI \*(lqfile: netrc \*(rq.
+With \*(lqlegacy\*(rq, or if there is no credentials entry, the
+username is the first of:
+.PP
+.RS 5
+1)
+.B \-user
+switch to
+.BR send ,
+.BR post ,
+.BR whom ,
+.BR inc ,
+or
+.B msgchk
+program
+.br
+2) the login name on the local machine
+.RE
+.PP
+The password for SMTP services is the first of:
+.PP
+.RS 5
+1) password value from matching entry in file named \*(lq.netrc\*(rq
+in the user's home directory
+.br
+2) password obtained by interactively prompting the user
+.RE
+.PP
+The password for POP service when the
+.B \-sasl
+switch is used with one of these programs is the login name on the
+local machine.
+.PP
+With a
+.RI \*(lqfile: netrc \*(rq
+.B credentials
+entry, the username is the first of:
+.PP
+.RS 5
+1)
+.B \-user
+switch to program
+.br
+2) login name from matching entry in
+.I netrc
+file
+.br
+3) value provided by user in response to interactive query
+.RE
+.PP
+Similarly, the password is provided either in the
+.I netrc
+file or interactively.
+.I netrc
+can be any valid filename, either absolute or relative to Path or
+$HOME. The
+.I netrc
+file contains authentication information, for each server,
+using a line of the following form. Replace the words
+.IR myserver ,
+.IR mylogin ,
+and
+.I mypassword
+with your own account information:
+.PP
+.RS 5
+.B machine
+.I myserver
+.B login
+.I mylogin
+.B password
+.I mypassword
+.RE
+.PP
+This
+.I netrc
+file must be owned and readable only by you.
+(profile, default: legacy)
+.RE
.SS "Process Profile Entries"
The following profile elements are used whenever an
.B nmh
-.TH MSGCHK %manext1% "January 27, 2012" "%nmhversion%"
+.TH MSGCHK %manext1% "April 14, 2013" "%nmhversion%"
.\"
.\" %nmhwarning%
.\"
will query this POP service host as to the status of
mail waiting.
.PP
-The default is for
-.B msgchk
-to assume that your account name
-on the POP server is the same as your current username. To specify
-a different username, use the `\-user\ username' switch.
-.PP
-When using POP, you will normally need to type the password for
-your account on the POP server, in order to retrieve your messages.
-It is possible to automate this process by creating a
-.RI \*(lq \&.netrc \*(rq
-file containing your login account information for this POP server.
-For each POP server, this file should have a line of the following
-form. Replace the words
-.IR mypopserver ,
-.IR mylogin ,
-and
-.I mypassword
-with
-your own account information.
-.PP
-.RS 5
-machine
-.I mypopserver
-login
-.I mylogin
-password
-.I mypassword
-.RE
-.PP
-This
-.RI \*(lq \&.netrc \*(rq
-file should be owned and readable only by you.
+To specify a username for authentication with the POP server, use the
+.B \-user
+.I username
+switch. The credentials profile entry in the mh_profile(5) man page
+describes the ways to supply a username and password.
.PP
For debugging purposes, there is also a switch
.BR \-snoop ,
switch will enable
the use of SASL authentication. Depending on the SASL mechanism used, this
may require an additional password prompt from the user (but the
-.RI \*(lq \&.netrc \*(rq
-file can be used to store this password). The
+.I netrc
+file can be used to store this password, as described in the
+mh-profile(5) man page). The
.B \-saslmech
switch can be used to select a particular SASL mechanism.
.PP
None
.fi
.SH "SEE ALSO"
-.IR inc (1)
+.IR inc (1),
+.IR mh\-mail (5)
.SH DEFAULTS
.nf
.RB ` user "' defaults to the current user"
-.TH POST %manext8% "April 9, 2013" "%nmhversion%"
+.TH POST %manext8% "April 14, 2013" "%nmhversion%"
.\"
.\" %nmhwarning%
.\"
the use of SASL authentication with the SMTP MTA. Depending on the
SASL mechanism used, this may require an additional password prompt from the
user (but the
-.RI \*(lq \&.netrc \*(rq
-file can be used to store this password).
+.I netrc
+file can be used to store this password, as described in the
+mh-profile(5) man page). The
.B \-saslmech
switch can be used to select a particular SASL mechanism,
and the
.B \-user
-switch can be used to select a authorization userid
-to provide to SASL other than the default.
+switch can be used to select a authorization userid to provide to SASL
+other than the default. The credentials profile entry in the
+mh_profile(5) man page describes the ways to supply a username and
+password.
.PP
If SASL authentication is successful,
.BR nmh
.IR send (1),
.IR mh\-mail (5),
.IR mh\-alias (5),
+.IR mh\-profile (5),
.IR mh\-tailor (5)
.PP
.I "Standard for the Format of ARPA Internet Text Messages"
.\"
.\" %nmhwarning%
.\"
-.TH SEND %manext1% "April 9, 2013" "%nmhversion%"
+.TH SEND %manext1% "April 14, 2013" "%nmhversion%"
.SH NAME
send \- send a message
.SH SYNOPSIS
the use of SASL authentication with the SMTP MTA. Depending on the
SASL mechanism used, this may require an additional password prompt from the
user (but the
-.RI \*(lq \&.netrc \*(rq
-file can be used to store this password).
+.I netrc
+file can be used to store this password, as described in the
+mh-profile(5) man page). The
.B \-saslmech
switch can be used to select a particular SASL mechanism,
and the
.B \-user
-switch can be used to select a authorization userid
-to provide to SASL other than the default.
+switch can be used to select a authorization userid to provide to SASL
+other than the default. The credentials profile entry in the
+mh_profile(5) man page describes the ways to supply a username and
+password.
.PP
If SASL authentication is successful,
.BR nmh
.IR repl (1),
.IR whatnow (1),
.IR mh\-alias (5),
+.IR mh\-profile (5),
.IR mh\-tailor (5),
.IR post (8)
.SH DEFAULTS
-.TH WHOM %manext1% "April 9, 2013" "%nmhversion%"
+.TH WHOM %manext1% "April 14, 2013" "%nmhversion%"
.\"
.\" %nmhwarning%
.\"
the use of SASL authentication with the SMTP MTA. Depending on the
SASL mechanism used, this may require an additional password prompt from the
user (but the
-.RI \*(lq \&.netrc \*(rq
-file can be used to store this password).
+.I netrc
+file can be used to store this password, as described in the
+mh-profile(5) man page). The
.B \-saslmech
switch can be used to select a particular SASL mechanism,
and the
.B \-user
-switch can be used to select a authorization userid
-to provide to SASL other than the default.
+switch can be used to select a authorization userid to provide to SASL
+other than the default. The credentials profile entry in the
+mh_profile(5) man page describes the ways to supply a username and
+password.
.PP
If SASL authentication is successful,
.BR nmh
.fi
.SH "SEE ALSO"
.IR mh\-alias (5),
+.IR mh\-profile (5),
.IR post (8)
.SH DEFAULTS
.nf
static sasl_conn_t *conn = NULL; /* SASL connection state */
static int sasl_complete = 0; /* Has authentication succeded? */
static sasl_ssf_t sasl_ssf; /* Our security strength factor */
-static char *sasl_pw_context[2]; /* Context to pass into sm_get_pass */
+static char *sasl_pw_context[3]; /* Context to pass into sm_get_pass */
static int maxoutbuf; /* Maximum crypto output buffer */
static char *sasl_outbuffer; /* SASL output buffer for encryption */
static int sasl_outbuflen; /* Current length of data in outbuf */
static sasl_callback_t callbacks[] = {
{ SASL_CB_USER, (sasl_callback_ft) sm_get_user, NULL },
#define SM_SASL_N_CB_USER 0
- { SASL_CB_PASS, (sasl_callback_ft) sm_get_pass, NULL },
-#define SM_SASL_N_CB_PASS 1
{ SASL_CB_AUTHNAME, (sasl_callback_ft) sm_get_user, NULL },
-#define SM_SASL_N_CB_AUTHNAME 2
+#define SM_SASL_N_CB_AUTHNAME 1
+ { SASL_CB_PASS, (sasl_callback_ft) sm_get_pass, NULL },
+#define SM_SASL_N_CB_PASS 2
{ SASL_CB_LIST_END, NULL, NULL },
};
sasl_security_properties_t secprops;
sasl_ssf_t *ssf;
int *outbufmax;
+ char *pass = NULL;
/*
* Initialize the callback contexts
*/
- if (user == NULL)
- user = getusername();
-
- callbacks[SM_SASL_N_CB_USER].context = user;
- callbacks[SM_SASL_N_CB_AUTHNAME].context = user;
-
/*
* This is a _bit_ of a hack ... but if the hostname wasn't supplied
* to us on the command line, then call getpeername and do a
strncpy(host, inhost, sizeof(host) - 1);
}
+ callbacks[SM_SASL_N_CB_USER].context = user;
+ callbacks[SM_SASL_N_CB_AUTHNAME].context = user;
+
sasl_pw_context[0] = host;
sasl_pw_context[1] = user;
+ sasl_pw_context[2] = pass;
callbacks[SM_SASL_N_CB_PASS].context = sasl_pw_context;
sasl_secret_t **psecret)
{
char **pw_context = (char **) context;
- char *pass = NULL;
int len;
NMH_UNUSED (conn);
if (! psecret || id != SASL_CB_PASS)
return SASL_BADPARAM;
- ruserpass(pw_context[0], &(pw_context[1]), &pass);
-
- len = strlen(pass);
-
- *psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len);
+ len = strlen (pw_context[2]);
- if (! *psecret) {
- free(pass);
+ if (! (*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len))) {
return SASL_NOMEM;
}
(*psecret)->len = len;
- strcpy((char *) (*psecret)->data, pass);
-/* free(pass); */
+ strcpy((char *) (*psecret)->data, pw_context[2]);
return SASL_OK;
}
--- /dev/null
+/*
+ * This code is Copyright (c) 2013, by the authors of nmh. See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
+ */
+
+#include <h/mh.h>
+#include <h/utils.h>
+#include <h/mts.h>
+
+void
+init_credentials_file () {
+ if (credentials_file == NULL) {
+ char *cred_style = context_find ("credentials");
+
+ if (cred_style == NULL || ! strcmp (cred_style, "legacy")) {
+ char *hdir = getenv ("HOME");
+
+ credentials_file = concat (hdir ? hdir : ".", "/.netrc", NULL);
+ } else if (! strncasecmp (cred_style, "file:", 5)) {
+ struct stat st;
+ char *filename = cred_style + 5;
+
+ while (*filename && isspace ((int) *filename)) ++filename;
+
+ if (*filename == '/') {
+ credentials_file = filename;
+ } else {
+ credentials_file = m_maildir (filename);
+ if (stat (credentials_file, &st) != OK) {
+ credentials_file =
+ concat (mypath ? mypath : ".", "/", filename, NULL);
+ if (stat (credentials_file, &st) != OK) {
+ admonish (NULL, "unable to find credentials file %s",
+ filename);
+ }
+ }
+ }
+ }
+ }
+}
+
+int
+nmh_get_credentials (char *host, char *user, int sasl, nmh_creds_t creds) {
+ char *cred_style = context_find ("credentials");
+
+ init_credentials_file ();
+ creds->host = host;
+
+ if (cred_style == NULL || ! strcmp (cred_style, "legacy")) {
+ /* This is what inc.c and msgchk.c used to contain. */
+ if (user == NULL) {
+ creds->user = getusername ();
+ }
+ if (sasl) {
+ creds->password = getusername ();
+ } else {
+ ruserpass (host, &creds->user, &creds->password);
+ }
+ } else if (! strncasecmp (cred_style, "file:", 5)) {
+ /*
+ * Determine user using the first of:
+ * 1) -user switch
+ * 2) matching host entry with login in a credentials file
+ * such as ~/.netrc
+ * 3) interactively request from user (as long as the
+ * credentials file didn't have a "default" token)
+ */
+ creds->user = user;
+ ruserpass (host, &creds->user, &creds->password);
+ }
+
+ return OK;
+}
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Portions of this code are Copyright (c) 2013, by the authors of
+ * nmh. See the COPYRIGHT file in the root directory of the nmh
+ * distribution for complete copyright information.
*/
#include <h/mh.h>
static FILE *cfile;
-#ifndef MAXHOSTNAMELEN
-# define MAXHOSTNAMELEN 64
-#endif
-
#define DEFAULT 1
#define LOGIN 2
#define PASSWD 3
void
ruserpass(char *host, char **aname, char **apass)
{
- char *hdir, buf[BUFSIZ];
int t, usedefault = 0;
struct stat stb;
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
- snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
- cfile = fopen(buf, "r");
+ init_credentials_file ();
+
+ cfile = fopen (credentials_file, "r");
if (cfile == NULL) {
if (errno != ENOENT)
- perror(buf);
- goto done;
- }
-
- while ((t = token())) {
- switch(t) {
- case DEFAULT:
- usedefault = 1;
- /* FALL THROUGH */
-
- case MACH:
- if (!usedefault) {
- if (token() != ID)
+ perror (credentials_file);
+ } else {
+ while ((t = token())) {
+ switch(t) {
+ case DEFAULT:
+ usedefault = 1;
+ /* FALL THROUGH */
+
+ case MACH:
+ if (!usedefault) {
+ if (token() != ID)
+ continue;
+ /*
+ * Allow match either for user's host name.
+ */
+ if (strcasecmp(host, tokval) == 0)
+ goto match;
continue;
- /*
- * Allow match either for user's host name.
- */
- if (strcasecmp(host, tokval) == 0)
- goto match;
- continue;
- }
-match:
- while ((t = token()) && t != MACH && t != DEFAULT) {
- switch(t) {
- case LOGIN:
- if (token() && *aname == 0) {
- *aname = mh_xmalloc((size_t) strlen(tokval) + 1);
- strcpy(*aname, tokval);
- }
- break;
- case PASSWD:
- if (fstat(fileno(cfile), &stb) >= 0 &&
- (stb.st_mode & 077) != 0) {
- /* We make this a fatal error to force the user to correct it */
- advise(NULL, "Error - ~/.netrc file must not be world or group readable.");
- adios(NULL, "Remove password or correct file permissions.");
- }
- if (token() && *apass == 0) {
- *apass = mh_xmalloc((size_t) strlen(tokval) + 1);
- strcpy(*apass, tokval);
+ }
+ match:
+ while ((t = token()) && t != MACH && t != DEFAULT) {
+ switch(t) {
+ case LOGIN:
+ if (token() && *aname == 0) {
+ *aname = mh_xmalloc((size_t) strlen(tokval) + 1);
+ strcpy(*aname, tokval);
+ }
+ break;
+
+ case PASSWD:
+ if (fstat(fileno(cfile), &stb) >= 0 &&
+ (stb.st_mode & 077) != 0) {
+ /* We make this a fatal error to force the
+ user to correct it. */
+ advise(NULL, "Error - file %s must not be world or "
+ "group readable.", credentials_file);
+ adios(NULL, "Remove password or correct file "
+ "permissions.");
+ }
+ if (token() && *apass == 0) {
+ *apass = mh_xmalloc((size_t) strlen(tokval) + 1);
+ strcpy(*apass, tokval);
+ }
+ break;
+
+ case ACCOUNT:
+ break;
+
+ case MACDEF:
+ fclose(cfile);
+ return;
+
+ default:
+ fprintf(stderr,
+ "Unknown keyword %s in credentials file %s\n",
+ tokval, credentials_file);
+ break;
}
- break;
- case ACCOUNT:
- break;
-
- case MACDEF:
- goto done_close;
- break;
- default:
- fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
- break;
}
+ return;
}
- goto done;
}
}
-done_close:
- fclose(cfile);
-
-done:
if (!*aname) {
char tmp[80];
char *myname;
11+ 12/17 No Such User Hello<<Hey man, how's it going? . Hope you're do"
+check $testmessage `mhpath +inbox 11` 'keep first'
+rm -f "$MH_TEST_DIR/inc.mbox" "$MH_TEST_DIR/.inc.map" "$netrc"
+
+# check credentials: file
+# Redirect stdin so that inc doesn't wait on the user if it can't
+# read the netrc file, even though that shouldn't happen.
+TESTUSER=differenuser
+TESTPASS=differentpass
+
+netrc="${HOME}/.mhnetrc"
+echo "default login ${TESTUSER} password ${TESTPASS}" > "$netrc"
+chmod 600 "$netrc"
+echo "credentials: file:${netrc}" >>$MH
+
+pid=`"${MH_OBJ_DIR}/test/fakepop" "$testmessage" "$testport" \
+ "$TESTUSER" "$TESTPASS"`
+
+touch "$MH_TEST_DIR/inc.mbox"
+run_test "inc -user ${TESTUSER} -host 127.0.0.1 -port $testport -width 65 \
+ -pack $MH_TEST_DIR/inc.mbox" \
+ "Incorporating new mail into (null)...
+
+ 1 12/17 No Such User Hello<<Hey man, how's it going? ." </dev/null
+run_test "inc -file $MH_TEST_DIR/inc.mbox -truncate -width 65" \
+ "Incorporating new mail into inbox...
+
+ 11+ 12/17 No Such User Hello<<Hey man, how's it going? ." </dev/null
+
check $testmessage `mhpath +inbox 11`
rm -f "$MH_TEST_DIR/inc.mbox" "$MH_TEST_DIR/.inc.map" "$netrc"
char *maildir_copy = NULL; /* copy of mail directory because the static gets overwritten */
int nmsgs, nbytes;
- char *pass = NULL;
char *MAILHOST_env_variable;
done=inc_done;
* a POP server?
*/
if (inc_type == INC_POP) {
- if (user == NULL)
- user = getusername ();
- if (sasl)
- pass = getusername ();
- else
- ruserpass (host, &user, &pass);
+ struct nmh_creds creds = { 0, 0, 0 };
/*
* initialize POP connection
*/
- if (pop_init (host, port, user, pass, proxy, snoop, sasl,
- saslmech) == NOTOK)
+ nmh_get_credentials (host, user, sasl, &creds);
+ if (pop_init (host, port, creds.user, creds.password, proxy, snoop,
+ sasl, saslmech) == NOTOK)
adios (NULL, "%s", response);
/* Check if there are any messages */
int datesw = 1, notifysw = NT_ALL;
int status = 0, sasl = 0;
int snoop = 0, vecp = 0;
- char *cp, *host = NULL, *port = NULL, *user, *proxy = NULL;
+ char *cp, *host = NULL, *port = NULL, *user = NULL, *proxy = NULL;
char buf[BUFSIZ], *saslmech = NULL;
char **argp, **arguments, *vec[MAXVEC];
struct passwd *pw;
context_read();
mts_init (invo_name);
- user = getusername();
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
if (vecp >= MAXVEC-1)
adios (NULL, "you can only check %d users at a time", MAXVEC-1);
else
- vec[vecp++] = cp;
+ user = vec[vecp++] = cp;
continue;
case SNOOPSW:
snoop, sasl, saslmech);
}
} else {
-
- if (vecp == 0) {
- char *home;
-
- /* Not sure this check makes sense... */
- if (!geteuid() || NULL == (home = getenv("HOME"))) {
- pw = getpwnam (user);
- if (pw == NULL)
- adios (NULL, "unable to get information about user");
- home = pw->pw_dir;
- }
- status = checkmail (user, home, datesw, notifysw, 1);
- } else {
- for (vecp = 0; vec[vecp]; vecp++) {
- if ((pw = getpwnam (vec[vecp])))
- status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
- else
- advise (NULL, "no such user as %s", vec[vecp]);
+ if (user == NULL) user = getusername ();
+ if (vecp == 0) {
+ char *home;
+
+ /* Not sure this check makes sense... */
+ if (!geteuid() || NULL == (home = getenv("HOME"))) {
+ pw = getpwnam (user);
+ if (pw == NULL)
+ adios (NULL, "unable to get information about user");
+ home = pw->pw_dir;
+ }
+ status = checkmail (user, home, datesw, notifysw, 1);
+ } else {
+ for (vecp = 0; vec[vecp]; vecp++) {
+ if ((pw = getpwnam (vec[vecp])))
+ status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
+ else
+ advise (NULL, "no such user as %s", vec[vecp]);
+ }
}
- }
} /* host == NULL */
done (status);
int personal, int snoop, int sasl, char *saslmech)
{
int nmsgs, nbytes, status;
- char *pass = NULL;
-
- if (user == NULL)
- user = getusername ();
- if (sasl)
- pass = getusername ();
- else
- ruserpass (host, &user, &pass);
+ struct nmh_creds creds = { 0, 0, 0 };
/* open the POP connection */
- if (pop_init (host, port, user, pass, proxy, snoop, sasl, saslmech) == NOTOK
- || pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
- || pop_quit () == NOTOK) { /* quit POP connection */
+ nmh_get_credentials (host, user, sasl, &creds);
+ if (pop_init (host, port, creds.user, creds.password, proxy, snoop, sasl,
+ saslmech) == NOTOK
+ || pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
+ || pop_quit () == NOTOK) { /* quit POP connection */
advise (NULL, "%s", response);
return 1;
}
static int sasl_get_pass(sasl_conn_t *, void *, int, sasl_secret_t **);
struct pass_context {
char *user;
+ char *password;
char *host;
};
static int multiline(void);
#ifdef CYRUS_SASL
-static int pop_auth_sasl(char *, char *, char *);
+static int pop_auth_sasl(char *, char *, char *, char *);
static int sasl_fgetc(FILE *);
#endif /* CYRUS_SASL */
*/
int
-pop_auth_sasl(char *user, char *host, char *mech)
+pop_auth_sasl(char *user, char *password, char *host, char *mech)
{
int result, status, sasl_capability = 0;
unsigned int buflen, outlen;
callbacks[POP_SASL_CB_N_USER].context = user;
p_context.user = user;
p_context.host = host;
+ p_context.password = password;
callbacks[POP_SASL_CB_N_PASS].context = &p_context;
result = sasl_client_init(callbacks);
sasl_get_pass(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
{
struct pass_context *p_context = (struct pass_context *) context;
- char *pass = NULL;
+ char *pass = p_context->password;
int len;
NMH_UNUSED (conn);
if (! psecret || id != SASL_CB_PASS)
return SASL_BADPARAM;
- ruserpass(p_context->user, &(p_context->host), &pass);
-
len = strlen(pass);
*psecret = (sasl_secret_t *) mh_xmalloc(sizeof(sasl_secret_t) + len);
if (*response == '+') {
# ifdef CYRUS_SASL
if (sasl) {
- if (pop_auth_sasl(user, host, mech) != NOTOK)
+ if (pop_auth_sasl(user, pass, host, mech) != NOTOK)
return OK;
} else
# endif /* CYRUS_SASL */