| NOTE: the Sudo auth API is subject to change |
| |
| Purpose: to provide a simple API for authentication methods that |
| encapsulates things nicely without turning into a maze |
| of #ifdef's |
| |
| The sudo_auth struct looks like this: |
| |
| typedef struct sudo_auth { |
| short flags; /* various flags, see below */ |
| short status; /* status from verify routine */ |
| char *name; /* name of the method in string form */ |
| void *data; /* method-specific data pointer */ |
| |
| int (*init) __P((struct passwd *pw, char **prompt, sudo_auth *auth)); |
| int (*setup) __P((struct passwd *pw, char **prompt, sudo_auth *auth)); |
| int (*verify) __P((struct passwd *pw, char *p, sudo_auth *auth)); |
| int (*cleanup) __P((struct passwd *pw, sudo_auth *auth)); |
| } sudo_auth; |
| |
| The variables in the struct are as follows: |
| flags Bitwise binary flags, see below. |
| |
| status Contains the return value from the last run of |
| the "verify" function. Starts out as AUTH_FAILURE. |
| |
| name The name of the authentication method as a C string. |
| |
| data A pointer to method-specific data. This is passed to |
| all the functions of an auth method and is usually |
| initialized in the "init" or "setup" routines. |
| |
| Possible values of sudo_auth.flags: |
| FLAG_USER Whether or not the auth functions should run with |
| the euid of the invoking user instead of 0. |
| |
| FLAG_CONFIGURED If set then the auth method is assumed to have been |
| configured successfully. All auth methods start out |
| with this set. If an "init" or "setup" function |
| fails, this bit is cleared. |
| |
| FLAG_ONEANDONLY If set, this indicates that the method is the |
| only one in use. Can be used by auth functions |
| to determine whether to return a fatal or nonfatal |
| error. |
| |
| The member functions can return the following values: |
| AUTH_SUCCESS Function succeeded. For a ``verify'' function |
| this means the user correctly authenticated. |
| |
| AUTH_FAILURE Function failed. If this is an ``init'' or |
| ``setup'' routine, the auth method will be |
| marked as !configured. |
| |
| AUTH_FATAL A fatal error occurred. The routine should have |
| written an error message to stderr and optionally |
| sent mail to the administrator. (If log_error() |
| is called to do this, the NO_EXIT flag must be used.) |
| When verify_user() gets AUTH_FATAL from an auth |
| function it does an exit(1). |
| |
| The functions in the struct are as follows: |
| |
| int init(struct passwd *pw, char **prompt, sudo_auth *auth) |
| Function to do any one-time initialization for the auth |
| method. All of the "init" functions are run before anything |
| else. A pointer to the prompt string may be used to add |
| method-specific info to the prompt. |
| |
| int setup(struct passwd *pw, char **prompt, sudo_auth *auth) |
| Function to do method-specific setup. All the "setup" |
| routines are run before any of the "verify" routines. A |
| pointer to the prompt string may be used to add method-specific |
| info to the prompt. |
| |
| int verify(struct passwd *pw, char *p, sudo_auth *auth) |
| Function to do user verification for this auth method. For |
| standalone auth methods ``p'' is the prompt string. For |
| normal auth methods, ``p'' is the password the user entered. |
| Note that standalone auth methods are responsible for |
| rerading the password themselves. |
| |
| int cleanup(struct passwd *pw, sudo_auth *auth) |
| Function to do per-auth method cleanup. This is only run |
| at the end of the authentication process, after the user |
| has completely failed or succeeded to authenticate. |
| The ``auth->status'' variable contains the result of the |
| last authentication attempt which may be interesting. |
| |
| A note about standalone methods. Some authentication methods can't |
| coexist with any others. This may be because they encapsulate other |
| methods (pam, sia) or because they have a special way of interacting |
| with the user (securid). |
| |
| Adding a new authentication method: |
| |
| Each method should live in its own file. Add prototypes for the functions |
| in sudo_auth.h. |
| |
| If this is a standalone method, add it to the standalone #if cascade |
| in sudo_auth.h. For instance, for a method, ``fooauth'', add: |
| |
| #elif defined(HAVE_FOOAUTH) |
| # define AUTH_STANDALONE \ |
| AUTH_ENTRY(0, "foo", \ |
| foo_init, foo_setup, foo_verify, foo_cleanup) |
| |
| If the method needs to run as the user, not root, replace the first |
| parameter to AUTH_ENTRY (0) with FLAG_USER. If you don't have a |
| init/setup/cleanup routine, just use a NULL for that field. |
| |
| For a normal authentication method, add it to the ``auth_switch'' in |
| sudo_auth.c. If ``fooauth'' is a normal auth method, its entry |
| would look like: |
| |
| # ifdef HAVE_FOOAUTH |
| AUTH_ENTRY(0, "foo", foo_init, foo_setup, foo_verify, foo_cleanup) |
| # endif |
| |
| Again, if the method doesn't need to run as root, replace the 0 with |
| FLAG_USER. Likewise, if you don't have a init/setup/cleanup routine, |
| just use a NULL for that field. |
| |
| NOTE: You should not make a method both ``standalone'' and |
| ``normal''. Just use the --without-passwd configure argument |
| to disable passwd/shadow file checking and then have your |
| auth routines check the FLAG_ONEANDONLY flag to see if |
| they are running standalone and act accordingly. |