The example of a small PAM module is the ssh_tunnels module. The module initiates a number of SSH tunnels for the user when he or she logs in. SSH tunnels tend to close when they are not used for a while, and the autossh program wraps the SSH client in order to prevent this (or more precisely—autossh will reconnect). The module use the autossh program instead of the plain SSH client.
/* pam_tunnels module */ /* * based on the pam_deny module (Linux PAM) */ #define PAM_SM_SESSION #include <security/pam_modules.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <pwd.h> #include <syslog.h> /* --- session management --- */ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { FILE *conffile; char *conffilename; const char *username = NULL; char *lport, *rport, *host; char cmdline[256], line[256]; struct passwd *pwd = malloc(sizeof(struct passwd)); if (pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) { syslog(LOG_ERR, "cannot determine user name"); return PAM_USER_UNKNOWN; } pwd = getpwnam(username); conffilename = calloc(sizeof(char), strlen(pwd->pw_dir)+20); sprintf(conffilename, "%s/.pam_tunnels.conf", pwd->pw_dir); conffile = fopen(conffilename, "r"); while ((fscanf(conffile, "%s\n", line)) != EOF) { lport = strtok(line, ":"); host = strtok(NULL, ":"); rport = strtok(NULL, ":"); sprintf(cmdline, "autossh -f -N -L %s:%s:%s %s", lport, host, rport, host); system(cmdline); } fclose(conffile); free(conffilename); return PAM_SUCCESS; } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } /* end of module definition */ /* static module data */ #ifdef PAM_STATIC struct pam_module _pam_deny_modstruct = { "pam_deny", NULL, NULL, NULL, pam_sm_open_session, pam_sm_close_session, NULL }; #endif