|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)kpasswdd.c 1.5 (Berkeley) 6/22/90"; ! 20: #endif /* not lint */ ! 21: ! 22: /* ! 23: * kpasswdd - update a principal's passwd field in the Kerberos ! 24: * database. Called from inetd. ! 25: * K. Fall ! 26: * 12-Dec-88 ! 27: */ ! 28: ! 29: #include <sys/types.h> ! 30: #include <sys/time.h> ! 31: #include <sys/resource.h> ! 32: #include <sys/signal.h> ! 33: #include <netinet/in.h> ! 34: #include <pwd.h> ! 35: #include <syslog.h> ! 36: #include <kerberosIV/des.h> ! 37: #include <kerberosIV/krb.h> ! 38: #include <kerberosIV/krb_db.h> ! 39: #include <stdio.h> ! 40: #include "kpasswd_proto.h" ! 41: ! 42: static struct kpasswd_data kpwd_data; ! 43: static des_cblock master_key, key; ! 44: static Key_schedule master_key_schedule, ! 45: key_schedule, random_sched; ! 46: long mkeyversion; ! 47: AUTH_DAT kdata; ! 48: static Principal principal_data; ! 49: static struct update_data ud_data; ! 50: ! 51: char inst[INST_SZ]; ! 52: char version[9]; ! 53: KTEXT_ST ticket; ! 54: ! 55: char *progname; /* for the library */ ! 56: ! 57: main() ! 58: { ! 59: struct sockaddr_in foreign; ! 60: int foreign_len = sizeof(foreign); ! 61: int rval, more; ! 62: static char name[] = "kpasswdd"; ! 63: ! 64: static struct rlimit rl = { 0, 0 }; ! 65: ! 66: progname = name; ! 67: openlog("kpasswdd", LOG_CONS | LOG_PID, LOG_AUTH); ! 68: ! 69: signal(SIGHUP, SIG_IGN); ! 70: signal(SIGINT, SIG_IGN); ! 71: signal(SIGTSTP, SIG_IGN); ! 72: if (setrlimit(RLIMIT_CORE, &rl) < 0) { ! 73: syslog(LOG_ERR, "setrlimit: %m"); ! 74: exit(1); ! 75: } ! 76: ! 77: if (getpeername(0, &foreign, &foreign_len) < 0) { ! 78: syslog(LOG_ERR,"getpeername: %m"); ! 79: exit(1); ! 80: } ! 81: ! 82: strcpy(inst, "*"); ! 83: rval = krb_recvauth( ! 84: 0L, /* options--!MUTUAL */ ! 85: 0, /* file desc */ ! 86: &ticket, /* client's ticket */ ! 87: SERVICE, /* expected service */ ! 88: inst, /* expected instance */ ! 89: &foreign, /* foreign addr */ ! 90: (struct sockaddr_in *) 0, /* local addr */ ! 91: &kdata, /* returned krb data */ ! 92: "", /* service keys file */ ! 93: (bit_64 *) NULL, /* returned key schedule */ ! 94: version ! 95: ); ! 96: ! 97: ! 98: if (rval != KSUCCESS) { ! 99: syslog(LOG_ERR, "krb_recvauth: %s", krb_err_txt[rval]); ! 100: cleanup(); ! 101: exit(1); ! 102: } ! 103: ! 104: if (*version == '\0') { ! 105: /* indicates error on client's side (no tickets, etc.) */ ! 106: cleanup(); ! 107: exit(0); ! 108: } else if (strcmp(version, "KPWDV0.1") != 0) { ! 109: syslog(LOG_NOTICE, ! 110: "kpasswdd version conflict (recv'd %s)", ! 111: version); ! 112: cleanup(); ! 113: exit(1); ! 114: } ! 115: ! 116: ! 117: /* get master key */ ! 118: if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) { ! 119: syslog(LOG_ERR, "couldn't get master key"); ! 120: cleanup(); ! 121: exit(1); ! 122: } ! 123: ! 124: mkeyversion = kdb_get_master_key(NULL, master_key, master_key_schedule); ! 125: ! 126: if (mkeyversion < 0) { ! 127: syslog(LOG_NOTICE, "couldn't verify master key"); ! 128: cleanup(); ! 129: exit(1); ! 130: } ! 131: ! 132: /* get principal info */ ! 133: rval = kerb_get_principal( ! 134: kdata.pname, ! 135: kdata.pinst, ! 136: &principal_data, ! 137: 1, ! 138: &more ! 139: ); ! 140: ! 141: if (rval < 0) { ! 142: syslog(LOG_NOTICE, ! 143: "error retrieving principal record for %s.%s", ! 144: kdata.pname, kdata.pinst); ! 145: cleanup(); ! 146: exit(1); ! 147: } ! 148: ! 149: if (rval != 1 || (more != 0)) { ! 150: syslog(LOG_NOTICE, "more than 1 dbase entry for %s.%s", ! 151: kdata.pname, kdata.pinst); ! 152: cleanup(); ! 153: exit(1); ! 154: } ! 155: ! 156: /* get the user's key */ ! 157: ! 158: bcopy(&principal_data.key_low, key, 4); ! 159: bcopy(&principal_data.key_high, ((long *) key) + 1, 4); ! 160: kdb_encrypt_key(key, key, master_key, master_key_schedule, ! 161: DECRYPT); ! 162: key_sched(key, key_schedule); ! 163: des_set_key(key, key_schedule); ! 164: ! 165: ! 166: /* get random key and send it over {random} Kperson */ ! 167: ! 168: random_key(kpwd_data.random_key); ! 169: strcpy(kpwd_data.secure_msg, SECURE_STRING); ! 170: if (des_write(0, &kpwd_data, sizeof(kpwd_data)) != sizeof(kpwd_data)) { ! 171: syslog(LOG_ERR, "error writing initial data"); ! 172: cleanup(); ! 173: exit(1); ! 174: } ! 175: ! 176: bzero(key, sizeof(key)); ! 177: bzero(key_schedule, sizeof(key_schedule)); ! 178: ! 179: /* now read update info: { info }Krandom */ ! 180: ! 181: key_sched(kpwd_data.random_key, random_sched); ! 182: des_set_key(kpwd_data.random_key, random_sched); ! 183: if (des_read(0, &ud_data, sizeof(ud_data)) != sizeof(ud_data)) { ! 184: syslog(LOG_ERR, "update aborted"); ! 185: cleanup(); ! 186: exit(1); ! 187: } ! 188: ! 189: /* validate info string by looking at the embedded string */ ! 190: ! 191: if (strcmp(ud_data.secure_msg, SECURE_STRING) != 0) { ! 192: syslog(LOG_NOTICE, "invalid update from %s", ! 193: inet_ntoa(foreign.sin_addr)); ! 194: cleanup(); ! 195: exit(1); ! 196: } ! 197: ! 198: /* produce the new key entry in the database { key }Kmaster */ ! 199: string_to_key(ud_data.pw, key); ! 200: kdb_encrypt_key(key, key, ! 201: master_key, master_key_schedule, ! 202: ENCRYPT); ! 203: bcopy(key, &principal_data.key_low, 4); ! 204: bcopy(((long *) key) + 1, ! 205: &principal_data.key_high, 4); ! 206: bzero(key, sizeof(key)); ! 207: principal_data.key_version++; ! 208: if (kerb_put_principal(&principal_data, 1)) { ! 209: syslog(LOG_ERR, "couldn't write new record for %s.%s", ! 210: principal_data.name, principal_data.instance); ! 211: cleanup(); ! 212: exit(1); ! 213: } ! 214: ! 215: syslog(LOG_NOTICE,"wrote new password field for %s.%s from %s", ! 216: principal_data.name, ! 217: principal_data.instance, ! 218: inet_ntoa(foreign.sin_addr) ! 219: ); ! 220: ! 221: send_ack(0, "Update complete.\n"); ! 222: cleanup(); ! 223: exit(0); ! 224: } ! 225: ! 226: cleanup() ! 227: { ! 228: bzero(&kpwd_data, sizeof(kpwd_data)); ! 229: bzero(master_key, sizeof(master_key)); ! 230: bzero(master_key_schedule, sizeof(master_key_schedule)); ! 231: bzero(key, sizeof(key)); ! 232: bzero(key_schedule, sizeof(key_schedule)); ! 233: bzero(random_sched, sizeof(random_sched)); ! 234: bzero(&principal_data, sizeof(principal_data)); ! 235: bzero(&ud_data, sizeof(ud_data)); ! 236: } ! 237: ! 238: send_ack(remote, msg) ! 239: int remote; ! 240: char *msg; ! 241: { ! 242: int cc; ! 243: cc = des_write(remote, msg, strlen(msg) + 1); ! 244: if (cc <= 0) { ! 245: syslog(LOG_ERR, "error writing ack"); ! 246: cleanup(); ! 247: exit(1); ! 248: } ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.