I think this is wrong. WHat do you expect this line to do?
> + user = name;
I think modifying user might be better left outside.
Also:
- You don't need endpwent() for getpwnam() so you can remove that.
- One of those silly _XFOOBAR defines hides the strsep definition. I
guess they can just be removed.
- gcc shows some other warnings as well.
On Tue, Jul 05, 2011 at 12:17:58AM +0200, Nils Anspach wrote:
> Hello,
>
> Nicholas Marriott schrieb am 02.07.2011 um 23:11:49 +0100:
> > Hi
> >
> > I don't think you need to strsep out the style yourself, a NULL style to
> > auth_userokay will look for it after a : itself.
> >
> > Otherwise this reads fine to me.
> >
> >
> > On Mon, Jun 27, 2011 at 07:30:53PM +0200, Nils Anspach wrote:
> > > Hello list,
> > >
> > > attached is a patch for popa3d(8) to use BSD authentication.
> > >
> > > Currently, to authenticate users, popa3d(8) encrypts the user-provided
> > > password via crypt(3) and then compares the hash with the passwd field
> > > from master.passwd(5). This method however does not work if users are
> > > authenticated by other means when logging into the machine (e.g. via
> > > login_ldap(8)). The attached patch allows for such authentication
> > > styles.
> > >
> > > Nils
> > > Index: auth_passwd.c
> > > ===================================================================
> > > RCS file: /cvs/src/usr.sbin/popa3d/auth_passwd.c,v
> > > retrieving revision 1.2
> > > diff -u -r1.2 auth_passwd.c
> > > --- auth_passwd.c 21 Sep 2001 20:22:06 -0000 1.2
> > > +++ auth_passwd.c 27 Jun 2011 16:48:21 -0000
> > > @@ -6,7 +6,7 @@
> > >
> > > #include "params.h"
> > >
> > > -#if AUTH_PASSWD && !VIRTUAL_ONLY
> > > +#if BSD_AUTH && !VIRTUAL_ONLY
> > >
> > > #define _XOPEN_SOURCE 4
> > > #define _XOPEN_SOURCE_EXTENDED
> > > @@ -16,8 +16,10 @@
> > > #include <string.h>
> > > #include <pwd.h>
> > > #include <sys/types.h>
> > > +#include <login_cap.h>
> > > +#include <bsd_auth.h>
> > >
> > > -struct passwd *auth_userpass(char *user, char *pass, int *known)
> > > +struct passwd *auth_userpass(char *user, char *style, char *pass, int
> > > *known)
> > > {
> > > struct passwd *pw, *result;
> > >
> > > @@ -25,11 +27,7 @@
> > > endpwent();
> > > result = NULL;
> > >
> > > - if (!pw || !*pw->pw_passwd ||
> > > - *pw->pw_passwd == '*' || *pw->pw_passwd == '!')
> > > - crypt(pass, AUTH_DUMMY_SALT);
> > > - else
> > > - if (!strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd))
> > > + if (pw && auth_userokay(user, style, BSD_AUTH_TYPE, pass))
> > > result = pw;
> > >
> > > if (pw)
> > > Index: params.h
> > > ===================================================================
> > > RCS file: /cvs/src/usr.sbin/popa3d/params.h,v
> > > retrieving revision 1.9
> > > diff -u -r1.9 params.h
> > > --- params.h 16 Dec 2009 20:42:26 -0000 1.9
> > > +++ params.h 27 Jun 2011 16:48:22 -0000
> > > @@ -142,15 +142,23 @@
> > > /*
> > > * Choose the password authentication method your system uses:
> > > *
> > > - * AUTH_PASSWD Use getpwnam(3) only, for *BSD or readable
> > > passwd;
> > > - *
> > > - * Note that there's no built-in password aging support.
> > > + * BSD_AUTH Use BSD Authentication.
> > > + *
> > > */
> > > -#define AUTH_PASSWD 1
> > > +#define BSD_AUTH 1
> > > +
> > > +#if BSD_AUTH
> > > +
> > > +/*
> > > + * BSD Authentication type
> > > + */
> > > +#define BSD_AUTH_TYPE "auth-popa3d"
> > > +
> > > +#endif
> > >
> > > #endif
> > >
> > > -#if POP_VIRTUAL || AUTH_PASSWD
> > > +#if POP_VIRTUAL
> > >
> > > /*
> > > * A salt used to waste some CPU time on dummy crypt(3) calls and make
> > > Index: pop_root.c
> > > ===================================================================
> > > RCS file: /cvs/src/usr.sbin/popa3d/pop_root.c,v
> > > retrieving revision 1.5
> > > diff -u -r1.5 pop_root.c
> > > --- pop_root.c 3 May 2005 05:44:35 -0000 1.5
> > > +++ pop_root.c 27 Jun 2011 16:48:22 -0000
> > > @@ -9,7 +9,7 @@
> > > * startup.c if supporting command line options (POP_OPTIONS)
> > > * standalone.c if not running via an inetd clone
> > > (POP_STANDALONE)
> > > * virtual.c if supporting virtual domains (POP_VIRTUAL)
> > > - * auth_passwd.c if using passwd or *BSD (AUTH_PASSWD && !VIRTUAL_ONLY)
> > > + * auth_passwd.c if using BSD Auth. (BSD_AUTH && !VIRTUAL_ONLY)
> > > */
> > >
> > > #include <unistd.h>
> > > @@ -34,7 +34,7 @@
> > > #endif
> > >
> > > #if !VIRTUAL_ONLY
> > > -extern struct passwd *auth_userpass(char *user, char *pass, int *known);
> > > +extern struct passwd *auth_userpass(char *user, char *style, char *pass,
> > > int *known);
> > > #endif
> > >
> > > /* POP_USER's pw_uid and pw_gid, other fields may not be valid */
> > > @@ -110,6 +110,9 @@
> > > {
> > > static char auth[AUTH_BUFFER_SIZE + 2];
> > > char *pass;
> > > +#if BSD_AUTH
> > > + char *style;
> > > +#endif
> > > struct passwd *pw;
> > >
> > > known = 0;
> > > @@ -130,8 +133,15 @@
> > > return AUTH_NONE;
> > > }
> > >
> > > +#if BSD_AUTH
> > > + style = auth;
> > > + pass = &style[strlen(style) + 1];
> > > + user = strsep(&style, ":");
> > > +#else
> > > user = auth;
> > > pass = &user[strlen(user) + 1];
> > > +#endif
> > > + if (!*pass) return AUTH_FAILED;
> > >
> > > pw = NULL;
> > > #if POP_VIRTUAL
> > > @@ -145,13 +155,17 @@
> > > memset(pass, 0, strlen(pass));
> > > return AUTH_FAILED;
> > > }
> > > +#elif BSD_AUTH
> > > + if (!pw && !(pw = auth_userpass(user, style, pass, &known))) {
> > > + memset(pass, 0, strlen(pass));
> > > + return AUTH_FAILED;
> > > + }
> > > #else
> > > - if (!pw && !(pw = auth_userpass(user, pass, &known))) {
> > > + if (!pw) {
> > > memset(pass, 0, strlen(pass));
> > > return AUTH_FAILED;
> > > }
> > > #endif
> > > - if (!*pass) return AUTH_FAILED;
> > > memset(pass, 0, strlen(pass));
> > > if (!*user) return AUTH_FAILED;
> > >
> > > Index: popa3d.8
> > > ===================================================================
> > > RCS file: /cvs/src/usr.sbin/popa3d/popa3d.8,v
> > > retrieving revision 1.14
> > > diff -u -r1.14 popa3d.8
> > > --- popa3d.8 31 May 2007 19:20:27 -0000 1.14
> > > +++ popa3d.8 27 Jun 2011 16:48:22 -0000
> > > @@ -102,6 +102,12 @@
> > > .Pp
> > > .Dl pop3 stream tcp nowait root /usr/libexec/tcpd /usr/sbin/popa3d
> > > .Pp
> > > +.Nm
> > > +uses BSD Authentication with authentication type
> > > +.Dq auth-popa3d
> > > +for the given username and password ; see
> > > +.Xr login.conf 5 .
> > > +.Pp
> > > For access to a mailbox through the POP3 service, the username must
> > > be in the password database.
> > > Additionally,
> > > @@ -165,6 +171,7 @@
> > > .Sh SEE ALSO
> > > .Xr hosts_access 5 ,
> > > .Xr inetd 8 ,
> > > +.Xr login.conf 5 ,
> > > .Xr sendmail 8 ,
> > > .Xr tcpd 8
> > > .Pp
>
> popa3d(8) wants to log known, but non-authenticated users too, so it
> needs the username (without the :style part), and in case of successful
> authentication it needs some data from the passwd structure, too. So,
> simply auth_userokay'ing is not enough.
>
> In the following diff, the strsep part is put into auth_userpass. Might
> be more appropriate.
>
> Comments? Suggestions?
>
> Nils
> Index: auth_passwd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/popa3d/auth_passwd.c,v
> retrieving revision 1.2
> diff -u -r1.2 auth_passwd.c
> --- auth_passwd.c 21 Sep 2001 20:22:06 -0000 1.2
> +++ auth_passwd.c 4 Jul 2011 21:30:48 -0000
> @@ -1,12 +1,12 @@
> /* $OpenBSD: auth_passwd.c,v 1.2 2001/09/21 20:22:06 camield Exp $ */
>
> /*
> - * The /etc/passwd authentication routine.
> + * The BSD authentication routine.
> */
>
> #include "params.h"
>
> -#if AUTH_PASSWD && !VIRTUAL_ONLY
> +#if BSD_AUTH && !VIRTUAL_ONLY
>
> #define _XOPEN_SOURCE 4
> #define _XOPEN_SOURCE_EXTENDED
> @@ -16,24 +16,29 @@
> #include <string.h>
> #include <pwd.h>
> #include <sys/types.h>
> +#include <login_cap.h>
> +#include <bsd_auth.h>
>
> struct passwd *auth_userpass(char *user, char *pass, int *known)
> {
> + char *name;
> struct passwd *pw, *result;
>
> - *known = (pw = getpwnam(user)) != NULL;
> - endpwent();
> + pw = NULL;
> result = NULL;
>
> - if (!pw || !*pw->pw_passwd ||
> - *pw->pw_passwd == '*' || *pw->pw_passwd == '!')
> - crypt(pass, AUTH_DUMMY_SALT);
> - else
> - if (!strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd))
> + if (name = strsep(&user, ":")) {
> + *known = (pw = getpwnam(name)) != NULL;
> + endpwent();
> + }
> +
> + if (pw && auth_userokay(name, user, BSD_AUTH_TYPE, pass))
> result = pw;
>
> if (pw)
> memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
> +
> + user = name;
>
> return result;
> }
> Index: params.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/popa3d/params.h,v
> retrieving revision 1.9
> diff -u -r1.9 params.h
> --- params.h 16 Dec 2009 20:42:26 -0000 1.9
> +++ params.h 4 Jul 2011 21:30:48 -0000
> @@ -142,15 +142,23 @@
> /*
> * Choose the password authentication method your system uses:
> *
> - * AUTH_PASSWD Use getpwnam(3) only, for *BSD or readable
> passwd;
> - *
> - * Note that there's no built-in password aging support.
> + * BSD_AUTH Use BSD Authentication.
> + *
> */
> -#define AUTH_PASSWD 1
> +#define BSD_AUTH 1
> +
> +#if BSD_AUTH
> +
> +/*
> + * BSD Authentication type
> + */
> +#define BSD_AUTH_TYPE "auth-popa3d"
> +
> +#endif
>
> #endif
>
> -#if POP_VIRTUAL || AUTH_PASSWD
> +#if POP_VIRTUAL
>
> /*
> * A salt used to waste some CPU time on dummy crypt(3) calls and make
> Index: pop_root.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/popa3d/pop_root.c,v
> retrieving revision 1.5
> diff -u -r1.5 pop_root.c
> --- pop_root.c 3 May 2005 05:44:35 -0000 1.5
> +++ pop_root.c 4 Jul 2011 21:30:48 -0000
> @@ -9,7 +9,7 @@
> * startup.c if supporting command line options (POP_OPTIONS)
> * standalone.c if not running via an inetd clone
> (POP_STANDALONE)
> * virtual.c if supporting virtual domains (POP_VIRTUAL)
> - * auth_passwd.c if using passwd or *BSD (AUTH_PASSWD && !VIRTUAL_ONLY)
> + * auth_passwd.c if using BSD Auth. (BSD_AUTH && !VIRTUAL_ONLY)
> */
>
> #include <unistd.h>
> @@ -133,6 +133,8 @@
> user = auth;
> pass = &user[strlen(user) + 1];
>
> + if (!*pass) return AUTH_FAILED;
> +
> pw = NULL;
> #if POP_VIRTUAL
> if (!(pw = virtual_userpass(user, pass, &known)) && virtual_domain) {
> @@ -145,13 +147,17 @@
> memset(pass, 0, strlen(pass));
> return AUTH_FAILED;
> }
> -#else
> +#elif BSD_AUTH
> if (!pw && !(pw = auth_userpass(user, pass, &known))) {
> memset(pass, 0, strlen(pass));
> return AUTH_FAILED;
> }
> +#else
> + if (!pw) {
> + memset(pass, 0, strlen(pass));
> + return AUTH_FAILED;
> + }
> #endif
> - if (!*pass) return AUTH_FAILED;
> memset(pass, 0, strlen(pass));
> if (!*user) return AUTH_FAILED;
>
> Index: popa3d.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/popa3d/popa3d.8,v
> retrieving revision 1.14
> diff -u -r1.14 popa3d.8
> --- popa3d.8 31 May 2007 19:20:27 -0000 1.14
> +++ popa3d.8 4 Jul 2011 21:30:48 -0000
> @@ -102,6 +102,12 @@
> .Pp
> .Dl pop3 stream tcp nowait root /usr/libexec/tcpd /usr/sbin/popa3d
> .Pp
> +.Nm
> +uses BSD Authentication with authentication type
> +.Dq auth-popa3d
> +for the given username and password ; see
> +.Xr login.conf 5 .
> +.Pp
> For access to a mailbox through the POP3 service, the username must
> be in the password database.
> Additionally,
> @@ -165,6 +171,7 @@
> .Sh SEE ALSO
> .Xr hosts_access 5 ,
> .Xr inetd 8 ,
> +.Xr login.conf 5 ,
> .Xr sendmail 8 ,
> .Xr tcpd 8
> .Pp