From: Todd C. Miller Date: Thu, 22 Jul 1999 11:04:02 +0000 (+0000) Subject: superceded by new auth API X-Git-Tag: SUDO_1_6_0~231 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d1bcdd0495dee5a9000d333d15d86482ea384143;p=sudo superceded by new auth API --- diff --git a/auth.c b/auth.c deleted file mode 100644 index 0f54fb6e7..000000000 --- a/auth.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * CU sudo version 1.6 - * Copyright (c) 1994,1996,1998,1999 Todd C. Miller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 1, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Please send bugs, changes, problems to sudo-bugs@courtesan.com - * - ******************************************************************* - * - * This module contains routines to authenticate a user. - */ - -#include "config.h" - -#include -#ifdef STDC_HEADERS -#include -#endif /* STDC_HEADERS */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_STRING_H -#include -#endif /* HAVE_STRING_H */ -#ifdef HAVE_STRINGS_H -#include -#endif /* HAVE_STRINGS_H */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_KERB4 -# include -#endif /* HAVE_KERB4 */ -#ifdef HAVE_KERB5 -# include -#endif /* HAVE_KERB5 */ -#ifdef HAVE_PAM -# include -#endif /* HAVE_PAM */ -#ifdef HAVE_AFS -# include -# include -#endif /* HAVE_AFS */ -#ifdef HAVE_SECURID -# include -# include -# include -#endif /* HAVE_SECURID */ -#ifdef HAVE_SKEY -# include -#endif /* HAVE_SKEY */ -#ifdef HAVE_OPIE -# include -#endif /* HAVE_OPIE */ -#ifdef HAVE_AUTHSRV -# include -#endif - -#include "sudo.h" -#include "insults.h" - -#ifndef lint -static const char rcsid[] = "$Sudo$"; -#endif /* lint */ - -/* - * Prototypes for local functions - */ -#ifdef HAVE_KERB4 -static int sudo_krb_validate_user __P((struct passwd *, char *)); -#endif /* HAVE_KERB4 */ -#ifdef HAVE_KERB5 -static int sudo_krb5_validate_user __P((struct passwd *, char *)); -static int verify_krb_v5_tgt __P((krb5_ccache)); -#endif /* HAVE_KERB5 */ -#ifdef HAVE_PAM -static int sudo_conv __P((int, - PAM_CONST struct pam_message **, - struct pam_response **, void *)); -#endif /* HAVE_PAM */ -#ifdef HAVE_SKEY -static char *sudo_skeyprompt __P((struct skey *, char *)); -#endif /* HAVE_SKEY */ -#ifdef HAVE_OPIE -static char *sudo_opieprompt __P((struct opie *, char *)); -#endif /* HAVE_OPIE */ -int user_is_exempt __P((void)); - -/* - * Globals - */ -#ifdef HAVE_SECURID -union config_record configure; -#endif /* HAVE_SECURID */ -#ifdef HAVE_SKEY -struct skey skey; -#endif -#ifdef HAVE_OPIE -struct opie opie; -#endif -#ifdef HAVE_KERB5 -extern krb5_context sudo_context; -extern char *realm; -extern int xrealm; -#endif /* HAVE_KERB5 */ - - -/******************************************************************** - * - * check_passwd() - * - * This function grabs the user's password and checks with the password - * in /etc/passwd (or uses other specified authentication method). - */ - -#ifdef HAVE_SECURID -void -check_passwd() -{ - struct SD_CLIENT sd_dat, *sd; /* SecurID data block */ - register int counter = TRIES_FOR_PASSWORD; - - (void) memset((VOID *)&sd_dat, 0, sizeof(sd_dat)); - sd = &sd_dat; - - /* Initialize SecurID. */ - set_perms(PERM_ROOT, 0); - creadcfg(); - if (sd_init(sd) != 0) { - (void) fprintf(stderr, "%s: Cannot contact SecurID server\n", Argv[0]); - exit(1); - } - - /* You get TRIES_FOR_PASSWORD times to guess your password */ - while (counter > 0) { - if (sd_auth(sd) == ACM_OK) { - set_perms(PERM_USER, 0); - return; - } - - --counter; /* otherwise, try again */ - pass_warn(stderr); - } - set_perms(PERM_USER, 0); - - log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - exit(1); -} -#else /* !HAVE_SECURID */ -#ifdef HAVE_AUTHSRV -void -check_passwd() -{ - char *pass; /* this is what gets entered */ - Cfg *confp; - - char cbuf[128]; - char ubuf[128], buf[128]; - register int counter = TRIES_FOR_PASSWORD; - - if ((confp = cfg_read("sudo")) == (Cfg *)-1) { - fprintf(stderr, "Cannot read config.\n"); - exit(1); - } - - /* Initialize Auth Client */ - auth_open(confp); - - /* get welcome message from auth server */ - if (auth_recv(buf, sizeof(buf))) { - sprintf(buf, "Lost connection to server"); - fprintf(stderr, "%s\n", buf); - exit(1); - } - - if (strncmp(buf, "Authsrv ready", 13)) { - fprintf(stderr, "Auth server error %s\n", buf); - auth_close(); - exit(1); - } - - /* You get TRIES_FOR_PASSWORD times to guess your password */ - while (counter > 0) { - - sprintf(cbuf,"authorize %s sudo",user_name); - - auth_send(cbuf); - auth_recv(cbuf,sizeof(cbuf)); - - if (!strncmp(cbuf, "challenge ", 10)) { - sprintf(buf, "Challenge \"%s\": ", &cbuf[10]); - pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1); - } else if (!strncmp(cbuf, "password", 8)) { - pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1); - } else { - fprintf(stderr, "Server sent %s\n", cbuf); - auth_close(); - exit(1); - } - - sprintf(cbuf, "response '%s'", pass); - auth_send(cbuf); - auth_recv(cbuf, sizeof(cbuf)); - - if (!strncmp(cbuf, "ok", 2)) { - /* Success */ - /*inform_user(cbuf);*/ - set_perms(PERM_USER, 0); - auth_close(); - return; - } else { - fprintf(stderr, "Server returned %s\n", cbuf); - } - pass_warn(stderr); - --counter; /* otherwise, try again */ - } - - set_perms(PERM_USER, 0); - - auth_close(); - - log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - exit(1); -} - -#else /* !HAVE_AUTHSRV */ - -void -check_passwd() -{ - char *pass; /* this is what gets entered */ - int counter = TRIES_FOR_PASSWORD; -#if defined(HAVE_KERB4) && defined(USE_GETPASS) - char kpass[SUDO_PASS_MAX + 1]; -#endif /* HAVE_KERB4 && USE_GETPASS */ -#ifdef HAVE_AUTHENTICATE - char *message; - int reenter; -#endif /* HAVE_AUTHENTICATE */ - -#ifdef HAVE_SKEY - (void) memset((VOID *)&skey, 0, sizeof(skey)); -#endif /* HAVE_SKEY */ -#ifdef HAVE_OPIE - (void) memset((VOID *)&opie, 0, sizeof(opie)); -#endif /* HAVE_OPIE */ - - /* You get TRIES_FOR_PASSWORD times to guess your password */ - while (counter > 0) { - -#ifdef HAVE_AUTHENTICATE - /* use AIX authenticate() function */ - pass = GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1); - reenter = 1; - if (authenticate(user_name, pass, &reenter, &message) == 0) - return; /* valid password */ -#else /* HAVE_AUTHENTICATE */ -# ifdef HAVE_SKEY - /* rewrite the prompt if using s/key since the challenge can change */ - set_perms(PERM_ROOT, 0); - prompt = sudo_skeyprompt(&skey, prompt); - set_perms(PERM_USER, 0); -# endif /* HAVE_SKEY */ -# ifdef HAVE_OPIE - /* rewrite the prompt if using OPIE since the challenge can change */ - set_perms(PERM_ROOT, 0); - prompt = sudo_opieprompt(&opie, prompt); - set_perms(PERM_USER, 0); -# endif /* HAVE_OPIE */ - - /* get a password from the user */ -# if defined(HAVE_KERB4) && defined(USE_GETPASS) - (void) des_read_pw_string(kpass, sizeof(kpass) - 1, prompt, 0); - pass = kpass; -# else - pass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1); -# endif /* HAVE_KERB4 */ - -# ifdef HAVE_SKEY - /* Only check s/key db if the user exists there */ - if (skey.keyfile) { - set_perms(PERM_ROOT, 0); - if (skeyverify(&skey, pass) == 0) { - set_perms(PERM_USER, 0); - return; /* if the key is correct return() */ - } - set_perms(PERM_USER, 0); - } -# endif /* HAVE_SKEY */ -# ifdef HAVE_OPIE - /* Only check OPIE db if the user exists there */ - if (opie.opie_flags) { - set_perms(PERM_ROOT, 0); - if (opieverify(&opie, pass) == 0) { - set_perms(PERM_USER, 0); - return; /* if the key is correct return() */ - } - set_perms(PERM_USER, 0); - } -# endif /* HAVE_OPIE */ -# if !defined(OTP_ONLY) || (!defined(HAVE_SKEY) && !defined(HAVE_OPIE)) - /* - * If we use shadow passwords with a different crypt(3) - * check that here, else use standard crypt(3). - */ -# ifdef HAVE_GETAUTHUID - if (!strcmp(user_passwd, (char *) crypt16(pass, user_passwd))) - return; /* if the passwd is correct return() */ -# endif /* HAVE_GETAUTHUID */ - -# ifdef HAVE_GETPRPWNAM - if (check_secureware(pass)) - return; /* if the passwd is correct return() */ -# endif /* HAVE_HAVE_GETPRPWNAM */ - - /* Normal UN*X password check */ - if (!strcmp(user_passwd, (char *) crypt(pass, user_passwd))) - return; /* if the passwd is correct return() */ - -# ifdef HAVE_KERB4 - if (user_uid && sudo_krb_validate_user(user_pw_ent, pass) == 0) - return; -# endif /* HAVE_KERB4 */ - -# ifdef HAVE_KERB5 - if (sudo_krb5_validate_user(user_pw_ent, pass) == 0) - return; -# endif /* HAVE_KERB5 */ - -# ifdef HAVE_AFS - if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, - user_name, /* name */ - NULL, /* instance */ - NULL, /* realm */ - pass, /* password */ - 0, /* lifetime */ - 0, 0, /* spare */ - NULL) == 0) /* reason */ - return; -# endif /* HAVE_AFS */ -# ifdef HAVE_DCE - /* - * consult the DCE registry for password validation - * note that dce_pwent trashes pass upon return... - */ - if (dce_pwent(user_name, pass)) - return; -# endif /* HAVE_DCE */ -# endif /* !OTP_ONLY || (!HAVE_SKEY && !HAVE_OPIE) */ -#endif /* HAVE_AUTHENTICATE */ - - /* Exit loop on nil password, but give it a chance to match first. */ - if (!pass || *pass == '\0') { - if (counter == TRIES_FOR_PASSWORD) - exit(1); - else - break; - } - - --counter; /* otherwise, try again */ - pass_warn(stderr); - } - - log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - exit(1); -} -#endif /* HAVE_AUTHSRV */ -#endif /* HAVE_SECURID */ - - -#ifdef HAVE_KERB4 -/******************************************************************** - * - * sudo_krb_validate_user() - * - * Validate a user via kerberos. - */ -static int -sudo_krb_validate_user(pw, pass) - struct passwd *pw; - char *pass; -{ - char realm[REALM_SZ]; - char tkfile[sizeof(_PATH_SUDO_TIMEDIR) + 4 + MAX_UID_T_LEN]; - int k_errno; - - /* Get the local realm, or retrun failure (no krb.conf) */ - if (krb_get_lrealm(realm, 1) != KSUCCESS) - return(-1); - - /* - * Set the ticket file to be in sudo sudo timedir so we don't - * wipe out other kerberos tickets. - */ - (void) sprintf(tkfile, "%s/tkt%ld", _PATH_SUDO_TIMEDIR, - (long) pw->pw_uid); - (void) krb_set_tkt_string(tkfile); - - /* - * Update the ticket if password is ok. Kerb4 expects - * the ruid and euid to be the same here so we setuid to root. - */ - set_perms(PERM_ROOT, 0); - k_errno = krb_get_pw_in_tkt(pw->pw_name, "", realm, "krbtgt", realm, - DEFAULT_TKT_LIFE, pass); - - /* - * If we authenticated, destroy the ticket now that we are done with it. - * If not, warn on a "real" error. - */ - if (k_errno == INTK_OK) - dest_tkt(); - else if (k_errno != INTK_BADPW && k_errno != KDC_PR_UNKNOWN) - (void) fprintf(stderr, "Warning: Kerberos error: %s\n", - krb_err_txt[k_errno]); - - /* done with rootly stuff */ - set_perms(PERM_USER, 0); - - return(!(k_errno == INTK_OK)); -} -#endif /* HAVE_KERB4 */ - - -#ifdef HAVE_KERB5 -/******************************************************************** - * - * sudo_krb5_validate_user() - * - * Validate a user via Kerberos 5. We may lose a bit of memory, but it's - * OK since we're a short lived program. I'd rather do that than contort - * the code to handle the cleanup. - */ -static int -sudo_krb5_validate_user(pw, pass) - struct passwd *pw; - char *pass; -{ - krb5_error_code retval; - krb5_principal princ; - krb5_creds creds; - krb5_ccache ccache; - char cache_name[64]; - char *princ_name; - krb5_get_init_creds_opt opts; - - /* Initialize */ - if (!sudo_context) - return -1; - krb5_get_init_creds_opt_init(&opts); - - princ_name = emalloc(strlen(pw->pw_name) + strlen(realm) + 2); - - (void) sprintf(princ_name, "%s@%s", pw->pw_name, realm); - if (retval = krb5_parse_name(sudo_context, princ_name, &princ)) - return retval; - - /* Set the ticket file to be in /tmp so we don't need to change perms. */ - (void) sprintf(cache_name, "FILE:/tmp/sudocc_%ld", getpid()); - if (retval = krb5_cc_resolve(sudo_context, cache_name, &ccache)) - return retval; - - if (retval = krb5_get_init_creds_password(sudo_context, &creds, princ, - pass, krb5_prompter_posix, NULL, - 0, NULL, &opts)) - return retval; - - /* Stash the TGT so we can verify it. */ - if (retval = krb5_cc_initialize(sudo_context, ccache, princ)) - return retval; - if (retval = krb5_cc_store_cred(sudo_context, ccache, &creds)) { - (void) krb5_cc_destroy(sudo_context, ccache); - return retval; - } - - retval = verify_krb_v5_tgt(ccache); - (void) krb5_cc_destroy(sudo_context, ccache); - return (retval == -1); -} - - -/* - * This routine with some modification is from the MIT V5B6 appl/bsd/login.c - * - * Verify the Kerberos ticket-granting ticket just retrieved for the - * user. If the Kerberos server doesn't respond, assume the user is - * trying to fake us out (since we DID just get a TGT from what is - * supposedly our KDC). If the host/ service is unknown (i.e., - * the local keytab doesn't have it), let her in. - * - * Returns 1 for confirmation, -1 for failure, 0 for uncertainty. - */ -static int -verify_krb_v5_tgt(ccache) - krb5_ccache ccache; -{ - char phost[BUFSIZ]; - krb5_error_code retval; - krb5_principal princ; - krb5_keyblock * keyblock = 0; - krb5_data packet; - krb5_auth_context auth_context = NULL; - - packet.data = 0; - - /* - * Get the server principal for the local host. - * (Use defaults of "host" and canonicalized local name.) - */ - if (krb5_sname_to_principal(sudo_context, NULL, NULL, - KRB5_NT_SRV_HST, &princ)) - return -1; - - /* Extract the name directly. */ - strncpy(phost, krb5_princ_component(c, princ, 1)->data, BUFSIZ); - phost[BUFSIZ - 1] = '\0'; - - /* - * Do we have host/ keys? - * (use default keytab, kvno IGNORE_VNO to get the first match, - * and enctype is currently ignored anyhow.) - */ - if (retval = krb5_kt_read_service_key(sudo_context, NULL, princ, 0, - ENCTYPE_DES_CBC_MD5, &keyblock)) { - /* Keytab or service key does not exist */ - if (xrealm) - retval = -1; - else - retval = 0; - goto cleanup; - } - if (keyblock) - krb5_free_keyblock(sudo_context, keyblock); - - /* Talk to the kdc and construct the ticket. */ - retval = krb5_mk_req(sudo_context, &auth_context, 0, "host", phost, - NULL, ccache, &packet); - if (auth_context) { - krb5_auth_con_free(sudo_context, auth_context); - auth_context = NULL; /* setup for rd_req */ - } - if (retval) { - retval = -1; - goto cleanup; - } - - /* Try to use the ticket. */ - retval = krb5_rd_req(sudo_context, &auth_context, &packet, princ, - NULL, NULL, NULL); - if (retval) { - retval = -1; - } else { - retval = 1; - } - -cleanup: - if (packet.data) - krb5_free_data_contents(sudo_context, &packet); - krb5_free_principal(sudo_context, princ); - return retval; - -} -#endif /* HAVE_KERB5 */ - - -#ifdef HAVE_PAM -/* We'd rather use appdata_ptr but Solaris does not pass it through... */ -static int PAM_nullpw; - -/******************************************************************** - * pam_attempt_auth() - * - * Try to authenticate the user using Pluggable Authentication - * Modules (PAM). - */ -void -pam_attempt_auth() -{ - int counter = TRIES_FOR_PASSWORD; - static struct pam_conv pam_conv; - static pam_handle_t *pamh; - - set_perms(PERM_ROOT, 0); - - /* Initial PAM setup */ - pam_conv.conv = sudo_conv; - pam_conv.appdata_ptr = NULL; - PAM_nullpw = 0; - if (pam_start("sudo", user_name, &pam_conv, &pamh) != PAM_SUCCESS) { - set_perms(PERM_USER, 0); - log_error(BAD_AUTH_INIT); - inform_user(BAD_AUTH_INIT); - exit(1); - } - - /* You get TRIES_FOR_PASSWORD times to guess your password */ - while (counter > 0) { - - /* PAM_SILENT prevents error messages from going to syslog(3) */ - if (pam_authenticate(pamh, PAM_SILENT) == PAM_SUCCESS) { - pam_end(pamh, PAM_SUCCESS); - set_perms(PERM_USER, 0); - return; - } - - /* Exit silently if they hit return at the first password prompt */ - if (PAM_nullpw) { - if (counter == TRIES_FOR_PASSWORD) - exit(1); - else - break; - } - - --counter; /* otherwise, try again */ - pass_warn(stderr); - } - pam_end(pamh, 0); - set_perms(PERM_USER, 0); - - log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - exit(1); -} - - -/******************************************************************** - * sudo_conv() - * - * ``Conversation function'' for PAM. - */ -static int -sudo_conv(num_msg, msg, response, appdata_ptr) - int num_msg; - PAM_CONST struct pam_message **msg; - struct pam_response **response; - void *appdata_ptr; -{ - struct pam_response *pr; - struct pam_message *pm; - char *p = prompt; - int echo = 0; - - if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL) - return(PAM_CONV_ERR); - (void) memset((VOID *)*response, 0, num_msg * sizeof(struct pam_response)); - - for (pr = *response, pm = *msg; num_msg--; pr++, pm++) { - switch (pm->msg_style) { - case PAM_PROMPT_ECHO_ON: - echo = 1; - case PAM_PROMPT_ECHO_OFF: - /* Override default prompt for unix auth */ - if (strcmp(p, "Password: ") && strcmp(p, "Password:")) - p = (char *) pm->msg; - pr->resp = estrdup((char *) GETPASS(p, - PASSWORD_TIMEOUT * 60, !echo)); - if (*pr->resp == '\0') - PAM_nullpw = 1; /* empty password */ - break; - case PAM_TEXT_INFO: - if (pm->msg) - (void) puts(pm->msg); - break; - case PAM_ERROR_MSG: - if (pm->msg) { - (void) fputs(pm->msg, stderr); - (void) fputc('\n', stderr); - } - break; - default: - /* Something odd happened */ - /* XXX - should free non-NULL response members */ - free(*response); - *response = NULL; - return(PAM_CONV_ERR); - break; - } - } - - return(PAM_SUCCESS); -} -#endif /* HAVE_PAM */ - - -#ifdef HAVE_SKEY -/******************************************************************** - * - * sudo_skeyprompt() - * - * This function rewrites and return the prompt based the - * s/key challenge * and fills in the user's skey structure. - */ - -static char * -sudo_skeyprompt(user_skey, p) - struct skey *user_skey; - char *p; -{ - char challenge[256]; - int rval; - static char *orig_prompt = NULL, *new_prompt = NULL; - static int op_len, np_size; - - /* save the original prompt */ - if (orig_prompt == NULL) { - orig_prompt = p; - op_len = strlen(p); - - /* ignore trailing colon */ - if (p[op_len - 1] == ':') - op_len--; - } - - /* close old stream */ - if (user_skey->keyfile) - (void) fclose(user_skey->keyfile); - - /* get the skey part of the prompt */ - if ((rval = skeychallenge(user_skey, user_name, challenge)) != 0) { -#ifdef OTP_ONLY - (void) fprintf(stderr, - "%s: You do not exist in the s/key database.\n", - Argv[0]); - exit(1); -#else - /* return the original prompt if we cannot get s/key info */ - return(orig_prompt); -#endif /* OTP_ONLY */ - } - - /* get space for new prompt with embedded s/key challenge */ - if (new_prompt == NULL) { - /* allocate space for new prompt */ - np_size = op_len + strlen(challenge) + 7; - new_prompt = (char *) emalloc(np_size); - } else { - /* already have space allocated, is it enough? */ - if (np_size < op_len + strlen(challenge) + 7) { - np_size = op_len + strlen(challenge) + 7; - new_prompt = (char *) erealloc(new_prompt, np_size); - } - } - - /* embed the s/key challenge into the new password prompt */ -#ifdef LONG_OTP_PROMPT - (void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt); -#else - (void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt, challenge); -#endif /* LONG_OTP_PROMPT */ - - return(new_prompt); -} -#endif /* HAVE_SKEY */ - - -#ifdef HAVE_OPIE -/******************************************************************** - * - * sudo_opieprompt() - * - * This function rewrites and return the prompt based the - * OPIE challenge * and fills in the user's opie structure. - */ - -static char * -sudo_opieprompt(user_opie, p) - struct opie *user_opie; - char *p; -{ - char challenge[OPIE_CHALLENGE_MAX]; - int rval; - static char *orig_prompt = NULL, *new_prompt = NULL; - static int op_len, np_size; - - /* save the original prompt */ - if (orig_prompt == NULL) { - orig_prompt = p; - op_len = strlen(p); - - /* ignore trailing colon */ - if (p[op_len - 1] == ':') - op_len--; - } - - /* get the opie part of the prompt */ - if ((rval = opiechallenge(user_opie, user_name, challenge)) != 0) { -#ifdef OTP_ONLY - (void) fprintf(stderr, - "%s: You do not exist in the opie database.\n", - Argv[0]); - exit(1); -#else - /* return the original prompt if we cannot get opie info */ - return(orig_prompt); -#endif /* OTP_ONLY */ - } - - /* get space for new prompt with embedded opie challenge */ - if (new_prompt == NULL) { - /* allocate space for new prompt */ - np_size = op_len + strlen(challenge) + 7; - new_prompt = (char *) emalloc(np_size); - } else { - /* already have space allocated, is it enough? */ - if (np_size < op_len + strlen(challenge) + 7) { - np_size = op_len + strlen(challenge) + 7; - new_prompt = (char *) erealloc(new_prompt, np_size); - } - } - - /* embed the s/key challenge into the new password prompt */ -#ifdef LONG_OTP_PROMPT - (void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt); -#else - (void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt, challenge); -#endif /* LONG_OTP_PROMPT */ - - return(new_prompt); -} -#endif /* HAVE_OPIE */ - - -/******************************************************************** - * - * pass_warn() - * - * warn the user that the password was incorrect - * (and insult them if insults are configured). - */ - -void -pass_warn(fp) - FILE *fp; -{ - -#ifdef USE_INSULTS - (void) fprintf(fp, "%s\n", INSULT); -#else - (void) fprintf(fp, "%s\n", INCORRECT_PASSWORD); -#endif /* USE_INSULTS */ -} diff --git a/check_sia.c b/check_sia.c deleted file mode 100644 index ebf607e4c..000000000 --- a/check_sia.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * CU sudo version 1.6 - * Copyright (c) 1998, 1999 Todd C. Miller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 1, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Please send bugs, changes, problems to sudo-bugs@courtesan.com - * - ******************************************************************* - * - * check_sia.c -- check a user's password using Digital UNIX's - * Security Integration Architecture - * - * Spider Boardman Sep 26, 1998 - */ - -#include "config.h" - -#ifdef HAVE_SIA - -#include -#ifdef STDC_HEADERS -#include -#endif /* STDC_HEADERS */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_STRING_H -#include -#endif /* HAVE_STRING_H */ -#ifdef HAVE_STRINGS_H -#include -#endif /* HAVE_STRINGS_H */ -#include -#include -#include -#include - -#include "sudo.h" - -#ifndef lint -static const char rcsid[] = "$Sudo$"; -#endif /* lint */ - -/* - * Prototypes for local functions - */ -static int tcollect __P((int, int, uchar_t *, int, prompt_t *)); - -/******************************************************************** - * tcollect() - * - * Collection routine (callback) for limiting the timeouts in SIA - * prompts. - */ -static int -tcollect(timeout, rendition, title, nprompts, prompts) - int timeout; - int rendition; - uchar_t *title; - int nprompts; - prompt_t *prompts; -{ - switch (rendition) { - case SIAFORM: - case SIAONELINER: - if (timeout <= 0 || timeout > PASSWORD_TIMEOUT * 60) - timeout = PASSWORD_TIMEOUT * 60; - /* - * Substitute custom prompt if a) the sudo prompt is not "Password:" - * and b) the SIA prompt is "Password:" (so we know it is safe). - * This keeps us from overwriting things like s/key challenges. - */ - if (strcmp((char *)prompts[0].prompt, "Password:") == 0 && - strcmp(prompt, "Password:") != 0) - prompts[0].prompt = (unsigned char *)prompt; - break; - default: - break; - } - - return sia_collect_trm(timeout, rendition, title, nprompts, prompts); -} - -/******************************************************************** - * sia_attempt_auth() - * - * Try to authenticate the user using Security Integration Architecture - * (SIA). Added 9/26/98 by Spider Boardman - */ -void -sia_attempt_auth() -{ - SIAENTITY *siah = NULL; - int retval; - int counter = TRIES_FOR_PASSWORD; - - set_perms(PERM_ROOT, 0); - while (counter > 0) { - retval = sia_ses_init(&siah, Argc, Argv, NULL, user_name, ttyname(0), - 1, NULL); - if (retval != SIASUCCESS) { - set_perms(PERM_USER, 0); - log_error(BAD_AUTH_INIT); - inform_user(BAD_AUTH_INIT); - exit(1); - } - /* XXX - need a way to detect user hitting return or EOF at prompt */ - retval = sia_ses_reauthent(tcollect, siah); - (void) sia_ses_release(&siah); - if (retval == SIASUCCESS) { - set_perms(PERM_USER, 0); - return; - } - - --counter; /* otherwise, try again */ - pass_warn(stderr); - } - set_perms(PERM_USER, 0); - - log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT); - exit(1); -} - -#endif /* HAVE_SIA */ diff --git a/dce_pwent.c b/dce_pwent.c deleted file mode 100644 index c1e108a99..000000000 --- a/dce_pwent.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * CU sudo version 1.6 - * Copyright (c) 1996, 1998, 1999 Todd C. Miller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 1, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Please send bugs, changes, problems to sudo-bugs@courtesan.com - * - ******************************************************************* - * - * Contributed by Jeff Earickson, Colby College, Waterville, ME - * (jaearick@colby.edu) - * - * The code below basically comes from the examples supplied on - * the OSF DCE 1.0.3 manpages for the sec_login routines, with - * enough additional polishing to make the routine work with the - * rest of sudo. - * - * This code is known to work on HP 700 and 800 series systems - * running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE. - * (aka, OSF DCE 1.0.3) or with HP's version 1.4 of DCE (aka, OSF - * DCE 1.1). - * - * Use at your own risk!!! (But I would like to hear about bugs.) - * - * $Sudo$ - */ - -#include "config.h" - -#ifdef HAVE_DCE - -#include -#include -#include -#include -#include -#include /* required to call dce_error_inq_text routine */ - -#include "compat.h" - -/* - * Prototypes - */ -static int check_dce_status __P((error_status_t, char *)); - -/* - * Globals - */ -static int error_stat; -static unsigned char error_string[dce_c_error_string_len]; - - -/* returns 1 ("true") if user is a valid DCE principal, 0 otherwise */ -int -dce_pwent(username, plain_pw) -char *username; -char *plain_pw; -{ - struct passwd *pwd; - sec_passwd_rec_t password_rec; - sec_login_handle_t login_context; - boolean32 reset_passwd; - sec_login_auth_src_t auth_src; - error_status_t status; - unsigned32 nbytes; - - /* create the local context of the DCE principal necessary */ - /* to perform authenticated network operations. The network */ - /* identity set up by this operation cannot be used until it */ - /* is validated via sec_login_validate_identity(). */ - if(sec_login_setup_identity((unsigned_char_p_t) username, - sec_login_no_flags,&login_context,&status)) - { - if(check_dce_status(status,"sec_login_setup_identity(1):")) - return(0); - - password_rec.key.key_type = sec_passwd_plain; - password_rec.key.tagged_union.plain = (idl_char *) plain_pw; - password_rec.pepper = NULL; - password_rec.version_number = sec_passwd_c_version_none; - - /* validate the login context with the password */ - if(sec_login_validate_identity(login_context,&password_rec, - &reset_passwd,&auth_src,&status)) - { - if(check_dce_status(status,"sec_login_validate_identity(1):")) - return(0); - - /* Certify that the DCE Security Server used to set */ - /* up and validate a login context is legitimate. Makes */ - /* sure that we didn't get spoofed by another DCE server.*/ - if(!sec_login_certify_identity(login_context,&status)) - { - fprintf(stderr,"Whoa! Bogus authentication server!\n"); - (void) check_dce_status(status,"sec_login_certify_identity(1):"); - return(0); - } - if(check_dce_status(status,"sec_login_certify_identity(2):")) - return(0); - - /* sets the network credentials to those specified */ - /* by the now validated login context. */ - sec_login_set_context(login_context,&status); - if(check_dce_status(status,"sec_login_set_context:")) - return(0); - - /* oops, your credentials were no good. Possibly */ - /* caused by clock times out of adjustment between */ - /* DCE client and DCE security server... */ - if(auth_src != sec_login_auth_src_network) - { - fprintf(stderr,"You have no network credentials\n"); - return(0); - } - /* check if the password has aged and is no good */ - if(reset_passwd) - { - fprintf(stderr,"Your DCE password needs resetting\n"); - return(0); - } - - /* malloc space for passwd structure */ - nbytes = sizeof(struct passwd); - if((pwd = (struct passwd *) malloc(nbytes)) == NULL) - { - fprintf(stderr,"malloc for passwd struct failed\n"); - return(0); - } - /* we should be a valid user by this point. Pull the */ - /* user's password structure from the DCE security */ - /* server just to make sure. If we get it with no */ - /* problems, then we really are legitimate... */ - sec_login_get_pwent(login_context,(sec_login_passwd_t) pwd,&status); - free(pwd); - if(check_dce_status(status,"sec_login_get_pwent:")) - return(0); - - /************************************************************/ - /* if we get to here, then the pwent above properly fetched */ - /* the password structure from the DCE registry, so the user*/ - /* must be valid. We don't really care what the user's */ - /* registry password is, just that the user could be */ - /* validated. In fact, if we tried to compare the local */ - /* password to the DCE entry at this point, the operation */ - /* would fail if the hidden password feature is turned on, */ - /* because the password field would contain an asterisk. */ - /* Also go ahead and destroy the user's DCE login context */ - /* before we leave here (and don't bother checking the */ - /* status), in order to clean up credentials files in */ - /* /opt/dcelocal/var/security/creds. By doing this, we are */ - /* assuming that the user will not need DCE authentication */ - /* later in the program, only local authentication. If this*/ - /* is not true, then the login_context will have to be */ - /* returned to the calling program, and the context purged */ - /* somewhere later in the program. */ - /************************************************************/ - sec_login_purge_context(&login_context,&status); - return(1); - } - else - { - if(check_dce_status(status,"sec_login_validate_identity(2):")) - return(0); - sec_login_purge_context(&login_context,&status); - if(check_dce_status(status,"sec_login_purge_context:")) - return(0); - } - } - if(check_dce_status(status,"sec_login_setup_identity(2):")) return(0); - return(0); -} - -/* returns 0 for DCE "ok" status, 1 otherwise */ -static int -check_dce_status(input_status, comment) -error_status_t input_status; -char *comment; -{ - if(input_status == rpc_s_ok) return(0); - dce_error_inq_text(input_status, error_string, &error_stat); - fprintf(stderr, "%s %s\n", comment, error_string); - return(1); -} -#endif /* HAVE_DCE */ diff --git a/secureware.c b/secureware.c deleted file mode 100644 index af6f72c85..000000000 --- a/secureware.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * CU sudo version 1.6 - * Copyright (c) 1998, 1999 Todd C. Miller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 1, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Please send bugs, changes, problems to sudo-bugs@courtesan.com - * - ******************************************************************* - * - * secureware.c -- check a user's password when using SecureWare C2 - * - * Todd C. Miller Sat Oct 17 14:42:44 MDT 1998 - */ - -#include "config.h" - -#ifdef HAVE_GETPRPWNAM - -#include -#ifdef STDC_HEADERS -#include -#endif /* STDC_HEADERS */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_STRING_H -#include -#endif /* HAVE_STRING_H */ -#ifdef HAVE_STRINGS_H -#include -#endif /* HAVE_STRINGS_H */ -#include -#include -#include -#ifdef __hpux -# include -#else -# include -#endif /* __hpux */ -#include - -#include "sudo.h" - -#ifndef lint -static const char rcsid[] = "$Sudo$"; -#endif /* lint */ - - -/******************************************************************** - * - * check_secureware() - * - * This function checks a password against the user's encrypted one - * using the SecureWare crypt functions. Returns 1 on a match, else 0. - */ - -int -check_secureware(pass) - char *pass; -{ -#ifdef __alpha - extern int crypt_type; - - if (crypt_type == INT_MAX) - return(0); /* no shadow */ - -# ifdef HAVE_DISPCRYPT - if (strcmp(user_passwd, dispcrypt(pass, user_passwd, crypt_type)) == 0) - return(1); -# else - if (crypt_type == AUTH_CRYPT_BIGCRYPT) { - if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0) - return(1); - } else if (crypt_type == AUTH_CRYPT_CRYPT16) { - if (strcmp(user_passwd, crypt(pass, user_passwd)) == 0) - return(1); - } -# endif /* HAVE_DISPCRYPT */ -#elif defined(HAVE_BIGCRYPT) - if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0) - return(1); -#endif /* __alpha */ - - return(0); -} - -#endif /* HAVE_GETPRPWNAM */