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

Annotation of src/usr.bin/passwd/krb_passwd.c, Revision 1.6

1.6     ! deraadt     1: /*     $OpenBSD: krb_passwd.c,v 1.5 1997/03/27 00:30:52 weingart Exp $ */
1.4       deraadt     2:
1.1       deraadt     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: /*static char sccsid[] = "from: @(#)krb_passwd.c       5.4 (Berkeley) 3/1/91";*/
1.6     ! deraadt    38: static char rcsid[] = "$OpenBSD: krb_passwd.c,v 1.5 1997/03/27 00:30:52 weingart Exp $";
1.1       deraadt    39: #endif /* not lint */
                     40:
                     41: #ifdef KERBEROS
                     42:
                     43: #include <sys/types.h>
                     44: #include <sys/socket.h>
                     45: #include <sys/time.h>
                     46: #include <sys/resource.h>
                     47: #include <netinet/in.h>
                     48: #include <kerberosIV/des.h>
                     49: #include <kerberosIV/krb.h>
                     50: #include <netdb.h>
                     51: #include <signal.h>
                     52: #include <pwd.h>
1.5       weingart   53: #include <err.h>
1.1       deraadt    54: #include <errno.h>
                     55: #include <stdio.h>
                     56: #include "kpasswd_proto.h"
                     57: #include <string.h>
                     58: #include <stdlib.h>
1.5       weingart   59: #include <unistd.h>
1.1       deraadt    60:
                     61: #define        PROTO   "tcp"
                     62:
                     63: static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 };
                     64: static struct kpasswd_data proto_data;
                     65: static des_cblock okey;
                     66: static Key_schedule osched;
                     67: KTEXT_ST ticket;
                     68: Key_schedule random_schedule;
                     69: long authopts;
                     70: char realm[REALM_SZ], krbhst[MAX_HSTNM];
                     71: int sock;
                     72:
                     73: krb_passwd()
                     74: {
                     75:        struct servent *se;
                     76:        struct hostent *host;
                     77:        struct sockaddr_in sin;
                     78:        CREDENTIALS cred;
1.6     ! deraadt    79:        int fdsn;
        !            80:        fd_set *fdsp;
1.1       deraadt    81:        int rval;
                     82:        char pass[_PASSWORD_LEN], password[_PASSWORD_LEN];
                     83:        static void finish();
                     84:
                     85:        static struct rlimit rl = { 0, 0 };
                     86:
                     87:        (void)signal(SIGHUP, SIG_IGN);
                     88:        (void)signal(SIGINT, SIG_IGN);
                     89:        (void)signal(SIGTSTP, SIG_IGN);
                     90:
                     91:        if (setrlimit(RLIMIT_CORE, &rl) < 0) {
1.5       weingart   92:                warn("setrlimit");
1.1       deraadt    93:                return(1);
                     94:        }
                     95:
                     96:        if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
1.5       weingart   97:                warnx("couldn't find entry for service %s/%s", SERVICE, PROTO);
1.1       deraadt    98:                return(1);
                     99:        }
                    100:
                    101:        if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
1.5       weingart  102:                warnx("couldn't get local Kerberos realm: %s", krb_err_txt[rval]);
1.1       deraadt   103:                return(1);
                    104:        }
                    105:
                    106:        if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
1.5       weingart  107:                warnx("couldn't get Kerberos host: %s", krb_err_txt[rval]);
1.1       deraadt   108:                return(1);
                    109:        }
                    110:
                    111:        if ((host = gethostbyname(krbhst)) == NULL) {
1.5       weingart  112:                warnx("couldn't get host entry for krb host %s", krbhst);
1.1       deraadt   113:                return(1);
                    114:        }
                    115:
                    116:        sin.sin_family = host->h_addrtype;
                    117:        bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
                    118:        sin.sin_port = se->s_port;
                    119:
                    120:        if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
1.5       weingart  121:                warn("socket");
1.1       deraadt   122:                return(1);
                    123:        }
                    124:
                    125:        if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
1.5       weingart  126:                warn("connect");
1.1       deraadt   127:                (void)close(sock);
                    128:                return(1);
                    129:        }
                    130:
                    131:        rval = krb_sendauth(
                    132:                authopts,               /* NOT mutual */
                    133:                sock,
                    134:                &ticket,                /* (filled in) */
                    135:                SERVICE,
                    136:                krbhst,                 /* instance (krbhst) */
                    137:                realm,                  /* dest realm */
                    138:                (u_long) getpid(),      /* checksum */
                    139:                NULL,                   /* msg data */
                    140:                NULL,                   /* credentials */
                    141:                NULL,                   /* schedule */
                    142:                NULL,                   /* local addr */
                    143:                NULL,                   /* foreign addr */
                    144:                "KPWDV0.1"
                    145:        );
                    146:
                    147:        if (rval != KSUCCESS) {
1.5       weingart  148:                warnx("Kerberos sendauth error: %s", krb_err_txt[rval]);
1.1       deraadt   149:                return(1);
                    150:        }
                    151:
                    152:        krb_get_cred("krbtgt", realm, realm, &cred);
                    153:
                    154:        (void)printf("Changing Kerberos password for %s.%s@%s.\n",
                    155:            cred.pname, cred.pinst, realm);
                    156:
                    157:        if (des_read_pw_string(pass,
                    158:            sizeof(pass)-1, "Old Kerberos password:", 0)) {
1.5       weingart  159:                warnx("error reading old Kerberos password");
1.1       deraadt   160:                return(1);
                    161:        }
                    162:
1.2       tholo     163:        (void)des_string_to_key(pass, &okey);
                    164:        (void)des_key_sched(&okey, osched);
1.3       tholo     165:        (void)desrw_set_key(&okey, osched);
1.1       deraadt   166:
                    167:        /* wait on the verification string */
                    168:
1.6     ! deraadt   169:        fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
        !           170:        if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
        !           171:                err(1, "malloc");
        !           172:        memset(fdsp, 0, fdsn);
        !           173:        FD_SET(sock, fdsp);
1.1       deraadt   174:
                    175:        rval =
1.6     ! deraadt   176:            select(sock + 1, fdsp, (fd_set *) 0, (fd_set *) 0, &timeout);
1.1       deraadt   177:
1.6     ! deraadt   178:        if ((rval < 1) || !FD_ISSET(sock, fdsp)) {
        !           179:                free(fdsp);
1.1       deraadt   180:                if(rval == 0) {
1.5       weingart  181:                        warnx("timed out (aborted)");
1.1       deraadt   182:                        cleanup();
                    183:                        return(1);
                    184:                }
1.5       weingart  185:                warnx("select failed (aborted)");
1.1       deraadt   186:                cleanup();
                    187:                return(1);
                    188:        }
1.6     ! deraadt   189:        free(fdsp);
1.1       deraadt   190:
                    191:        /* read verification string */
                    192:
                    193:        if (des_read(sock, &proto_data, sizeof(proto_data)) !=
                    194:            sizeof(proto_data)) {
1.5       weingart  195:                warnx("couldn't read verification string (aborted)");
1.1       deraadt   196:                cleanup();
                    197:                return(1);
                    198:        }
                    199:
                    200:        (void)signal(SIGHUP, finish);
                    201:        (void)signal(SIGINT, finish);
                    202:
                    203:        if (strcmp(SECURE_STRING, proto_data.secure_msg) != 0) {
                    204:                cleanup();
                    205:                /* don't complain loud if user just hit return */
                    206:                if (pass == NULL || (!*pass))
                    207:                        return(0);
1.5       weingart  208:                warnx("Sorry");
1.1       deraadt   209:                return(1);
                    210:        }
                    211:
1.2       tholo     212:        (void)des_key_sched(&proto_data.random_key, random_schedule);
1.3       tholo     213:        (void)desrw_set_key(&proto_data.random_key, random_schedule);
1.1       deraadt   214:        (void)bzero(pass, sizeof(pass));
                    215:
                    216:        if (des_read_pw_string(pass,
                    217:            sizeof(pass)-1, "New Kerberos password:", 0)) {
1.5       weingart  218:                warnx("error reading new Kerberos password (aborted)");
1.1       deraadt   219:                cleanup();
                    220:                return(1);
                    221:        }
                    222:
                    223:        if (des_read_pw_string(password,
                    224:            sizeof(password)-1, "Retype new Kerberos password:", 0)) {
1.5       weingart  225:                warnx("error reading new Kerberos password (aborted)");
1.1       deraadt   226:                cleanup();
                    227:                return(1);
                    228:        }
                    229:
                    230:        if (strcmp(password, pass) != 0) {
1.5       weingart  231:                warnx("password mismatch (aborted)");
1.1       deraadt   232:                cleanup();
                    233:                return(1);
                    234:        }
                    235:
                    236:        if (strlen(pass) == 0)
                    237:                (void)printf("using NULL password\n");
                    238:
                    239:        send_update(sock, password, SECURE_STRING);
                    240:
                    241:        /* wait for ACK */
                    242:
1.6     ! deraadt   243:        fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
        !           244:        if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
        !           245:                err(1, "malloc");
        !           246:        memset(fdsp, 0, fdsn);
        !           247:        FD_SET(sock, fdsp);
1.1       deraadt   248:
                    249:        rval =
1.6     ! deraadt   250:            select(sock + 1, fdsp, (fd_set *) 0, (fd_set *) 0, &timeout);
        !           251:        if ((rval < 1) || !FD_ISSET(sock, fdsp)) {
        !           252:                free(fdsp);
1.1       deraadt   253:                if(rval == 0) {
1.5       weingart  254:                        warnx("timed out reading ACK (aborted)");
1.1       deraadt   255:                        cleanup();
                    256:                        exit(1);
                    257:                }
1.5       weingart  258:                warnx("select failed (aborted)");
1.1       deraadt   259:                cleanup();
                    260:                exit(1);
                    261:        }
1.6     ! deraadt   262:        free(fdsp);
1.1       deraadt   263:        recv_ack(sock);
                    264:        cleanup();
                    265:        exit(0);
                    266: }
                    267:
                    268: send_update(dest, pwd, str)
                    269:        int dest;
                    270:        char *pwd, *str;
                    271: {
                    272:        static struct update_data ud;
                    273:
                    274:        (void)strncpy(ud.secure_msg, str, _PASSWORD_LEN);
                    275:        (void)strncpy(ud.pw, pwd, sizeof(ud.pw));
                    276:        if (des_write(dest, &ud, sizeof(ud)) != sizeof(ud)) {
1.5       weingart  277:                warnx("couldn't write pw update (abort)");
1.1       deraadt   278:                bzero((char *)&ud, sizeof(ud));
                    279:                cleanup();
                    280:                exit(1);
                    281:        }
                    282: }
                    283:
                    284: recv_ack(remote)
                    285:        int remote;
                    286: {
                    287:        int cc;
                    288:        char buf[BUFSIZ];
                    289:
                    290:        cc = des_read(remote, buf, sizeof(buf));
                    291:        if (cc <= 0) {
1.5       weingart  292:                warnx("error reading acknowledgement (aborted)");
1.1       deraadt   293:                cleanup();
                    294:                exit(1);
                    295:        }
                    296:        (void)printf("%s", buf);
                    297: }
                    298:
                    299: cleanup()
                    300: {
                    301:        (void)bzero((char *)&proto_data, sizeof(proto_data));
                    302:        (void)bzero((char *)okey, sizeof(okey));
                    303:        (void)bzero((char *)osched, sizeof(osched));
                    304:        (void)bzero((char *)random_schedule, sizeof(random_schedule));
                    305: }
                    306:
                    307: static void
                    308: finish()
                    309: {
                    310:        (void)close(sock);
                    311:        exit(1);
                    312: }
                    313:
                    314: #endif /* KERBEROS */