chkey.c revision 26240
1168054Sflz/* 2168054Sflz * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3168266Sgabor * unrestricted use provided that this legend is included on all tape 4168266Sgabor * media and as a part of the software program in whole or part. Users 5168266Sgabor * may copy or modify Sun RPC without charge, but are not authorized 6168266Sgabor * to license or distribute it to anyone else except as part of a product or 7168266Sgabor * program developed by the user or with the express written consent of 8168266Sgabor * Sun Microsystems, Inc. 9168266Sgabor * 10168266Sgabor * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11168054Sflz * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12168054Sflz * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13168064Sflz * 14168064Sflz * Sun RPC is provided with no support and without any obligation on the 15168064Sflz * part of Sun Microsystems, Inc. to assist in its use, correction, 16168064Sflz * modification or enhancement. 17168064Sflz * 18168064Sflz * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19168064Sflz * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20168064Sflz * OR ANY PART THEREOF. 21168064Sflz * 22168064Sflz * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23168064Sflz * or profits or other special, indirect and consequential damages, even if 24168064Sflz * Sun has been advised of the possibility of such damages. 25168064Sflz * 26168064Sflz * Sun Microsystems, Inc. 27168054Sflz * 2550 Garcia Avenue 28168054Sflz * Mountain View, California 94043 29168064Sflz */ 30168054Sflz#ifndef lint 31168064Sflzstatic char sccsid[] = "@(#)chkey.c 1.7 91/03/11 Copyr 1986 Sun Micro"; 32171129Sobrien#endif 33168939Stmclaugh/* 34168131Sbmah * Copyright (C) 1986, Sun Microsystems, Inc. 35168113Smarcus */ 36180225Smarcel 37168123Snetchild/* 38168939Stmclaugh * Command to change one's public key in the public key database 39168064Sflz */ 40168054Sflz#include <stdio.h> 41168054Sflz#include <rpc/rpc.h> 42168054Sflz#include <rpc/key_prot.h> 43168054Sflz#ifdef YP 44168261Sache#include <rpcsvc/yp_prot.h> 45168077Sflz#include <rpcsvc/ypclnt.h> 46168077Sflz#else 47232357Sak#define YPOP_STORE 4 48168126Sale#endif 49168069Sgarga#include <pwd.h> 50168472Snovel#include <string.h> 51179877Samdmi3#include <sys/fcntl.h> 52168274Ssem 53169073Saraujoextern char *getpass(); 54168667Sstefan#define index strchr 55209039Sashishextern char *crypt(); 56203044Savilla#ifdef YPPASSWD 57193190Savlstruct passwd *ypgetpwuid(); 58168274Ssem#endif 59210573Sbapt 60188692Sbeat#ifdef YP 61170471Sbeechstatic char *domain; 62168113Smarcusstatic char PKMAP[] = "publickey.byname"; 63218631Smiwi#else 64173254Sbrixstatic char PKFILE[] = "/etc/publickey"; 65168098Skrion#endif /* YP */ 66168123Snetchildstatic char ROOTKEY[] = "/etc/.rootkey"; 67170601Schinsan 68168082Sgargamain(argc, argv) 69168116Sclsung int argc; 70168937Scperciva char **argv; 71222995Screes{ 72225632Scs char name[MAXNETNAMELEN+1]; 73213988Sculot char public[HEXKEYBYTES + 1]; 74168177Sgabor char secret[HEXKEYBYTES + 1]; 75168354Sdanfe char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 76168072Sehaupt char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 77206034Sdecke int status; 78168108Srafan char *pass; 79168186Smat struct passwd *pw; 80218631Smiwi uid_t uid; 81168210Sitetcu int force = 0; 82225853Seadler char *self; 83168068Serwin#ifdef YP 84168072Sehaupt char *master; 85168113Smarcus#endif 86168059Sgabor 87168542Smiwi self = argv[0]; 88168098Skrion for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) { 89216282Sflo if (argv[0][2] != 0) { 90206495Sfluffy usage(self); 91168054Sflz } 92168059Sgabor switch (argv[0][1]) { 93176595Sgahr case 'f': 94168054Sflz force = 1; 95210773Sglarkin break; 96210773Sglarkin default: 97172158Sjkim usage(self); 98172158Sjkim } 99168256Sijliao } 100168209Sitetcu if (argc != 0) { 101206184Sjacula usage(self); 102176768Sjadawin } 103236343Sjase 104228752Sjgh#ifdef YP 105172158Sjkim (void)yp_get_default_domain(&domain); 106222797Sjlaffaye if (yp_master(domain, PKMAP, &master) != 0) { 107168076Sjmelo (void)fprintf(stderr, 108168123Snetchild "can't find master of publickey database\n"); 109168054Sflz exit(1); 110168055Spav } 111182814Sjpaetzel#endif 112210169Sjsa uid = getuid() /*geteuid()*/; 113168055Spav if (uid == 0) { 114168536Skevlo if (host2netname(name, NULL, NULL) == 0) { 115168177Sgabor (void)fprintf(stderr, 116168098Skrion "chkey: cannot convert hostname to netname\n"); 117218631Smiwi exit(1); 118168055Spav } 119168161Sphilip } else { 120168054Sflz if (user2netname(name, uid, NULL) == 0) { 121168208Sitetcu (void)fprintf(stderr, 122168295Sleeym "chkey: cannot convert username to netname\n"); 123168295Sleeym exit(1); 124172158Sjkim } 125175205Sedwin } 126168939Stmclaugh (void)printf("Generating new key for %s.\n", name); 127176979Slippe 128218631Smiwi if (!force) { 129168068Serwin if (uid != 0) { 130168337Slwhsu#ifdef YPPASSWD 131175205Sedwin pw = ypgetpwuid(uid); 132234195Smadpilot#else 133168177Sgabor pw = getpwuid(uid); 134199480Smandree#endif 135199479Smandree if (pw == NULL) { 136168113Smarcus#ifdef YPPASSWD 137168918Sbrueffer (void)fprintf(stderr, 138220095Smartymac "No NIS password entry found: can't change key.\n"); 139168186Smat#else 140231275Smatthew (void)fprintf(stderr, 141168055Spav "No password entry found: can't change key.\n"); 142168098Skrion#endif 143168359Smm exit(1); 144168100Smnag } 145218631Smiwi } else { 146169036Snemoliu pw = getpwuid(0); 147168123Snetchild if (pw == NULL) { 148168177Sgabor (void)fprintf(stderr, 149168134Snork "No password entry found: can't change key.\n"); 150168084Sehaupt exit(1); 151168542Smiwi } 152171129Sobrien } 153236257Solivierd } 154171129Sobrien pass = getpass("Password:"); 155169253Sfjoe#ifdef YPPASSWD 156168939Stmclaugh if (!force) { 157168054Sflz if (strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd) != 0) { 158219614Spawel (void)fprintf(stderr, "Invalid password.\n"); 159190977Spgj exit(1); 160168098Skrion } 161180729Spgollucci } 162168108Srafan#else 163226351Srakuco force = 1; /* Make this mandatory */ 164206489Srene#endif 165227417Srm genkeys(public, secret, pass); 166180983Srnoland 167203046Sromain memcpy(crypt1, secret, HEXKEYBYTES); 168206532Ssahil memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); 169168098Skrion crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 170219730Ssbz xencrypt(crypt1, pass); 171227731Sscheidell 172168098Skrion if (force) { 173168098Skrion memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1); 174168055Spav xdecrypt(crypt2, getpass("Retype password:")); 175168068Serwin if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 || 176191885Sskreuzer memcmp(crypt2, secret, HEXKEYBYTES) != 0) { 177168939Stmclaugh (void)fprintf(stderr, "Password incorrect.\n"); 178234343Ssperber exit(1); 179168290Ssem } 180168667Sstefan } 181223090Sstephen 182213001Ssunpoet#ifdef YP 183218631Smiwi (void)printf("Sending key change request to %s...\n", master); 184212219Sswills#endif 185172276Stabthorpe status = setpublicmap(name, public, crypt1); 186168125Stdb if (status != 0) { 187170675Stimur#ifdef YP 188236348Stj (void)fprintf(stderr, 189192568Stota "%s: unable to update NIS database (%u): %s\n", 190169018Strasz self, status, yperr_string(status)); 191168225Strhodes#else 192168186Smat (void)fprintf(stderr, 193168061Sahze "%s: unable to update publickey database\n", self); 194231128Suqs#endif 195168069Sgarga exit(1); 196216401Swen } 197180728Swxs 198168935Stmclaugh if (uid == 0) { 199195800Syzlin /* 200224071Szi * Root users store their key in /etc/$ROOTKEY so 201172158Sjkim * that they can auto reboot without having to be 202168054Sflz * around to type a password. Storing this in a file 203168054Sflz * is rather dubious: it should really be in the EEPROM 204168064Sflz * so it does not go over the net. 205168064Sflz */ 206168054Sflz int fd; 207168055Spav 208168055Spav fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 209168055Spav if (fd < 0) { 210168055Spav perror(ROOTKEY); 211168055Spav } else { 212182814Sjpaetzel char newline = '\n'; 213182814Sjpaetzel 214168055Spav if (write(fd, secret, strlen(secret)) < 0 || 215168057Sahze write(fd, &newline, sizeof(newline)) < 0) { 216168055Spav (void)fprintf(stderr, "%s: ", ROOTKEY); 217176979Slippe perror("write"); 218180729Spgollucci } 219176979Slippe } 220168919Sbrueffer } 221168667Sstefan 222168667Sstefan if (key_setsecret(secret) < 0) { 223171129Sobrien (void)printf("Unable to login with new secret key.\n"); 224171129Sobrien exit(1); 225226351Srakuco } 226226351Srakuco (void)printf("Done.\n"); 227225848Seadler exit(0); 228222817Sjlaffaye /* NOTREACHED */ 229222817Sjlaffaye} 230206034Sdecke 231234343Ssperberusage(name) 232231128Suqs char *name; 233206034Sdecke{ 234188837Sbeech (void)fprintf(stderr, "usage: %s [-f]\n", name); 235188837Sbeech exit(1); 236188837Sbeech /* NOTREACHED */ 237168939Stmclaugh} 238168939Stmclaugh 239168939Stmclaugh 240218631Smiwi/* 241218631Smiwi * Set the entry in the public key file 242168125Stdb */ 243168208Sitetcusetpublicmap(name, public, secret) 244168125Stdb char *name; 245168337Slwhsu char *public; 246172275Stabthorpe char *secret; 247168337Slwhsu{ 248228752Sjgh char pkent[1024]; 249234195Smadpilot 250228752Sjgh (void)sprintf(pkent,"%s:%s", public, secret); 251236348Stj#ifdef YP 252236348Stj return (yp_update(domain, PKMAP, YPOP_STORE, 253236343Sjase name, strlen(name), pkent, strlen(pkent))); 254236343Sjase#else 255234343Ssperber return (localupdate(name, PKFILE, YPOP_STORE, 256234343Ssperber strlen(name), name, strlen(pkent), pkent)); 257169036Snemoliu#endif 258168108Srafan} 259168108Srafan 260168186Smat#ifdef YPPASSWD 261168186Smatstruct passwd * 262232357Sakypgetpwuid(uid) 263236348Stj uid_t uid; 264232357Sak{ 265168938Scperciva char uidstr[10]; 266168068Serwin char *val; 267175205Sedwin int vallen; 268175205Sedwin static struct passwd pw; 269168068Serwin char *p; 270168072Sehaupt 271220182Smartymac (void)sprintf(uidstr, "%d", uid); 272168072Sehaupt if (yp_match(domain, "passwd.byuid", uidstr, strlen(uidstr), 273168274Ssem &val, &vallen) != 0) { 274168225Strhodes return (NULL); 275168225Strhodes } 276173254Sbrix p = index(val, ':'); 277168068Serwin if (p == NULL) { 278168059Sgabor return (NULL); 279168068Serwin } 280168068Serwin pw.pw_passwd = p + 1; 281168068Serwin p = index(pw.pw_passwd, ':'); 282168059Sgabor if (p == NULL) { 283168354Sdanfe return (NULL); 284216282Sflo } 285168098Skrion *p = 0; 286169251Sfjoe return (&pw); 287168098Skrion} 288236343Sjase#endif /* YPPASSWD */ 289236343Sjase