| 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. |