185690Snsayer/*- 285690Snsayer * Copyright (c) 1991, 1993 385690Snsayer * Dave Safford. All rights reserved. 485690Snsayer * 585690Snsayer * Redistribution and use in source and binary forms, with or without 685690Snsayer * modification, are permitted provided that the following conditions 785690Snsayer * are met: 885690Snsayer * 1. Redistributions of source code must retain the above copyright 985690Snsayer * notice, this list of conditions and the following disclaimer. 1085690Snsayer * 2. Redistributions in binary form must reproduce the above copyright 1185690Snsayer * notice, this list of conditions and the following disclaimer in the 1285690Snsayer * documentation and/or other materials provided with the distribution. 1385690Snsayer * 3. Neither the name of the University nor the names of its contributors 1485690Snsayer * may be used to endorse or promote products derived from this software 1585690Snsayer * without specific prior written permission. 1685690Snsayer * 1785690Snsayer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1885690Snsayer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1985690Snsayer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2085690Snsayer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2185690Snsayer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2285690Snsayer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2385690Snsayer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2485690Snsayer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2585690Snsayer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2685690Snsayer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2785690Snsayer * SUCH DAMAGE. 2885690Snsayer * 2985690Snsayer */ 3085690Snsayer 3184305Smarkm#include <sys/cdefs.h> 3287139Smarkm 3384305Smarkm__FBSDID("$FreeBSD$"); 3463248Speter 3549887Snsayer#ifdef SRA 3687139Smarkm#ifdef ENCRYPTION 3749887Snsayer#include <sys/types.h> 3849887Snsayer#include <arpa/telnet.h> 3987139Smarkm#include <pwd.h> 4049887Snsayer#include <stdio.h> 4149887Snsayer#include <stdlib.h> 4249887Snsayer#include <string.h> 4387139Smarkm#include <syslog.h> 4487139Smarkm#include <ttyent.h> 4549887Snsayer 4687139Smarkm#ifndef NOPAM 4776339Snsayer#include <security/pam_appl.h> 4881965Smarkm#else 4981965Smarkm#include <unistd.h> 5076339Snsayer#endif 5176339Snsayer 5249887Snsayer#include "auth.h" 5349887Snsayer#include "misc.h" 5449887Snsayer#include "encrypt.h" 5549887Snsayer#include "pk.h" 5649887Snsayer 5749887Snsayerchar pka[HEXKEYBYTES+1], ska[HEXKEYBYTES+1], pkb[HEXKEYBYTES+1]; 5887139Smarkmchar *user, *pass, *xuser, *xpass; 5949887SnsayerDesData ck; 6049887SnsayerIdeaData ik; 6149887Snsayer 6249887Snsayerextern int auth_debug_mode; 6396108Smarkmextern char line[]; 6476610Snsayer 6581965Smarkmstatic int sra_valid = 0; 6681965Smarkmstatic int passwd_sent = 0; 6749887Snsayer 6849887Snsayerstatic unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, 6949887Snsayer AUTHTYPE_SRA, }; 7049887Snsayer 7149887Snsayer#define SRA_KEY 0 7249887Snsayer#define SRA_USER 1 7349887Snsayer#define SRA_CONTINUE 2 7449887Snsayer#define SRA_PASS 3 7549887Snsayer#define SRA_ACCEPT 4 7649887Snsayer#define SRA_REJECT 5 7749887Snsayer 7887139Smarkmstatic int check_user(char *, char *); 7981965Smarkm 8049887Snsayer/* support routine to send out authentication message */ 8181965Smarkmstatic int 8281965SmarkmData(Authenticator *ap, int type, void *d, int c) 8349887Snsayer{ 8449887Snsayer unsigned char *p = str_data + 4; 8549887Snsayer unsigned char *cd = (unsigned char *)d; 8649887Snsayer 8749887Snsayer if (c == -1) 8849887Snsayer c = strlen((char *)cd); 8949887Snsayer 9049887Snsayer if (auth_debug_mode) { 9149887Snsayer printf("%s:%d: [%d] (%d)", 9249887Snsayer str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 9349887Snsayer str_data[3], 9449887Snsayer type, c); 9549887Snsayer printd(d, c); 9649887Snsayer printf("\r\n"); 9749887Snsayer } 9849887Snsayer *p++ = ap->type; 9949887Snsayer *p++ = ap->way; 10049887Snsayer *p++ = type; 10149887Snsayer while (c-- > 0) { 10249887Snsayer if ((*p++ = *cd++) == IAC) 10349887Snsayer *p++ = IAC; 10449887Snsayer } 10549887Snsayer *p++ = IAC; 10649887Snsayer *p++ = SE; 10749887Snsayer if (str_data[3] == TELQUAL_IS) 10849887Snsayer printsub('>', &str_data[2], p - (&str_data[2])); 10949887Snsayer return(net_write(str_data, p - str_data)); 11049887Snsayer} 11149887Snsayer 11281965Smarkmint 11387139Smarkmsra_init(Authenticator *ap __unused, int server) 11449887Snsayer{ 11549887Snsayer if (server) 11649887Snsayer str_data[3] = TELQUAL_REPLY; 11749887Snsayer else 11849887Snsayer str_data[3] = TELQUAL_IS; 11949887Snsayer 12049887Snsayer user = (char *)malloc(256); 12176690Snsayer xuser = (char *)malloc(513); 12249887Snsayer pass = (char *)malloc(256); 12376690Snsayer xpass = (char *)malloc(513); 12476689Snsayer 12576689Snsayer if (user == NULL || xuser == NULL || pass == NULL || xpass == 12676689Snsayer NULL) 12776689Snsayer return 0; /* malloc failed */ 12876689Snsayer 12949887Snsayer passwd_sent = 0; 13049887Snsayer 13149887Snsayer genkeys(pka,ska); 13249887Snsayer return(1); 13349887Snsayer} 13449887Snsayer 13549887Snsayer/* client received a go-ahead for sra */ 13681965Smarkmint 13781965Smarkmsra_send(Authenticator *ap) 13849887Snsayer{ 13949887Snsayer /* send PKA */ 14049887Snsayer 14149887Snsayer if (auth_debug_mode) 14249887Snsayer printf("Sent PKA to server.\r\n" ); 14349887Snsayer printf("Trying SRA secure login:\r\n"); 14449887Snsayer if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) { 14549887Snsayer if (auth_debug_mode) 14649887Snsayer printf("Not enough room for authentication data\r\n"); 14749887Snsayer return(0); 14849887Snsayer } 14949887Snsayer 15049887Snsayer return(1); 15149887Snsayer} 15249887Snsayer 15349887Snsayer/* server received an IS -- could be SRA KEY, USER, or PASS */ 15481965Smarkmvoid 15581965Smarkmsra_is(Authenticator *ap, unsigned char *data, int cnt) 15649887Snsayer{ 15749887Snsayer int valid; 15849887Snsayer Session_Key skey; 15949887Snsayer 16049887Snsayer if (cnt-- < 1) 16176696Snsayer goto bad; 16249887Snsayer switch (*data++) { 16349887Snsayer 16449887Snsayer case SRA_KEY: 16549887Snsayer if (cnt < HEXKEYBYTES) { 16649887Snsayer Data(ap, SRA_REJECT, (void *)0, 0); 16749887Snsayer auth_finished(ap, AUTH_USER); 16849887Snsayer if (auth_debug_mode) { 16949887Snsayer printf("SRA user rejected for bad PKB\r\n"); 17049887Snsayer } 17149887Snsayer return; 17249887Snsayer } 17349887Snsayer if (auth_debug_mode) 17449887Snsayer printf("Sent pka\r\n"); 17549887Snsayer if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) { 17649887Snsayer if (auth_debug_mode) 17749887Snsayer printf("Not enough room\r\n"); 17849887Snsayer return; 17949887Snsayer } 18049887Snsayer memcpy(pkb,data,HEXKEYBYTES); 18149887Snsayer pkb[HEXKEYBYTES] = '\0'; 18249887Snsayer common_key(ska,pkb,&ik,&ck); 18376696Snsayer return; 18449887Snsayer 18549887Snsayer case SRA_USER: 18649887Snsayer /* decode KAB(u) */ 18776690Snsayer if (cnt > 512) /* Attempted buffer overflow */ 18876690Snsayer break; 18949887Snsayer memcpy(xuser,data,cnt); 19049887Snsayer xuser[cnt] = '\0'; 19149887Snsayer pk_decode(xuser,user,&ck); 19249887Snsayer auth_encrypt_user(user); 19349887Snsayer Data(ap, SRA_CONTINUE, (void *)0, 0); 19449887Snsayer 19576696Snsayer return; 19649887Snsayer 19749887Snsayer case SRA_PASS: 19876690Snsayer if (cnt > 512) /* Attempted buffer overflow */ 19976690Snsayer break; 20049887Snsayer /* decode KAB(P) */ 20149887Snsayer memcpy(xpass,data,cnt); 20249887Snsayer xpass[cnt] = '\0'; 20349887Snsayer pk_decode(xpass,pass,&ck); 20449887Snsayer 20549887Snsayer /* check user's password */ 20649887Snsayer valid = check_user(user,pass); 20749887Snsayer 20849887Snsayer if(valid) { 20949887Snsayer Data(ap, SRA_ACCEPT, (void *)0, 0); 21049887Snsayer skey.data = ck; 21149887Snsayer skey.type = SK_DES; 21249887Snsayer skey.length = 8; 21349887Snsayer encrypt_session_key(&skey, 1); 21449887Snsayer 21549887Snsayer sra_valid = 1; 21649887Snsayer auth_finished(ap, AUTH_VALID); 21749887Snsayer if (auth_debug_mode) { 21849887Snsayer printf("SRA user accepted\r\n"); 21949887Snsayer } 22049887Snsayer } 22149887Snsayer else { 22249887Snsayer Data(ap, SRA_CONTINUE, (void *)0, 0); 22349887Snsayer/* 22449887Snsayer Data(ap, SRA_REJECT, (void *)0, 0); 22549887Snsayer sra_valid = 0; 22649887Snsayer auth_finished(ap, AUTH_REJECT); 22749887Snsayer*/ 22849887Snsayer if (auth_debug_mode) { 22949887Snsayer printf("SRA user failed\r\n"); 23049887Snsayer } 23149887Snsayer } 23276696Snsayer return; 23349887Snsayer 23449887Snsayer default: 23549887Snsayer if (auth_debug_mode) 23649887Snsayer printf("Unknown SRA option %d\r\n", data[-1]); 23749887Snsayer } 23876696Snsayerbad: 23976696Snsayer Data(ap, SRA_REJECT, 0, 0); 24076696Snsayer sra_valid = 0; 24176696Snsayer auth_finished(ap, AUTH_REJECT); 24249887Snsayer} 24349887Snsayer 24449887Snsayer/* client received REPLY -- could be SRA KEY, CONTINUE, ACCEPT, or REJECT */ 24581965Smarkmvoid 24681965Smarkmsra_reply(Authenticator *ap, unsigned char *data, int cnt) 24749887Snsayer{ 24849887Snsayer char uprompt[256],tuser[256]; 24949887Snsayer Session_Key skey; 25087139Smarkm size_t i; 25149887Snsayer 25249887Snsayer if (cnt-- < 1) 25349887Snsayer return; 25449887Snsayer switch (*data++) { 25549887Snsayer 25649887Snsayer case SRA_KEY: 25749887Snsayer /* calculate common key */ 25849887Snsayer if (cnt < HEXKEYBYTES) { 25949887Snsayer if (auth_debug_mode) { 26049887Snsayer printf("SRA user rejected for bad PKB\r\n"); 26149887Snsayer } 26249887Snsayer return; 26349887Snsayer } 26449887Snsayer memcpy(pkb,data,HEXKEYBYTES); 26549887Snsayer pkb[HEXKEYBYTES] = '\0'; 26649887Snsayer 26749887Snsayer common_key(ska,pkb,&ik,&ck); 26849887Snsayer 26949887Snsayer enc_user: 27049887Snsayer 27149887Snsayer /* encode user */ 27249887Snsayer memset(tuser,0,sizeof(tuser)); 27349887Snsayer sprintf(uprompt,"User (%s): ",UserNameRequested); 27449887Snsayer telnet_gets(uprompt,tuser,255,1); 27549887Snsayer if (tuser[0] == '\n' || tuser[0] == '\r' ) 27649887Snsayer strcpy(user,UserNameRequested); 27749887Snsayer else { 27849887Snsayer /* telnet_gets leaves the newline on */ 27949887Snsayer for(i=0;i<sizeof(tuser);i++) { 28049887Snsayer if (tuser[i] == '\n') { 28149887Snsayer tuser[i] = '\0'; 28249887Snsayer break; 28349887Snsayer } 28449887Snsayer } 28549887Snsayer strcpy(user,tuser); 28649887Snsayer } 28749887Snsayer pk_encode(user,xuser,&ck); 28849887Snsayer 28949887Snsayer /* send it off */ 29049887Snsayer if (auth_debug_mode) 29149887Snsayer printf("Sent KAB(U)\r\n"); 29249887Snsayer if (!Data(ap, SRA_USER, (void *)xuser, strlen(xuser))) { 29349887Snsayer if (auth_debug_mode) 29449887Snsayer printf("Not enough room\r\n"); 29549887Snsayer return; 29649887Snsayer } 29749887Snsayer break; 29849887Snsayer 29949887Snsayer case SRA_CONTINUE: 30049887Snsayer if (passwd_sent) { 30149887Snsayer passwd_sent = 0; 30249887Snsayer printf("[ SRA login failed ]\r\n"); 30349887Snsayer goto enc_user; 30449887Snsayer } 30549887Snsayer /* encode password */ 306228559Sdim memset(pass,0,256); 30749887Snsayer telnet_gets("Password: ",pass,255,0); 30849887Snsayer pk_encode(pass,xpass,&ck); 30949887Snsayer /* send it off */ 31049887Snsayer if (auth_debug_mode) 31149887Snsayer printf("Sent KAB(P)\r\n"); 31249887Snsayer if (!Data(ap, SRA_PASS, (void *)xpass, strlen(xpass))) { 31349887Snsayer if (auth_debug_mode) 31449887Snsayer printf("Not enough room\r\n"); 31549887Snsayer return; 31649887Snsayer } 31749887Snsayer passwd_sent = 1; 31849887Snsayer break; 31949887Snsayer 32049887Snsayer case SRA_REJECT: 32149887Snsayer printf("[ SRA refuses authentication ]\r\n"); 32249887Snsayer printf("Trying plaintext login:\r\n"); 32349887Snsayer auth_finished(0,AUTH_REJECT); 32449887Snsayer return; 32549887Snsayer 32649887Snsayer case SRA_ACCEPT: 32749887Snsayer printf("[ SRA accepts you ]\r\n"); 32849887Snsayer skey.data = ck; 32949887Snsayer skey.type = SK_DES; 33049887Snsayer skey.length = 8; 33149887Snsayer encrypt_session_key(&skey, 0); 33249887Snsayer 33349887Snsayer auth_finished(ap, AUTH_VALID); 33449887Snsayer return; 33549887Snsayer default: 33649887Snsayer if (auth_debug_mode) 33749887Snsayer printf("Unknown SRA option %d\r\n", data[-1]); 33849887Snsayer return; 33949887Snsayer } 34049887Snsayer} 34149887Snsayer 34281965Smarkmint 34387139Smarkmsra_status(Authenticator *ap __unused, char *name, int level) 34449887Snsayer{ 34549887Snsayer if (level < AUTH_USER) 34649887Snsayer return(level); 34749887Snsayer if (UserNameRequested && sra_valid) { 34849887Snsayer strcpy(name, UserNameRequested); 34949887Snsayer return(AUTH_VALID); 35049887Snsayer } else 35149887Snsayer return(AUTH_USER); 35249887Snsayer} 35349887Snsayer 35449887Snsayer#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 35549887Snsayer#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 35649887Snsayer 35781965Smarkmvoid 35881965Smarkmsra_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 35949887Snsayer{ 36049887Snsayer char lbuf[32]; 36187139Smarkm int i; 36249887Snsayer 36349887Snsayer buf[buflen-1] = '\0'; /* make sure its NULL terminated */ 36449887Snsayer buflen -= 1; 36549887Snsayer 36649887Snsayer switch(data[3]) { 36749887Snsayer 36849887Snsayer case SRA_CONTINUE: 36949887Snsayer strncpy((char *)buf, " CONTINUE ", buflen); 37049887Snsayer goto common; 37149887Snsayer 37249887Snsayer case SRA_REJECT: /* Rejected (reason might follow) */ 37349887Snsayer strncpy((char *)buf, " REJECT ", buflen); 37449887Snsayer goto common; 37549887Snsayer 37649887Snsayer case SRA_ACCEPT: /* Accepted (name might follow) */ 37749887Snsayer strncpy((char *)buf, " ACCEPT ", buflen); 37849887Snsayer 37949887Snsayer common: 38049887Snsayer BUMP(buf, buflen); 38149887Snsayer if (cnt <= 4) 38249887Snsayer break; 38349887Snsayer ADDC(buf, buflen, '"'); 38449887Snsayer for (i = 4; i < cnt; i++) 38549887Snsayer ADDC(buf, buflen, data[i]); 38649887Snsayer ADDC(buf, buflen, '"'); 38749887Snsayer ADDC(buf, buflen, '\0'); 38849887Snsayer break; 38949887Snsayer 39049887Snsayer case SRA_KEY: /* Authentication data follows */ 39149887Snsayer strncpy((char *)buf, " KEY ", buflen); 39249887Snsayer goto common2; 39349887Snsayer 39449887Snsayer case SRA_USER: 39549887Snsayer strncpy((char *)buf, " USER ", buflen); 39649887Snsayer goto common2; 39749887Snsayer 39849887Snsayer case SRA_PASS: 39949887Snsayer strncpy((char *)buf, " PASS ", buflen); 40049887Snsayer goto common2; 40149887Snsayer 40249887Snsayer default: 40349887Snsayer sprintf(lbuf, " %d (unknown)", data[3]); 40449887Snsayer strncpy((char *)buf, lbuf, buflen); 40549887Snsayer common2: 40649887Snsayer BUMP(buf, buflen); 40749887Snsayer for (i = 4; i < cnt; i++) { 40849887Snsayer sprintf(lbuf, " %d", data[i]); 40949887Snsayer strncpy((char *)buf, lbuf, buflen); 41049887Snsayer BUMP(buf, buflen); 41149887Snsayer } 41249887Snsayer break; 41349887Snsayer } 41449887Snsayer} 41549887Snsayer 41676610Snsayerstatic int 41787139Smarkmisroot(const char *usr) 41876610Snsayer{ 41987139Smarkm struct passwd *pwd; 42076610Snsayer 42187139Smarkm if ((pwd=getpwnam(usr))==NULL) 42276610Snsayer return 0; 42387139Smarkm return (!pwd->pw_uid); 42476610Snsayer} 42576610Snsayer 42676610Snsayerstatic int 42781965Smarkmrootterm(char *ttyn) 42876610Snsayer{ 42976610Snsayer struct ttyent *t; 43076610Snsayer 43176610Snsayer return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE); 43276610Snsayer} 43376610Snsayer 43476339Snsayer#ifdef NOPAM 43581965Smarkmstatic int 43687139Smarkmcheck_user(char *name, char *cred) 43749887Snsayer{ 43887139Smarkm char *cp; 43949887Snsayer char *xpasswd, *salt; 44049887Snsayer 44176610Snsayer if (isroot(name) && !rootterm(line)) 44276610Snsayer { 44376610Snsayer crypt("AA","*"); /* Waste some time to simulate success */ 44476610Snsayer return(0); 44576610Snsayer } 44676610Snsayer 44749887Snsayer if (pw = sgetpwnam(name)) { 44849887Snsayer if (pw->pw_shell == NULL) { 44949887Snsayer pw = (struct passwd *) NULL; 45049887Snsayer return(0); 45149887Snsayer } 45249887Snsayer 45349887Snsayer salt = pw->pw_passwd; 45487139Smarkm xpasswd = crypt(cred, salt); 45549887Snsayer /* The strcmp does not catch null passwords! */ 45649887Snsayer if (pw == NULL || *pw->pw_passwd == '\0' || 45749887Snsayer strcmp(xpasswd, pw->pw_passwd)) { 45849887Snsayer pw = (struct passwd *) NULL; 45949887Snsayer return(0); 46049887Snsayer } 46149887Snsayer return(1); 46249887Snsayer } 46349887Snsayer return(0); 46449887Snsayer} 46576339Snsayer#else 46649887Snsayer 46776339Snsayer/* 46876339Snsayer * The following is stolen from ftpd, which stole it from the imap-uw 46976339Snsayer * PAM module and login.c. It is needed because we can't really 47076339Snsayer * "converse" with the user, having already gone to the trouble of 47176339Snsayer * getting their username and password through an encrypted channel. 47276339Snsayer */ 47349887Snsayer 47476339Snsayer#define COPY_STRING(s) (s ? strdup(s):NULL) 47576339Snsayer 47676339Snsayerstruct cred_t { 47776339Snsayer const char *uname; 47876339Snsayer const char *pass; 47976339Snsayer}; 48076339Snsayertypedef struct cred_t cred_t; 48176339Snsayer 48287139Smarkmstatic int 48387139Smarkmauth_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata) 48476339Snsayer{ 48576339Snsayer int i; 48676339Snsayer cred_t *cred = (cred_t *) appdata; 48776339Snsayer struct pam_response *reply = 48876339Snsayer malloc(sizeof(struct pam_response) * num_msg); 48976339Snsayer 49076689Snsayer if (reply == NULL) 49176689Snsayer return PAM_BUF_ERR; 49276689Snsayer 49376339Snsayer for (i = 0; i < num_msg; i++) { 49476339Snsayer switch (msg[i]->msg_style) { 49576339Snsayer case PAM_PROMPT_ECHO_ON: /* assume want user name */ 49676339Snsayer reply[i].resp_retcode = PAM_SUCCESS; 49776339Snsayer reply[i].resp = COPY_STRING(cred->uname); 49876339Snsayer /* PAM frees resp. */ 49976339Snsayer break; 50076339Snsayer case PAM_PROMPT_ECHO_OFF: /* assume want password */ 50176339Snsayer reply[i].resp_retcode = PAM_SUCCESS; 50276339Snsayer reply[i].resp = COPY_STRING(cred->pass); 50376339Snsayer /* PAM frees resp. */ 50476339Snsayer break; 50576339Snsayer case PAM_TEXT_INFO: 50676339Snsayer case PAM_ERROR_MSG: 50776339Snsayer reply[i].resp_retcode = PAM_SUCCESS; 50876339Snsayer reply[i].resp = NULL; 50976339Snsayer break; 51076339Snsayer default: /* unknown message style */ 51176339Snsayer free(reply); 51276339Snsayer return PAM_CONV_ERR; 51376339Snsayer } 51476339Snsayer } 51576339Snsayer 51676339Snsayer *resp = reply; 51776339Snsayer return PAM_SUCCESS; 51876339Snsayer} 51976339Snsayer 52076339Snsayer/* 52176751Snsayer * The PAM version as a side effect may put a new username in *name. 52276339Snsayer */ 52381965Smarkmstatic int 52487139Smarkmcheck_user(char *name, char *cred) 52576339Snsayer{ 52676339Snsayer pam_handle_t *pamh = NULL; 52776339Snsayer const void *item; 52876339Snsayer int rval; 52976339Snsayer int e; 53087139Smarkm cred_t auth_cred = { name, cred }; 53176339Snsayer struct pam_conv conv = { &auth_conv, &auth_cred }; 53276339Snsayer 53376339Snsayer e = pam_start("telnetd", name, &conv, &pamh); 53476339Snsayer if (e != PAM_SUCCESS) { 53576339Snsayer syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e)); 53676339Snsayer return 0; 53776339Snsayer } 53876339Snsayer 53976339Snsayer#if 0 /* Where can we find this value? */ 54076339Snsayer e = pam_set_item(pamh, PAM_RHOST, remotehost); 54176339Snsayer if (e != PAM_SUCCESS) { 54276339Snsayer syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s", 54376339Snsayer pam_strerror(pamh, e)); 54476339Snsayer return 0; 54576339Snsayer } 54649887Snsayer#endif 54749887Snsayer 54876339Snsayer e = pam_authenticate(pamh, 0); 54976339Snsayer switch (e) { 55076339Snsayer case PAM_SUCCESS: 55176339Snsayer /* 55276339Snsayer * With PAM we support the concept of a "template" 55376339Snsayer * user. The user enters a login name which is 55476339Snsayer * authenticated by PAM, usually via a remote service 55576339Snsayer * such as RADIUS or TACACS+. If authentication 55676339Snsayer * succeeds, a different but related "template" name 55776339Snsayer * is used for setting the credentials, shell, and 55876339Snsayer * home directory. The name the user enters need only 55976339Snsayer * exist on the remote authentication server, but the 56076339Snsayer * template name must be present in the local password 56176339Snsayer * database. 56276339Snsayer * 56376339Snsayer * This is supported by two various mechanisms in the 56476339Snsayer * individual modules. However, from the application's 56576339Snsayer * point of view, the template user is always passed 56676339Snsayer * back as a changed value of the PAM_USER item. 56776339Snsayer */ 56876339Snsayer if ((e = pam_get_item(pamh, PAM_USER, &item)) == 56976339Snsayer PAM_SUCCESS) { 57087139Smarkm strcpy(name, item); 57176339Snsayer } else 57276339Snsayer syslog(LOG_ERR, "Couldn't get PAM_USER: %s", 57376339Snsayer pam_strerror(pamh, e)); 57476751Snsayer if (isroot(name) && !rootterm(line)) 57576610Snsayer rval = 0; 57676610Snsayer else 57776610Snsayer rval = 1; 57876339Snsayer break; 57976339Snsayer 58076339Snsayer case PAM_AUTH_ERR: 58176339Snsayer case PAM_USER_UNKNOWN: 58276339Snsayer case PAM_MAXTRIES: 58376339Snsayer rval = 0; 58476339Snsayer break; 58576339Snsayer 58676339Snsayer default: 58776339Snsayer syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e)); 58876339Snsayer rval = 0; 58976339Snsayer break; 59076339Snsayer } 59176339Snsayer 59276339Snsayer if ((e = pam_end(pamh, e)) != PAM_SUCCESS) { 59376339Snsayer syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e)); 59476339Snsayer rval = 0; 59576339Snsayer } 59676339Snsayer return rval; 59776339Snsayer} 59876339Snsayer 59976339Snsayer#endif 60076339Snsayer 60187139Smarkm#endif /* ENCRYPTION */ 60287139Smarkm#endif /* SRA */ 603