126240Swpaul/* 226240Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326240Swpaul * unrestricted use provided that this legend is included on all tape 426240Swpaul * media and as a part of the software program in whole or part. Users 526240Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626240Swpaul * to license or distribute it to anyone else except as part of a product or 726240Swpaul * program developed by the user or with the express written consent of 826240Swpaul * Sun Microsystems, Inc. 926240Swpaul * 1026240Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11102497Scharnier * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1226240Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1326240Swpaul * 1426240Swpaul * Sun RPC is provided with no support and without any obligation on the 1526240Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1626240Swpaul * modification or enhancement. 1726240Swpaul * 1826240Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1926240Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2026240Swpaul * OR ANY PART THEREOF. 2126240Swpaul * 2226240Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2326240Swpaul * or profits or other special, indirect and consequential damages, even if 2426240Swpaul * Sun has been advised of the possibility of such damages. 2526240Swpaul * 2626240Swpaul * Sun Microsystems, Inc. 2726240Swpaul * 2550 Garcia Avenue 2826240Swpaul * Mountain View, California 94043 2926240Swpaul */ 3087240Smarkm 3187628Sdwmalone#if 0 3287628Sdwmalone#ifndef lint 3387628Sdwmalonestatic char sccsid[] = "@(#)chkey.c 1.7 91/03/11 Copyr 1986 Sun Micro"; 3487628Sdwmalone#endif 3587628Sdwmalone#endif 3687628Sdwmalone 3787240Smarkm#include <sys/cdefs.h> 3887240Smarkm__FBSDID("$FreeBSD$"); 3987240Smarkm 4026240Swpaul/* 4126240Swpaul * Copyright (C) 1986, Sun Microsystems, Inc. 4226240Swpaul */ 4326240Swpaul 4426240Swpaul/* 4526240Swpaul * Command to change one's public key in the public key database 4626240Swpaul */ 4726240Swpaul#include <rpc/rpc.h> 4826240Swpaul#include <rpc/key_prot.h> 4926240Swpaul#ifdef YP 5026240Swpaul#include <rpcsvc/yp_prot.h> 5126240Swpaul#include <rpcsvc/ypclnt.h> 5226240Swpaul#else 5326240Swpaul#define YPOP_STORE 4 5426240Swpaul#endif 5587240Smarkm#include <sys/fcntl.h> 56102497Scharnier#include <err.h> 5726240Swpaul#include <pwd.h> 5887240Smarkm#include <stdio.h> 59100814Sdwmalone#include <stdlib.h> 6026240Swpaul#include <string.h> 6187240Smarkm#include <unistd.h> 6226240Swpaul 6387240Smarkm#include "extern.h" 6487240Smarkm 6526240Swpaul#ifdef YPPASSWD 6687240Smarkmstruct passwd *ypgetpwuid(uid_t); 6726240Swpaul#endif 6826240Swpaul 6926240Swpaul#ifdef YP 7026240Swpaulstatic char *domain; 7126240Swpaulstatic char PKMAP[] = "publickey.byname"; 7226240Swpaul#else 7326240Swpaulstatic char PKFILE[] = "/etc/publickey"; 7426240Swpaul#endif /* YP */ 7526240Swpaulstatic char ROOTKEY[] = "/etc/.rootkey"; 7626240Swpaul 77102497Scharnierstatic void usage(void); 7887240Smarkmextern int yp_update(char *, char *, int, char *, size_t, char *, size_t); 7987240Smarkm 8087240Smarkmint 81100814Sdwmalonemain(int argc, char **argv) 8226240Swpaul{ 8326240Swpaul char name[MAXNETNAMELEN+1]; 8426240Swpaul char public[HEXKEYBYTES + 1]; 8526240Swpaul char secret[HEXKEYBYTES + 1]; 8626240Swpaul char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 8726240Swpaul char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 8826240Swpaul int status; 8926240Swpaul char *pass; 9026240Swpaul struct passwd *pw; 9126240Swpaul uid_t uid; 9226240Swpaul int force = 0; 93102497Scharnier int ch; 9426240Swpaul#ifdef YP 9526240Swpaul char *master; 9626240Swpaul#endif 9726240Swpaul 98102497Scharnier while ((ch = getopt(argc, argv, "f")) != -1) 99102497Scharnier switch(ch) { 10026240Swpaul case 'f': 10126240Swpaul force = 1; 10226240Swpaul break; 10326240Swpaul default: 104102497Scharnier usage(); 10526240Swpaul } 106102497Scharnier argc -= optind; 107102497Scharnier argv += optind; 10826240Swpaul 109102497Scharnier if (argc != 0) 110102497Scharnier usage(); 111102497Scharnier 11226240Swpaul#ifdef YP 11326240Swpaul (void)yp_get_default_domain(&domain); 114102497Scharnier if (yp_master(domain, PKMAP, &master) != 0) 115102497Scharnier errx(1, "can't find master of publickey database"); 11626240Swpaul#endif 11726240Swpaul uid = getuid() /*geteuid()*/; 11826240Swpaul if (uid == 0) { 119102497Scharnier if (host2netname(name, NULL, NULL) == 0) 120102497Scharnier errx(1, "cannot convert hostname to netname"); 12126240Swpaul } else { 122102497Scharnier if (user2netname(name, uid, NULL) == 0) 123102497Scharnier errx(1, "cannot convert username to netname"); 12426240Swpaul } 12526240Swpaul (void)printf("Generating new key for %s.\n", name); 12626240Swpaul 12726240Swpaul if (!force) { 12826240Swpaul if (uid != 0) { 12926240Swpaul#ifdef YPPASSWD 13026240Swpaul pw = ypgetpwuid(uid); 13126240Swpaul#else 13226240Swpaul pw = getpwuid(uid); 13326240Swpaul#endif 13426240Swpaul if (pw == NULL) { 13526240Swpaul#ifdef YPPASSWD 136102497Scharnier errx(1, 137102497Scharnier "no NIS password entry found: can't change key"); 13826240Swpaul#else 139102497Scharnier errx(1, 140102497Scharnier "no password entry found: can't change key"); 14126240Swpaul#endif 14226240Swpaul } 14326240Swpaul } else { 14426240Swpaul pw = getpwuid(0); 145102497Scharnier if (pw == NULL) 146102497Scharnier errx(1, "no password entry found: can't change key"); 14726240Swpaul } 14826240Swpaul } 14926240Swpaul pass = getpass("Password:"); 15026240Swpaul#ifdef YPPASSWD 15126240Swpaul if (!force) { 152102497Scharnier if (strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd) != 0) 153102497Scharnier errx(1, "invalid password"); 15426240Swpaul } 15526240Swpaul#else 15626240Swpaul force = 1; /* Make this mandatory */ 15726240Swpaul#endif 15826240Swpaul genkeys(public, secret, pass); 15926240Swpaul 16026240Swpaul memcpy(crypt1, secret, HEXKEYBYTES); 16126240Swpaul memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); 16226240Swpaul crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 16326240Swpaul xencrypt(crypt1, pass); 16426240Swpaul 16526240Swpaul if (force) { 16626240Swpaul memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1); 16726240Swpaul xdecrypt(crypt2, getpass("Retype password:")); 168102497Scharnier if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 169102497Scharnier || memcmp(crypt2, secret, HEXKEYBYTES) != 0) 170102497Scharnier errx(1, "password incorrect"); 17126240Swpaul } 17226240Swpaul 17326240Swpaul#ifdef YP 17426240Swpaul (void)printf("Sending key change request to %s...\n", master); 17526240Swpaul#endif 17626240Swpaul status = setpublicmap(name, public, crypt1); 17726240Swpaul if (status != 0) { 17826240Swpaul#ifdef YP 179102497Scharnier errx(1, "unable to update NIS database (%u): %s", 180102497Scharnier status, yperr_string(status)); 18126240Swpaul#else 182102497Scharnier errx(1, "unable to update publickey database"); 18326240Swpaul#endif 18426240Swpaul } 18526240Swpaul 18626240Swpaul if (uid == 0) { 18726240Swpaul /* 18826240Swpaul * Root users store their key in /etc/$ROOTKEY so 18926240Swpaul * that they can auto reboot without having to be 19026240Swpaul * around to type a password. Storing this in a file 19126240Swpaul * is rather dubious: it should really be in the EEPROM 19226240Swpaul * so it does not go over the net. 19326240Swpaul */ 19426240Swpaul int fd; 19526240Swpaul 19626240Swpaul fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 19726240Swpaul if (fd < 0) { 198102497Scharnier warn("%s", ROOTKEY); 19926240Swpaul } else { 20026240Swpaul char newline = '\n'; 20126240Swpaul 20226240Swpaul if (write(fd, secret, strlen(secret)) < 0 || 203102497Scharnier write(fd, &newline, sizeof(newline)) < 0) 204102497Scharnier warn("%s: write", ROOTKEY); 20526240Swpaul } 206215519Skevlo close(fd); 20726240Swpaul } 20826240Swpaul 209102497Scharnier if (key_setsecret(secret) < 0) 210102497Scharnier errx(1, "unable to login with new secret key"); 21126240Swpaul (void)printf("Done.\n"); 21226240Swpaul exit(0); 21326240Swpaul /* NOTREACHED */ 21426240Swpaul} 21526240Swpaul 21687240Smarkmstatic void 217102497Scharnierusage(void) 21826240Swpaul{ 219102497Scharnier (void)fprintf(stderr, "usage: chkey [-f]\n"); 22026240Swpaul exit(1); 22126240Swpaul /* NOTREACHED */ 22226240Swpaul} 22326240Swpaul 22426240Swpaul 22526240Swpaul/* 22626240Swpaul * Set the entry in the public key file 22726240Swpaul */ 22887240Smarkmint 229100814Sdwmalonesetpublicmap(char *name, char *public, char *secret) 23026240Swpaul{ 23126240Swpaul char pkent[1024]; 23226240Swpaul 23326240Swpaul (void)sprintf(pkent,"%s:%s", public, secret); 23426240Swpaul#ifdef YP 23526240Swpaul return (yp_update(domain, PKMAP, YPOP_STORE, 23626240Swpaul name, strlen(name), pkent, strlen(pkent))); 23726240Swpaul#else 23826240Swpaul return (localupdate(name, PKFILE, YPOP_STORE, 23926240Swpaul strlen(name), name, strlen(pkent), pkent)); 24026240Swpaul#endif 24126240Swpaul} 24226240Swpaul 24326240Swpaul#ifdef YPPASSWD 24426240Swpaulstruct passwd * 245100814Sdwmaloneypgetpwuid(uid_t uid) 24626240Swpaul{ 24726240Swpaul char uidstr[10]; 24826240Swpaul char *val; 24926240Swpaul int vallen; 25026240Swpaul static struct passwd pw; 25126240Swpaul char *p; 25226240Swpaul 25326240Swpaul (void)sprintf(uidstr, "%d", uid); 25426240Swpaul if (yp_match(domain, "passwd.byuid", uidstr, strlen(uidstr), 25526240Swpaul &val, &vallen) != 0) { 25626240Swpaul return (NULL); 25726240Swpaul } 258102497Scharnier p = strchr(val, ':'); 25926240Swpaul if (p == NULL) { 26026240Swpaul return (NULL); 26126240Swpaul } 26226240Swpaul pw.pw_passwd = p + 1; 263102497Scharnier p = strchr(pw.pw_passwd, ':'); 26426240Swpaul if (p == NULL) { 26526240Swpaul return (NULL); 26626240Swpaul } 26726240Swpaul *p = 0; 26826240Swpaul return (&pw); 26926240Swpaul} 27026240Swpaul#endif /* YPPASSWD */ 271