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 { int flags; /* various flags, see below */ int status; /* status from verify routine */ char *name; /* name of the method in string form */ void *data; /* method-specific data pointer */ int (*init)(struct passwd *pw, sudo_auth *auth); int (*setup)(struct passwd *pw, char **prompt, sudo_auth *auth); int (*verify)(struct passwd *pw, const char *p, sudo_auth *auth, struct sudo_conv_callback *callback); int (*approval)(struct passwd *pw, sudo_auth *auth); int (*cleanup)(struct passwd *pw, sudo_auth *auth, bool force); int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth); int (*end_session)(struct passwd *pw, struct 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_DISABLED Set if an "init" or "setup" function fails. FLAG_STANDALONE If set, this indicates that the method must be the only auth method configured, and that it will prompt for the password itself. 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. FLAG_NONINTERACTIVE If set, this indicates that the user invoked sudo with the -n option and no user interaction is allowed. 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. When verify_user() gets AUTH_FATAL from an auth function it does an exit(1). AUTH_INTR An attempt to read the password read was interrupted. Usually this means the user entered ^C at the password prompt. AUTH_NONINTERACTIVE Function failed because user interaction was required but sudo was run in non-interactive mode. The functions in the struct are as follows: int init(struct passwd *pw, sudo_auth *auth) Function to do any one-time initialization for the auth method. All of the "init" functions are run before anything else. 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, struct sudo_conv_callback *callback) 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. The callback should be passed to auth_getpass() to allow sudoers to unlock the ticket file when sudo is suspended. Note that standalone auth methods are responsible for rerading the password themselves. int approval(struct passwd *pw, struct sudo_auth *auth) Function to perform account management and approval *after* the user has authenticated successfully. This function may check for expired accounts, perform time of day restrictions, etc. For PAM, this calls pam_acct_mgmt(). For BSD auth, it calls auth_approval(). int cleanup(struct passwd *pw, sudo_auth *auth, bool force) 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. If the force flag is set, cleanup should happen immediately. int begin_session(struct passwd *pw, char **user_env[], struct sudo_auth *auth) Function to begin a user session. This is used for session handling in PAM and SIA. int end_session(struct passwd *pw, struct sudo_auth *auth) Function to end a user session. This is used for session handling in PAM and SIA. 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. Add the method to the ``auth_switch'' in sudo_auth.c. Note that standalone methods must go first. If ``fooauth'' is a normal auth method, its entry would look like: #ifdef HAVE_FOOAUTH AUTH_ENTRY("foo", 0, foo_init, foo_setup, foo_verify, foo_cleanup, foo_begin_session, foo_end_session) #endif If this is a standalone method, it would be: #ifdef HAVE_FOOAUTH AUTH_ENTRY("foo", FLAG_STANDALONE, foo_init, foo_setup, foo_verify, foo_cleanup, foo_begin_session, foo_end_session) #endif If the method needs to run as the user, not root, add FLAG_USER to the second argument in the AUTH_ENTRY line. If you don't have an init/setup/cleanup/begin/end routine, just use a NULL for that field.