Annotation of src/usr.bin/login/k5login.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: k5login.c,v 1.2 1994/12/23 06:52:58 jtc Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1990 The Regents of the University of California.
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
! 36: #ifndef lint
! 37: #if 0
! 38: static char sccsid[] = "@(#)klogin.c 5.11 (Berkeley) 7/12/92";
! 39: #endif
! 40: static char rcsid[] = "$NetBSD: k5login.c,v 1.2 1994/12/23 06:52:58 jtc Exp $";
! 41: #endif /* not lint */
! 42:
! 43: #ifdef KERBEROS5
! 44: #include <sys/param.h>
! 45: #include <sys/syslog.h>
! 46: #include <com_err.h>
! 47: #include <krb5/krb5.h>
! 48: #include <krb5/ext-proto.h>
! 49: #include <krb5/los-proto.h>
! 50: #include <pwd.h>
! 51: #include <netdb.h>
! 52: #include <stdio.h>
! 53: #include <string.h>
! 54: #include <unistd.h>
! 55:
! 56: #define KRB5_DEFAULT_OPTIONS 0
! 57: #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
! 58:
! 59: krb5_data tgtname = {
! 60: KRB5_TGS_NAME_SIZE,
! 61: KRB5_TGS_NAME
! 62: };
! 63:
! 64: /*
! 65: * Try no preauthentication first; then try the encrypted timestamp
! 66: */
! 67: int preauth_search_list[] = {
! 68: 0,
! 69: KRB5_PADATA_ENC_TIMESTAMP,
! 70: -1
! 71: };
! 72:
! 73: extern int notickets;
! 74: extern char *krbtkfile_env;
! 75: extern char *tty;
! 76:
! 77: static char tkt_location[MAXPATHLEN];
! 78:
! 79: /*
! 80: * Attempt to log the user in using Kerberos authentication
! 81: *
! 82: * return 0 on success (will be logged in)
! 83: * 1 if Kerberos failed (try local password in login)
! 84: */
! 85: int
! 86: klogin(pw, instance, localhost, password)
! 87: struct passwd *pw;
! 88: char *instance, *localhost, *password;
! 89: {
! 90: krb5_error_code kerror;
! 91: krb5_address **my_addresses;
! 92: krb5_principal me, server;
! 93: krb5_creds my_creds;
! 94: krb5_timestamp now;
! 95: krb5_ccache ccache = NULL;
! 96: int preauth_type = -1;
! 97: long lifetime = KRB5_DEFAULT_LIFE;
! 98: int options = KRB5_DEFAULT_OPTIONS;
! 99: int i;
! 100: char *realm, *client_name;
! 101: char *principal;
! 102:
! 103: #ifdef SKEY
! 104: /*
! 105: * We don't do s/key challenge and Kerberos at the same time
! 106: */
! 107: if (strcasecmp(password, "s/key") == 0) {
! 108: return (1);
! 109: }
! 110: #endif
! 111:
! 112: krb5_init_ets();
! 113:
! 114: /*
! 115: * Root logins don't use Kerberos.
! 116: * If we have a realm, try getting a ticket-granting ticket
! 117: * and using it to authenticate. Otherwise, return
! 118: * failure so that we can try the normal passwd file
! 119: * for a password. If that's ok, log the user in
! 120: * without issuing any tickets.
! 121: */
! 122: if (strcmp(pw->pw_name, "root") == 0 ||
! 123: krb5_get_default_realm(&realm))
! 124: return (1);
! 125:
! 126: /*
! 127: * get TGT for local realm
! 128: * tickets are stored in a file named TKT_ROOT plus uid
! 129: * except for user.root tickets.
! 130: */
! 131:
! 132: if (strcmp(instance, "root") != 0)
! 133: (void)sprintf(tkt_location, "FILE:/tmp/krb5cc_%d.%s",
! 134: pw->pw_uid, tty);
! 135: else
! 136: (void)sprintf(tkt_location, "FILE:/tmp/krb5cc_root_%d.%s",
! 137: pw->pw_uid, tty);
! 138: krbtkfile_env = tkt_location;
! 139:
! 140: principal = malloc(strlen(pw->pw_name)+strlen(instance)+2);
! 141: strcpy(principal, pw->pw_name);
! 142: if (strlen(instance)) {
! 143: strcat(principal, "/");
! 144: strcat(principal, instance);
! 145: }
! 146:
! 147: if (kerror = krb5_cc_resolve(tkt_location, &ccache)) {
! 148: syslog(LOG_NOTICE, "warning: %s while getting default ccache",
! 149: error_message(kerror));
! 150: return(1);
! 151: }
! 152:
! 153: if (kerror = krb5_parse_name(principal, &me)) {
! 154: syslog(LOG_NOTICE, "warning: %s when parsing name %s",
! 155: error_message(kerror), principal);
! 156: return(1);
! 157: }
! 158:
! 159: if (kerror = krb5_unparse_name(me, &client_name)) {
! 160: syslog(LOG_NOTICE, "warning: %s when unparsing name %s",
! 161: error_message(kerror), principal);
! 162: return(1);
! 163: }
! 164:
! 165: kerror = krb5_cc_initialize (ccache, me);
! 166: if (kerror != 0) {
! 167: syslog(LOG_NOTICE, "%s when initializing cache %s",
! 168: error_message(kerror), tkt_location);
! 169: return(1);
! 170: }
! 171:
! 172: memset((char *)&my_creds, 0, sizeof(my_creds));
! 173:
! 174: my_creds.client = me;
! 175:
! 176: if (kerror = krb5_build_principal_ext(&server,
! 177: krb5_princ_realm(me)->length,
! 178: krb5_princ_realm(me)->data,
! 179: tgtname.length, tgtname.data,
! 180: krb5_princ_realm(me)->length,
! 181: krb5_princ_realm(me)->data,
! 182: 0)) {
! 183: syslog(LOG_NOTICE, "%s while building server name",
! 184: error_message(kerror));
! 185: return(1);
! 186: }
! 187:
! 188: my_creds.server = server;
! 189:
! 190: kerror = krb5_os_localaddr(&my_addresses);
! 191: if (kerror != 0) {
! 192: syslog(LOG_NOTICE, "%s when getting my address",
! 193: error_message(kerror));
! 194: return(1);
! 195: }
! 196:
! 197: if (kerror = krb5_timeofday(&now)) {
! 198: syslog(LOG_NOTICE, "%s while getting time of day",
! 199: error_message(kerror));
! 200: return(1);
! 201: }
! 202: my_creds.times.starttime = 0; /* start timer when request
! 203: gets to KDC */
! 204: my_creds.times.endtime = now + lifetime;
! 205: my_creds.times.renew_till = 0;
! 206:
! 207: for (i=0; preauth_search_list[i] >= 0; i++) {
! 208: kerror = krb5_get_in_tkt_with_password(options, my_addresses,
! 209: preauth_search_list[i],
! 210: ETYPE_DES_CBC_CRC,
! 211: KEYTYPE_DES,
! 212: password,
! 213: ccache,
! 214: &my_creds, 0);
! 215: if (kerror != KRB5KDC_PREAUTH_FAILED &&
! 216: kerror != KRB5KRB_ERR_GENERIC)
! 217: break;
! 218: }
! 219:
! 220: krb5_free_principal(server);
! 221: krb5_free_addresses(my_addresses);
! 222:
! 223: if (chown(&tkt_location[5], pw->pw_uid, pw->pw_gid) < 0)
! 224: syslog(LOG_ERR, "chown tkfile (%s): %m", &tkt_location[5]);
! 225:
! 226: if (kerror) {
! 227: if (kerror == KRB5KRB_AP_ERR_BAD_INTEGRITY)
! 228: printf("%s: Kerberos Password incorrect\n", principal);
! 229: else
! 230: printf("%s while getting initial credentials\n", error_message(kerror));
! 231:
! 232: return(1);
! 233: }
! 234:
! 235: /* Success */
! 236: notickets = 0;
! 237: return(0);
! 238: }
! 239:
! 240: /*
! 241: * Remove any credentials
! 242: */
! 243: void
! 244: kdestroy()
! 245: {
! 246: krb5_error_code code;
! 247: krb5_ccache ccache = NULL;
! 248:
! 249: if (krbtkfile_env == NULL)
! 250: return;
! 251:
! 252: code = krb5_cc_resolve(krbtkfile_env, &ccache);
! 253: if (!code) {
! 254: code = krb5_cc_destroy(ccache);
! 255: if (!code) {
! 256: krb5_cc_close(ccache);
! 257: }
! 258: }
! 259: }
! 260: #endif