From cbec586dc12d3cc597535e3aa49819c9ab39d40c Mon Sep 17 00:00:00 2001
From: Dante Catalfamo
Date: Mon, 29 Jun 2020 17:21:16 -0400
Subject: Indent heading contents, more content

---
 .../posts/how-bsd-authentication-works/index.org   | 545 +++++++++++----------
 1 file changed, 275 insertions(+), 270 deletions(-)

(limited to 'content/posts')

diff --git a/content/posts/how-bsd-authentication-works/index.org b/content/posts/how-bsd-authentication-works/index.org
index 6eae6a5..76fe4a4 100644
--- a/content/posts/how-bsd-authentication-works/index.org
+++ b/content/posts/how-bsd-authentication-works/index.org
@@ -10,303 +10,308 @@
 
 [[https://web.archive.org/web/20170327150148/http://www.penzin.net/bsdauth/]]
 * History
-OpenBSD is quite different from many other Unix-like operating systems
-in many ways, but one way which I find interesting is the
-authentication system. Most systems from AIX, Solaris, and Linux to
-most BSDs including MacOS use some form of a system called Pluggable
-Authentication Module (PAM). The two main implementations of PAM are
-[[http://www.linux-pam.org/][Linux PAM]] and [[https://www.openpam.org/][OpenPAM]]. PAM modules are created a dynamically loaded
-shared objects, which communicate using a set of standard
-interfaces ([[https://linux.die.net/man/3/pam][Linux-PAM]]) ([[https://www.freebsd.org/cgi/man.cgi?query=pam&apropos=0&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports&arch=default&format=html][OpenPAM]]). PAM is configured using the [[https://linux.die.net/man/5/pam.d][pam.d]]
-directory and [[https://www.freebsd.org/cgi/man.cgi?query=pam.conf&sektion=5&apropos=0&manpath=FreeBSD+12.1-RELEASE+and+Ports][pam.conf]].
-
-OpenBSD on the other hand uses a mechanism called BSD
-Authentication. It was originally developed for a proprietary
-operating system called [[https://en.wikipedia.org/wiki/BSD/OS][BSD/OS]] by [[https://en.wikipedia.org/wiki/Berkeley_Software_Design][Berkeley Software Design Inc.]], who
-later donated the system. It was adopted by OpenBSD in release
-2.9. BSD Auth is comparatively much simpler than PAM. Modules or,
-authentication "styles", are instead stand alone applications or
-scripts that communicate over IPC (=PF_LOCAL, SOCK_STREAM=,
-specifically). The program or script has no ability to interfere with
-the parent and can very easily revoke permissions using =pledge(3)= or
-=unveil(3)=.
+
+  OpenBSD is quite different from many other Unix-like operating systems
+  in many ways, but one way which I find interesting is the
+  authentication system. Most systems from AIX, Solaris, and Linux to
+  most BSDs including MacOS use some form of a system called Pluggable
+  Authentication Module (PAM). The two main implementations of PAM are
+  [[http://www.linux-pam.org/][Linux PAM]] and [[https://www.openpam.org/][OpenPAM]]. PAM modules are created a dynamically loaded
+  shared objects, which communicate using a set of standard
+  interfaces ([[https://linux.die.net/man/3/pam][Linux-PAM]]) ([[https://www.freebsd.org/cgi/man.cgi?query=pam&apropos=0&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports&arch=default&format=html][OpenPAM]]). PAM is configured using the [[https://linux.die.net/man/5/pam.d][pam.d]]
+  directory and [[https://www.freebsd.org/cgi/man.cgi?query=pam.conf&sektion=5&apropos=0&manpath=FreeBSD+12.1-RELEASE+and+Ports][pam.conf]].
+
+  OpenBSD on the other hand uses a mechanism called BSD
+  Authentication. It was originally developed for a proprietary
+  operating system called [[https://en.wikipedia.org/wiki/BSD/OS][BSD/OS]] by [[https://en.wikipedia.org/wiki/Berkeley_Software_Design][Berkeley Software Design Inc.]], who
+  later donated the system. It was adopted by OpenBSD in release
+  2.9. BSD Auth is comparatively much simpler than PAM. Modules or,
+  authentication "styles", are instead stand alone applications or
+  scripts that communicate over IPC (=PF_LOCAL, SOCK_STREAM=,
+  specifically). The program or script has no ability to interfere with
+  the parent and can very easily revoke permissions using =pledge(3)= or
+  =unveil(3)=.
 
 * Why
-This one is pretty difficult, since there seems to be very little
-information about how BSD Auth works apart from the source code
-itself. This is my best attempt to understand the flow of BSD Auth
-from what I've read.
 
+  This one is pretty difficult, since there seems to be very little
+  information about how BSD Auth works apart from the source code
+  itself. This is my best attempt to understand the flow of BSD Auth
+  from what I've read.
 
 * BSD Auth Modules
-These programs or scripts are located in =/usr/libexec/auth/= with the
-naming convention =login_<style>=. They take arguments in the form of
-
-#+BEGIN_SRC shell
-login_<style> [-s service] [-v key=value] user [class]
-#+END_SRC
 
-- =<style>= is the authentication method. This could be =passwd=,
-  =radius=, =skey=, =yubikey=, etc.
-  - There's more information about available styles in =login.conf(5)=
-- =service= is the service type. Typically authentication methods will
-  accept three values here, =login=, =challenge=, or =response=. Some
-  styles take different service arguments, read the style's man page
-  for details.
-  - =login= is typically the default method
-- =-v key=value= is an optional argument. This is used to pass extra
-  data to the program under certain circumstances.
-- =user= is the name of the user to be authenticated.
-- =class= is optional and specifies the class of the user to be
-  authenticated.
+  These programs or scripts are located in =/usr/libexec/auth/= with the
+  naming convention =login_<style>=. They take arguments in the form of
+
+  #+BEGIN_SRC shell
+  login_<style> [-s service] [-v key=value] user [class]
+  #+END_SRC
+
+  - =<style>= is the authentication method. This could be =passwd=,
+    =radius=, =skey=, =yubikey=, etc. There's more information about
+    available styles in =login.conf(5)= under the =AUTHENTICATION=
+    header.
+  - =service= is the service type. Typically authentication methods will
+    accept one of three values here, =login=, =challenge=, or
+    =response=. =login= is the default if it's not specified, and is
+    usually the right choice. Read the style's man page for details.
+  - =-v key=value= is an optional argument. This is used to pass extra
+    data to the program under certain circumstances.
+  - =user= is the name of the user to be authenticated.
+  - =class= is optional and specifies the class of the user to be
+    authenticated.
 
 * Documentation
-All of the high level authentication functions are described in
-=authenticate(3)=, with the lower level functions being described in
-=auth_subr(3)=.
 
-* auth_userokay
-The highest level function, and easiest to use is =auth_userokay=. It
-takes four character arrays as arguments, =name=, =style=, =type=, and
-=password=. It returns either a =0= for failure, of a non-zero value
-for success.
+  All of the high level authentication functions are described in
+  =authenticate(3)=, with the lower level functions being described in
+  =auth_subr(3)=.
 
-This function lives inside =/lib/libc/gen/authenticate.c=
-
-#+BEGIN_SRC c
-int auth_userokay(char *name, char *style, char *type, char *password);
-#+END_SRC
+* auth_userokay
 
-- =name= is the name of the user to be authenticated
-- =style= is the login method to be used
-  - If =style= is =NULL=, the user's default login style will be
-    used. By default this is =passwd= on normal accounts.
-  - The style can be one of the installed authentication methods, like
-    =passwd=, =radius=, =skey=, =yubikey=, etc.
-  - There's more information about available styles in =login.conf(5)=
-  - Styles can also be installed through BSD Auth module packages
-- =type= is the authentication type
-  - Types are defined in =login.conf= and define a group of allowed
-    auth styles
-  - If =type= is =NULL=, use the auth type for the user's login
-    class. The default type is =auth-default=, which allows
-    =psaswd= and =skey= auth methods.
-  - There's more information about how to add methods in =login.conf(5)=
-- =password= is the password to test
-  - If =password= is =NULL=, then the user is interactively
-    prompted. This is required for auth styles using
-    challenge-response methods.
-  - If =password= is specified, then it's non-interactively tested
-
-=auth_userokay= is just a wrapper around =auth_usercheck=, which
-returns a finished auth session of type =auth_session_t=. It closes
-the auth session using =auth_close= and returns the value returned
-from closing.
+  The highest level function, and easiest to use is =auth_userokay=. It
+  takes four character arrays as arguments, =name=, =style=, =type=, and
+  =password=. It returns either a =0= for failure, of a non-zero value
+  for success.
+
+  This function lives inside =/lib/libc/gen/authenticate.c=
+
+  #+BEGIN_SRC c
+  int auth_userokay(char *name, char *style, char *type, char *password);
+  #+END_SRC
+
+  - =name= is the name of the user to be authenticated
+  - =style= is the login method to be used
+    - If =style= is =NULL=, the user's default login style will be
+      used. By default this is =passwd= on normal accounts.
+    - The style can be one of the installed authentication methods, like
+      =passwd=, =radius=, =skey=, =yubikey=, etc.
+    - There's more information about available styles in =login.conf(5)=
+    - Styles can also be installed through BSD Auth module packages
+  - =type= is the authentication type
+    - Types are defined in =login.conf= and define a group of allowed
+      auth styles
+    - If =type= is =NULL=, use the auth type for the user's login
+      class. The default type is =auth-default=, which allows
+      =psaswd= and =skey= auth methods.
+    - There's more information about how to add methods in =login.conf(5)=
+  - =password= is the password to test
+    - If =password= is =NULL=, then the user is interactively
+      prompted. This is required for auth styles using
+      challenge-response methods.
+    - If =password= is specified, then it's non-interactively tested
+
+  =auth_userokay= is just a wrapper around =auth_usercheck=, which
+  returns a finished auth session of type =auth_session_t=. It closes
+  the auth session using =auth_close= and returns the value returned
+  from closing.
 
 * auth_session_t
 
-#+BEGIN_SRC c
-struct auth_session_t {
-    char    *name;                 /* name of use being authenticated */
-    char    *style;                /* style of authentication used */
-    char    *class;                /* class of user */
-    char    *service;              /* type of service being performed */
-    char    *challenge;            /* last challenge issued */
-    int     flags;                 /* see below */
-    struct  passwd *pwd;           /* password entry for user */
-    struct  timeval now;           /* time of authentication */
-
-    int     state;                 /* authenticated state */
-
-    struct  rmfiles *rmlist;       /* list of files to remove on failure */
-    struct  authopts *optlist;     /* list of options to scripts */
-    struct  authdata *data;        /* additional data to send to scripts */
-
-    char    spool[MAXSPOOLSIZE];   /* data returned from login script */
-    int     index;                 /* how much returned thus far */
-
-    int     fd;                    /* connection to authenticator */
-
-    va_list ap0;                   /* argument list to auth_call */
-    va_list ap;                    /* additional arguments to auth_call */
-};
-#+END_SRC
-
-Where =authdata=, =authopts=, and =rmfiles= are defined as
-
-#+BEGIN_SRC c
-struct rmfiles {
-    struct rmfiles  *next;
-    char            *file;
-};
-
-struct authopts {
-    struct authopts *next;
-    char            *opt;
-};
-
-struct authdata {
-    struct  authdata *next;
-    void    *ptr;
-    size_t   len;
-};
-#+END_SRC
+  #+BEGIN_SRC c
+  struct auth_session_t {
+      char    *name;                 /* name of use being authenticated */
+      char    *style;                /* style of authentication used */
+      char    *class;                /* class of user */
+      char    *service;              /* type of service being performed */
+      char    *challenge;            /* last challenge issued */
+      int     flags;                 /* see below */
+      struct  passwd *pwd;           /* password entry for user */
+      struct  timeval now;           /* time of authentication */
+
+      int     state;                 /* authenticated state */
+
+      struct  rmfiles *rmlist;       /* list of files to remove on failure */
+      struct  authopts *optlist;     /* list of options to scripts */
+      struct  authdata *data;        /* additional data to send to scripts */
+
+      char    spool[MAXSPOOLSIZE];   /* data returned from login script */
+      int     index;                 /* how much returned thus far */
+
+      int     fd;                    /* connection to authenticator */
+
+      va_list ap0;                   /* argument list to auth_call */
+      va_list ap;                    /* additional arguments to auth_call */
+  };
+  #+END_SRC
+
+  Where =authdata=, =authopts=, and =rmfiles= are defined as
+
+  #+BEGIN_SRC c
+  struct rmfiles {
+      struct rmfiles  *next;
+      char            *file;
+  };
+
+  struct authopts {
+      struct authopts *next;
+      char            *opt;
+  };
+
+  struct authdata {
+      struct  authdata *next;
+      void    *ptr;
+      size_t   len;
+  };
+  #+END_SRC
 
 * auth_usercheck
-#+BEGIN_SRC c
-auth_session_t *auth_usercheck(char *name, char *style, char *type, char *password)
-#+END_SRC
-
-=auth_usercheck= checks the user name against the passwd db. It also
-checks the login class against the =login.conf= db, along with
-confirming the login styles available.
-
-If the password is non-=NULL=, then it calls =auth_open=, which
-allocates and returns the pointer to an =auth_session_t=, and sets its
-default =service= to =login=, and it's =fd= to =-1=. After that's
-returned, =auth_usercheck= calls (with =as= as the session struct)
 
-#+BEGIN_SRC c
-auth_setitem(as, AUTHV_SERVICE, "response");
-auth_setdata(as, "", 1);
-auth_setdata(as, password, strlen(password) + 1);
-#+END_SRC
-
-setting the service protocol to =response=, adding an empty line to
-the session data, then adding the password as data. If the password is
-=NULL=, it sets the =auth_session_t= pointer to =NULL=. It then passes
-the user name, style, login class, and =NULL= char pointer to
-=auth_verify=. The last two variables are received as variable
-arguments. It then returns the auth session pointer the call
-returns.
+  #+BEGIN_SRC c
+  auth_session_t *auth_usercheck(char *name, char *style, char *type, char *password)
+  #+END_SRC
+
+  =auth_usercheck= checks the user name against the passwd db. It also
+  checks the login class against the =login.conf= db, along with
+  confirming the login styles available.
+
+  If the password is non-=NULL=, then it calls =auth_open=, which
+  allocates and returns the pointer to an =auth_session_t=, and sets its
+  default =service= to =login=, and it's =fd= to =-1=. After that's
+  returned, =auth_usercheck= calls (with =as= as the session struct)
+
+  #+BEGIN_SRC c
+  auth_setitem(as, AUTHV_SERVICE, "response");
+  auth_setdata(as, "", 1);
+  auth_setdata(as, password, strlen(password) + 1);
+  #+END_SRC
+
+  setting the service protocol to =response=, adding an empty line to
+  the session data, then adding the password as data. If the password is
+  =NULL=, it sets the =auth_session_t= pointer to =NULL=. It then passes
+  the user name, style, login class, and =NULL= char pointer to
+  =auth_verify=. The last two variables are received as variable
+  arguments. It then returns the auth session pointer the call
+  returns.
 
 * auth_verify
 
-#+BEGIN_SRC c
-auth_session_t *auth_verify(auth_session_t *as, char *style, char *name, ...)
-#+END_SRC
+  #+BEGIN_SRC c
+  auth_session_t *auth_verify(auth_session_t *as, char *style, char *name, ...)
+  #+END_SRC
 
-=auth_verify= creates an auth session if =as= is =NULL=. It then sets
-the user name and style of the session, if the respective arguments
-are non-=NULL=. It then copies its variable arguments to the auth
-session's =va_list ap=, which is used inside of =auth_call=.
+  =auth_verify= creates an auth session if =as= is =NULL=. It then sets
+  the user name and style of the session, if the respective arguments
+  are non-=NULL=. It then copies its variable arguments to the auth
+  session's =va_list ap=, which is used inside of =auth_call=.
 
-After that it constructs the path of the authentication module by
-combining =_PATH_AUTHPROG=, which is defined in =login_cap.h= as
-=/usr/libexec/auth/login_=, and the authentication style. For the
-case of auth style =passwd=, it would result in the path
-=/usr/libexec/auth/login_passwd=.
+  After that it constructs the path of the authentication module by
+  combining =_PATH_AUTHPROG=, which is defined in =login_cap.h= as
+  =/usr/libexec/auth/login_=, and the authentication style. For the
+  case of auth style =passwd=, it would result in the path
+  =/usr/libexec/auth/login_passwd=.
 
-Then =auth_call= is called with the struct, the path to the auth
-module, the auth style, the "-s" flag followed by the service (login,
-challenge, response), a double dash, the user name, and a =NULL=
-character pointer. The return value of =auth_call= is ignored and a
-pointer to the auth session is returned immediately afterwards.
+  Then =auth_call= is called with the struct, the path to the auth
+  module, the auth style, the "-s" flag followed by the service (login,
+  challenge, response), a double dash, the user name, and a =NULL=
+  character pointer. The return value of =auth_call= is ignored and a
+  pointer to the auth session is returned immediately afterwards.
 
-#+BEGIN_SRC c
-auth_call(as, path, auth_getitem(as, AUTHV_STYLE), "-s",
-    auth_getitem(as, AUTHV_SERVICE), "--", name, (char *)NULL);
-#+END_SRC
+  #+BEGIN_SRC c
+  auth_call(as, path, auth_getitem(as, AUTHV_STYLE), "-s",
+      auth_getitem(as, AUTHV_SERVICE), "--", name, (char *)NULL);
+  #+END_SRC
 
 * auth_call
 
-#+BEGIN_SRC c
-int auth_call(auth_session_t *as, char *path, ...)
-#+END_SRC
-
-<<here>>
-
----
-note: In the man page auth_subr it says
-#+begin_quote
-path    The full path name of the login script to run.  The call will
-             fail if path does not pass the requirements of the secure_path(3)
-             function.
-#+end_quote
-However I don't see this enforced anywhere, I even wrote a small test
-script to prove that's the case on =vfwall ~/authtest=.
-
-The manpage also says the path is limited to =/bin/= and =/usr/bin=,
-which is also not the case.
-
-Ask jcs about the file descriptor situation, I don't understand it
-after reading both the man page and source.
----
-
-Inside of =auth_call=, a socket pair of type =PF_LOCAL, SOCK_STREAM=
-is created. This is called the "back channel", and is used to
-communicate with the authentication module. The process then forks,
-calling ~execve(path, argv, auth_environ)~, where the =argv= is
-everything after =path= in the =auth_call= arguments. Any =authopts=
-set in the auth session are also passed as arguments in the format =-v
-opt1 -v opt2 -v opt3=, etc. =auth_environ= is defined at the top of
-the file as
-
-#+BEGIN_SRC c
-static char *auth_environ[] = {
-    "PATH=" _PATH_DEFPATH,
-    "SHELL=" _PATH_BSHELL,
-    NULL,
-};
-#+END_SRC
-
-Where both constants are defined in =paths.h= as
-
-#+BEGIN_SRC c
-#define	_PATH_DEFPATH	"/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin"
-#define	_PATH_BSHELL	"/bin/sh"
-#+END_SRC
-
-
-The =exec='d process then listens on FD 3, which is one half of the
-=sockpair= that was created earlier.
-
-In the non-exec'd process, first the contents of the auth session's
-=*data= are read in one at a time.
-
-The data received through the back channel is then put into the
-=spool= of the auth session using =_auth_spool(as, pfd[0])=. After
-that the spooled data is scanned for key words defined in
-=login_cap.h=.
-
-#+BEGIN_SRC c
-#define BI_AUTH         "authorize"         /* Accepted authentication */
-#define BI_REJECT       "reject"            /* Rejected authentication */
-#define BI_CHALLENGE    "reject challenge"  /* Reject with a challenge */
-#define BI_SILENT       "reject silent"     /* Reject silently */
-#define BI_REMOVE       "remove"            /* remove file on error */
-#define BI_ROOTOKAY     "authorize root"    /* root authenticated */
-#define BI_SECURE       "authorize secure"  /* okay on non-secure line */
-#define BI_SETENV       "setenv"            /* set environment variable */
-#define BI_UNSETENV     "unsetenv"          /* unset environment variable */
-#define BI_VALUE        "value"             /* set local variable */
-#define BI_EXPIRED      "reject expired"    /* account expired */
-#define BI_PWEXPIRED    "reject pwexpired"  /* password expired */
-#define BI_FDPASS       "fd"                /* child is passing an fd */
-#+END_SRC
-
-It is looking for lines that start with either =BI_AUTH=
-(=authorize=), or =BI_REJECT= (=reject=). If the line is still longer,
-it continues to scan for any other qualifiers such as =pwexpired= or
-=silent=. The struct's =state= is set to one using the =AUTH_= values
-from =login_cap.h= accordingly.
-
-#+BEGIN_SRC c
-/*
- * bits which can be returned by authenticate()/auth_scan()
- */
-#define  AUTH_OKAY       0x01            /* user authenticated */
-#define  AUTH_ROOTOKAY   0x02            /* authenticated as root */
-#define  AUTH_SECURE     0x04            /* secure login */
-#define  AUTH_SILENT     0x08            /* silent rejection */
-#define  AUTH_CHALLENGE  0x10            /* a challenge was given */
-#define  AUTH_EXPIRED    0x20            /* account expired */
-#define  AUTH_PWEXPIRED  0x40            /* password expired */
-#+END_SRC
-
-
-This is the integer returned by
-=auth_userokay=.
+  #+BEGIN_SRC c
+  int auth_call(auth_session_t *as, char *path, ...)
+  #+END_SRC
+
+  <<here>>
+
+  ---
+  note: In the man page auth_subr it says
+  #+begin_quote
+  path    The full path name of the login script to run.  The call will
+               fail if path does not pass the requirements of the secure_path(3)
+               function.
+  #+end_quote
+  However I don't see this enforced anywhere, I even wrote a small test
+  script to prove that's the case on =vfwall ~/authtest=.
+
+  The manpage also says the path is limited to =/bin/= and =/usr/bin=,
+  which is also not the case.
+
+  Ask jcs about the file descriptor situation, I don't understand it
+  after reading both the man page and source.
+  ---
+
+  Inside of =auth_call=, a socket pair of type =PF_LOCAL, SOCK_STREAM=
+  is created. This is called the "back channel", and is used to
+  communicate with the authentication module. The process then forks,
+  calling ~execve(path, argv, auth_environ)~, where the =argv= is
+  everything after =path= in the =auth_call= arguments. Any =authopts=
+  set in the auth session are also passed as arguments in the format =-v
+  opt1 -v opt2 -v opt3=, etc. =auth_environ= is defined at the top of
+  the file as
+
+  #+BEGIN_SRC c
+  static char *auth_environ[] = {
+      "PATH=" _PATH_DEFPATH,
+      "SHELL=" _PATH_BSHELL,
+      NULL,
+  };
+  #+END_SRC
+
+  Where both constants are defined in =paths.h= as
+
+  #+BEGIN_SRC c
+  #define	_PATH_DEFPATH	"/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin"
+  #define	_PATH_BSHELL	"/bin/sh"
+  #+END_SRC
+
+
+  The =exec='d process then listens on FD 3, which is one half of the
+  =sockpair= that was created earlier.
+
+  In the non-exec'd process, first the contents of the auth session's
+  =*data= are read in one at a time.
+
+  The data received through the back channel is then put into the
+  =spool= of the auth session using =_auth_spool(as, pfd[0])=. After
+  that the spooled data is scanned for key words defined in
+  =login_cap.h=.
+
+  #+BEGIN_SRC c
+  #define BI_AUTH         "authorize"         /* Accepted authentication */
+  #define BI_REJECT       "reject"            /* Rejected authentication */
+  #define BI_CHALLENGE    "reject challenge"  /* Reject with a challenge */
+  #define BI_SILENT       "reject silent"     /* Reject silently */
+  #define BI_REMOVE       "remove"            /* remove file on error */
+  #define BI_ROOTOKAY     "authorize root"    /* root authenticated */
+  #define BI_SECURE       "authorize secure"  /* okay on non-secure line */
+  #define BI_SETENV       "setenv"            /* set environment variable */
+  #define BI_UNSETENV     "unsetenv"          /* unset environment variable */
+  #define BI_VALUE        "value"             /* set local variable */
+  #define BI_EXPIRED      "reject expired"    /* account expired */
+  #define BI_PWEXPIRED    "reject pwexpired"  /* password expired */
+  #define BI_FDPASS       "fd"                /* child is passing an fd */
+  #+END_SRC
+
+  It is looking for lines that start with either =BI_AUTH=
+  (=authorize=), or =BI_REJECT= (=reject=). If the line is still longer,
+  it continues to scan for any other qualifiers such as =pwexpired= or
+  =silent=. The struct's =state= is set to one using the =AUTH_= values
+  from =login_cap.h= accordingly.
+
+  #+BEGIN_SRC c
+  /*
+   * bits which can be returned by authenticate()/auth_scan()
+   */
+  #define  AUTH_OKAY       0x01            /* user authenticated */
+  #define  AUTH_ROOTOKAY   0x02            /* authenticated as root */
+  #define  AUTH_SECURE     0x04            /* secure login */
+  #define  AUTH_SILENT     0x08            /* silent rejection */
+  #define  AUTH_CHALLENGE  0x10            /* a challenge was given */
+  #define  AUTH_EXPIRED    0x20            /* account expired */
+  #define  AUTH_PWEXPIRED  0x40            /* password expired */
+  #+END_SRC
+
+
+  This is the integer returned by
+  =auth_userokay=.
 
 * grapgh?
 # Setting env on auth_close(as)
-- 
cgit v1.2.3