diff options
author | nsayer <nsayer@FreeBSD.org> | 2001-05-07 20:42:02 +0000 |
---|---|---|
committer | nsayer <nsayer@FreeBSD.org> | 2001-05-07 20:42:02 +0000 |
commit | b47830be3e58e44dd6ae03b8dc4c9c034f7a2074 (patch) | |
tree | 6a64bdcf7b40b60eb51400ed98636f3cf17b21a3 /contrib/telnet/libtelnet | |
parent | ce2648b0d2ae4682634f37e718bdc59869d8d572 (diff) | |
download | FreeBSD-src-b47830be3e58e44dd6ae03b8dc4c9c034f7a2074.zip FreeBSD-src-b47830be3e58e44dd6ae03b8dc4c9c034f7a2074.tar.gz |
Pointy hat fix -- reapply the SRA PAM patch. To -current this time.
Diffstat (limited to 'contrib/telnet/libtelnet')
-rw-r--r-- | contrib/telnet/libtelnet/sra.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/contrib/telnet/libtelnet/sra.c b/contrib/telnet/libtelnet/sra.c index 95ac9fd..9274f88 100644 --- a/contrib/telnet/libtelnet/sra.c +++ b/contrib/telnet/libtelnet/sra.c @@ -13,6 +13,10 @@ #include <string.h> #endif +#if !defined(NOPAM) +#include <security/pam_appl.h> +#endif + #include "auth.h" #include "misc.h" #include "encrypt.h" @@ -447,6 +451,7 @@ syslog(LOG_WARNING,"%s\n",save.pw_dir); return (&save); } +#ifdef NOPAM char *crypt(); int check_user(name, pass) @@ -474,7 +479,135 @@ char *pass; } return(0); } +#else + +/* + * The following is stolen from ftpd, which stole it from the imap-uw + * PAM module and login.c. It is needed because we can't really + * "converse" with the user, having already gone to the trouble of + * getting their username and password through an encrypted channel. + */ + +#define COPY_STRING(s) (s ? strdup(s):NULL) + +struct cred_t { + const char *uname; + const char *pass; +}; +typedef struct cred_t cred_t; +auth_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata) +{ + int i; + cred_t *cred = (cred_t *) appdata; + struct pam_response *reply = + malloc(sizeof(struct pam_response) * num_msg); + + for (i = 0; i < num_msg; i++) { + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_ON: /* assume want user name */ + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = COPY_STRING(cred->uname); + /* PAM frees resp. */ + break; + case PAM_PROMPT_ECHO_OFF: /* assume want password */ + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = COPY_STRING(cred->pass); + /* PAM frees resp. */ + break; + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = NULL; + break; + default: /* unknown message style */ + free(reply); + return PAM_CONV_ERR; + } + } + + *resp = reply; + return PAM_SUCCESS; +} + +/* + * The PAM version as a side effect may put a new username in *user. + */ +int check_user(const char *name, const char *pass) +{ + pam_handle_t *pamh = NULL; + const char *tmpl_user; + const void *item; + int rval; + int e; + cred_t auth_cred = { name, pass }; + struct pam_conv conv = { &auth_conv, &auth_cred }; + + e = pam_start("telnetd", name, &conv, &pamh); + if (e != PAM_SUCCESS) { + syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e)); + return 0; + } + +#if 0 /* Where can we find this value? */ + e = pam_set_item(pamh, PAM_RHOST, remotehost); + if (e != PAM_SUCCESS) { + syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s", + pam_strerror(pamh, e)); + return 0; + } +#endif + + e = pam_authenticate(pamh, 0); + switch (e) { + case PAM_SUCCESS: + /* + * With PAM we support the concept of a "template" + * user. The user enters a login name which is + * authenticated by PAM, usually via a remote service + * such as RADIUS or TACACS+. If authentication + * succeeds, a different but related "template" name + * is used for setting the credentials, shell, and + * home directory. The name the user enters need only + * exist on the remote authentication server, but the + * template name must be present in the local password + * database. + * + * This is supported by two various mechanisms in the + * individual modules. However, from the application's + * point of view, the template user is always passed + * back as a changed value of the PAM_USER item. + */ + if ((e = pam_get_item(pamh, PAM_USER, &item)) == + PAM_SUCCESS) { + strcpy(user, (const char *) item); + } else + syslog(LOG_ERR, "Couldn't get PAM_USER: %s", + pam_strerror(pamh, e)); + rval = 1; + break; + + case PAM_AUTH_ERR: + case PAM_USER_UNKNOWN: + case PAM_MAXTRIES: + rval = 0; + break; + + default: + syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e)); + rval = 0; + break; + } + + if ((e = pam_end(pamh, e)) != PAM_SUCCESS) { + syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e)); + rval = 0; + } + return rval; +} + +#endif #endif |