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 97231994Skevlo#ifdef YPPASSWD 98231994Skevlo char *cryptpw; 99231994Skevlo#endif 10026240Swpaul 101102497Scharnier while ((ch = getopt(argc, argv, "f")) != -1) 102102497Scharnier switch(ch) { 10326240Swpaul case 'f': 10426240Swpaul force = 1; 10526240Swpaul break; 10626240Swpaul default: 107102497Scharnier usage(); 10826240Swpaul } 109102497Scharnier argc -= optind; 110102497Scharnier argv += optind; 11126240Swpaul 112102497Scharnier if (argc != 0) 113102497Scharnier usage(); 114102497Scharnier 11526240Swpaul#ifdef YP 11626240Swpaul (void)yp_get_default_domain(&domain); 117102497Scharnier if (yp_master(domain, PKMAP, &master) != 0) 118102497Scharnier errx(1, "can't find master of publickey database"); 11926240Swpaul#endif 12026240Swpaul uid = getuid() /*geteuid()*/; 12126240Swpaul if (uid == 0) { 122102497Scharnier if (host2netname(name, NULL, NULL) == 0) 123102497Scharnier errx(1, "cannot convert hostname to netname"); 12426240Swpaul } else { 125102497Scharnier if (user2netname(name, uid, NULL) == 0) 126102497Scharnier errx(1, "cannot convert username to netname"); 12726240Swpaul } 12826240Swpaul (void)printf("Generating new key for %s.\n", name); 12926240Swpaul 13026240Swpaul if (!force) { 13126240Swpaul if (uid != 0) { 13226240Swpaul#ifdef YPPASSWD 13326240Swpaul pw = ypgetpwuid(uid); 13426240Swpaul#else 13526240Swpaul pw = getpwuid(uid); 13626240Swpaul#endif 13726240Swpaul if (pw == NULL) { 13826240Swpaul#ifdef YPPASSWD 139102497Scharnier errx(1, 140102497Scharnier "no NIS password entry found: can't change key"); 14126240Swpaul#else 142102497Scharnier errx(1, 143102497Scharnier "no password entry found: can't change key"); 14426240Swpaul#endif 14526240Swpaul } 14626240Swpaul } else { 14726240Swpaul pw = getpwuid(0); 148102497Scharnier if (pw == NULL) 149102497Scharnier errx(1, "no password entry found: can't change key"); 15026240Swpaul } 15126240Swpaul } 15226240Swpaul pass = getpass("Password:"); 15326240Swpaul#ifdef YPPASSWD 15426240Swpaul if (!force) { 155231994Skevlo cryptpw = crypt(pass, pw->pw_passwd); 156231994Skevlo if (cryptpw == NULL || strcmp(cryptpw, pw->pw_passwd) != 0) 157102497Scharnier errx(1, "invalid password"); 15826240Swpaul } 15926240Swpaul#else 16026240Swpaul force = 1; /* Make this mandatory */ 16126240Swpaul#endif 16226240Swpaul genkeys(public, secret, pass); 16326240Swpaul 16426240Swpaul memcpy(crypt1, secret, HEXKEYBYTES); 16526240Swpaul memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); 16626240Swpaul crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 16726240Swpaul xencrypt(crypt1, pass); 16826240Swpaul 16926240Swpaul if (force) { 17026240Swpaul memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1); 17126240Swpaul xdecrypt(crypt2, getpass("Retype password:")); 172102497Scharnier if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 173102497Scharnier || memcmp(crypt2, secret, HEXKEYBYTES) != 0) 174102497Scharnier errx(1, "password incorrect"); 17526240Swpaul } 17626240Swpaul 17726240Swpaul#ifdef YP 17826240Swpaul (void)printf("Sending key change request to %s...\n", master); 17926240Swpaul#endif 18026240Swpaul status = setpublicmap(name, public, crypt1); 18126240Swpaul if (status != 0) { 18226240Swpaul#ifdef YP 183102497Scharnier errx(1, "unable to update NIS database (%u): %s", 184102497Scharnier status, yperr_string(status)); 18526240Swpaul#else 186102497Scharnier errx(1, "unable to update publickey database"); 18726240Swpaul#endif 18826240Swpaul } 18926240Swpaul 19026240Swpaul if (uid == 0) { 19126240Swpaul /* 19226240Swpaul * Root users store their key in /etc/$ROOTKEY so 19326240Swpaul * that they can auto reboot without having to be 19426240Swpaul * around to type a password. Storing this in a file 19526240Swpaul * is rather dubious: it should really be in the EEPROM 19626240Swpaul * so it does not go over the net. 19726240Swpaul */ 19826240Swpaul int fd; 19926240Swpaul 20026240Swpaul fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 20126240Swpaul if (fd < 0) { 202102497Scharnier warn("%s", ROOTKEY); 20326240Swpaul } else { 20426240Swpaul char newline = '\n'; 20526240Swpaul 20626240Swpaul if (write(fd, secret, strlen(secret)) < 0 || 207102497Scharnier write(fd, &newline, sizeof(newline)) < 0) 208102497Scharnier warn("%s: write", ROOTKEY); 20926240Swpaul } 210215519Skevlo close(fd); 21126240Swpaul } 21226240Swpaul 213102497Scharnier if (key_setsecret(secret) < 0) 214102497Scharnier errx(1, "unable to login with new secret key"); 21526240Swpaul (void)printf("Done.\n"); 21626240Swpaul exit(0); 21726240Swpaul /* NOTREACHED */ 21826240Swpaul} 21926240Swpaul 22087240Smarkmstatic void 221102497Scharnierusage(void) 22226240Swpaul{ 223102497Scharnier (void)fprintf(stderr, "usage: chkey [-f]\n"); 22426240Swpaul exit(1); 22526240Swpaul /* NOTREACHED */ 22626240Swpaul} 22726240Swpaul 22826240Swpaul 22926240Swpaul/* 23026240Swpaul * Set the entry in the public key file 23126240Swpaul */ 23287240Smarkmint 233100814Sdwmalonesetpublicmap(char *name, char *public, char *secret) 23426240Swpaul{ 23526240Swpaul char pkent[1024]; 23626240Swpaul 23726240Swpaul (void)sprintf(pkent,"%s:%s", public, secret); 23826240Swpaul#ifdef YP 23926240Swpaul return (yp_update(domain, PKMAP, YPOP_STORE, 24026240Swpaul name, strlen(name), pkent, strlen(pkent))); 24126240Swpaul#else 24226240Swpaul return (localupdate(name, PKFILE, YPOP_STORE, 24326240Swpaul strlen(name), name, strlen(pkent), pkent)); 24426240Swpaul#endif 24526240Swpaul} 24626240Swpaul 24726240Swpaul#ifdef YPPASSWD 24826240Swpaulstruct passwd * 249100814Sdwmaloneypgetpwuid(uid_t uid) 25026240Swpaul{ 25126240Swpaul char uidstr[10]; 25226240Swpaul char *val; 25326240Swpaul int vallen; 25426240Swpaul static struct passwd pw; 25526240Swpaul char *p; 25626240Swpaul 25726240Swpaul (void)sprintf(uidstr, "%d", uid); 25826240Swpaul if (yp_match(domain, "passwd.byuid", uidstr, strlen(uidstr), 25926240Swpaul &val, &vallen) != 0) { 26026240Swpaul return (NULL); 26126240Swpaul } 262102497Scharnier p = strchr(val, ':'); 26326240Swpaul if (p == NULL) { 26426240Swpaul return (NULL); 26526240Swpaul } 26626240Swpaul pw.pw_passwd = p + 1; 267102497Scharnier p = strchr(pw.pw_passwd, ':'); 26826240Swpaul if (p == NULL) { 26926240Swpaul return (NULL); 27026240Swpaul } 27126240Swpaul *p = 0; 27226240Swpaul return (&pw); 27326240Swpaul} 27426240Swpaul#endif /* YPPASSWD */ 275