[BACK]Return to k5login.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / login

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