diff --git a/auth/API b/auth/API new file mode 100644 index 000000000..bf6d4e5e9 --- /dev/null +++ b/auth/API @@ -0,0 +1,118 @@ +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 need_root; /* must run as root? */ + int configured; /* auth type configured on this host? */ + int 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, void **data)); + int (*setup) __P((struct passwd *pw, char **prompt, void **data)); + int (*verify) __P((struct passwd *pw, char *p, void **data)); + int (*cleanup) __P((struct passwd *pw, int status, void **data)); +} sudo_auth; + +The variables in the struct are as follows: + need_root Boolean flag that determines whether or not the auth functions + run with an euid of 0 or the uid of the invoking user. + + configured Boolean flag that is true if the auth method has + been configured and false if not. All auth methods + start out with this set to true. If an "init" or "setup" + functions fails, "configured" is set to false. + + 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. + +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, void **data) + 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, void **data) + 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, void **data) + 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, int status, void **data) + 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 ``status'' variable contains the result of the last + authentication attempt. + +A note about standalone methods. Some authentication methods can't +coexist with anyh 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(1, "foo", foo_init, foo_setup, foo_verify, foo_cleanup) + +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(1, "foo", foo_init, foo_setup, foo_verify, foo_cleanup) +# endif + +Again, if you don't have a init/setup/cleanup routine, just use a NULL +for that field. + +NOTE: in general, you should not make a method both ``standalone'' and + ``normal'' unless you *really* know what you are doing. See + the ``rfc1938'' method for an example of how to do this. + In most cases, you are better off using the --without-passwd + configure argument.