126238Swpaul/* 226238Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326238Swpaul * unrestricted use provided that this legend is included on all tape 426238Swpaul * media and as a part of the software program in whole or part. Users 526238Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626238Swpaul * to license or distribute it to anyone else except as part of a product or 726238Swpaul * program developed by the user or with the express written consent of 826238Swpaul * Sun Microsystems, Inc. 926238Swpaul * 1026238Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1126238Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1226238Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1326238Swpaul * 1426238Swpaul * Sun RPC is provided with no support and without any obligation on the 1526238Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1626238Swpaul * modification or enhancement. 1726238Swpaul * 1826238Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1926238Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2026238Swpaul * OR ANY PART THEREOF. 2126238Swpaul * 2226238Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2326238Swpaul * or profits or other special, indirect and consequential damages, even if 2426238Swpaul * Sun has been advised of the possibility of such damages. 2526238Swpaul * 2626238Swpaul * Sun Microsystems, Inc. 2726238Swpaul * 2550 Garcia Avenue 2826238Swpaul * Mountain View, California 94043 2926238Swpaul */ 3095633Smarkm 3126238Swpaul#if !defined(lint) && defined(SCCSIDS) 3227754Scharnier#if 0 3326238Swpaulstatic char sccsid[] = "@(#)newkey.c 1.8 91/03/11 Copyr 1986 Sun Micro"; 3426238Swpaul#endif 3527754Scharnier#endif 3626238Swpaul 3726238Swpaul/* 3826238Swpaul * Copyright (C) 1986, Sun Microsystems, Inc. 3926238Swpaul */ 4026238Swpaul 4126238Swpaul/* 4226238Swpaul * Administrative tool to add a new user to the publickey database 4326238Swpaul */ 4495633Smarkm#include <sys/cdefs.h> 4595633Smarkm__FBSDID("$FreeBSD$"); 4695633Smarkm 4787204Smarkm#include <sys/types.h> 4887204Smarkm#include <sys/time.h> 4987204Smarkm#include <sys/resource.h> 5095633Smarkm 5126238Swpaul#include <rpc/rpc.h> 5226238Swpaul#include <rpc/key_prot.h> 5395633Smarkm 5426238Swpaul#ifdef YP 5587204Smarkm#include <sys/wait.h> 5626238Swpaul#include <rpcsvc/yp_prot.h> 5726238Swpaul#include <rpcsvc/ypclnt.h> 5826238Swpaul#include <netdb.h> 5926238Swpaul#endif /* YP */ 6095633Smarkm 6187204Smarkm#include <err.h> 6226238Swpaul#include <pwd.h> 6387204Smarkm#include <stdio.h> 64141481Sstefanf#include <stdlib.h> 6526238Swpaul#include <string.h> 6627754Scharnier#include <unistd.h> 6726238Swpaul 6887204Smarkm#include "extern.h" 6987204Smarkm 7026238Swpaul#ifdef YP 7126238Swpaul#define MAXMAPNAMELEN 256 7226238Swpaul#else 7326238Swpaul#define YPOP_CHANGE 1 /* change, do not add */ 7426238Swpaul#define YPOP_INSERT 2 /* add, do not change */ 7526238Swpaul#define YPOP_DELETE 3 /* delete this entry */ 7626238Swpaul#define YPOP_STORE 4 /* add, or change */ 7726238Swpaul#define ERR_ACCESS 1 7826238Swpaul#define ERR_MALLOC 2 7926238Swpaul#define ERR_READ 3 8026238Swpaul#define ERR_WRITE 4 8126238Swpaul#define ERR_DBASE 5 8226238Swpaul#define ERR_KEY 6 8326238Swpaul#endif 8426238Swpaul 8526238Swpaul#ifdef YP 8626238Swpaulstatic char YPDBPATH[]="/var/yp"; 8726238Swpaulstatic char PKMAP[] = "publickey.byname"; 8826238Swpaul#else 8926238Swpaulstatic char PKFILE[] = "/etc/publickey"; 90189169Sedstatic const char *err_string(int); 9126238Swpaul#endif /* YP */ 9226238Swpaul 9392921Simpstatic void usage(void); 9427754Scharnier 9527754Scharnierint 9695633Smarkmmain(int argc, char *argv[]) 9726238Swpaul{ 9826238Swpaul char name[MAXNETNAMELEN + 1]; 9926238Swpaul char public[HEXKEYBYTES + 1]; 10026238Swpaul char secret[HEXKEYBYTES + 1]; 10126238Swpaul char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 10226238Swpaul char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 10326238Swpaul int status; 10426238Swpaul char *pass; 10526238Swpaul struct passwd *pw; 10626238Swpaul#ifdef undef 10726238Swpaul struct hostent *h; 10826238Swpaul#endif 10926238Swpaul 11026238Swpaul if (argc != 3 || !(strcmp(argv[1], "-u") == 0 || 11126238Swpaul strcmp(argv[1], "-h") == 0)) { 11227754Scharnier usage(); 11326238Swpaul } 11427754Scharnier if (geteuid() != 0) 11527754Scharnier errx(1, "must be superuser"); 11626238Swpaul 11726238Swpaul#ifdef YP 11827754Scharnier if (chdir(YPDBPATH) < 0) 11927754Scharnier warn("cannot chdir to %s", YPDBPATH); 12026238Swpaul#endif /* YP */ 12126238Swpaul if (strcmp(argv[1], "-u") == 0) { 12226238Swpaul pw = getpwnam(argv[2]); 12327754Scharnier if (pw == NULL) 12427754Scharnier errx(1, "unknown user: %s", argv[2]); 12526238Swpaul (void)user2netname(name, (int)pw->pw_uid, (char *)NULL); 12626238Swpaul } else { 12726238Swpaul#ifdef undef 12826238Swpaul h = gethostbyname(argv[2]); 12927754Scharnier if (h == NULL) 13027754Scharnier errx(1, "unknown host: %s", argv[1]); 13126238Swpaul (void)host2netname(name, h->h_name, (char *)NULL); 13226238Swpaul#else 13326238Swpaul (void)host2netname(name, argv[2], (char *)NULL); 13426238Swpaul#endif 13526238Swpaul } 13626238Swpaul 13726238Swpaul (void)printf("Adding new key for %s.\n", name); 13826238Swpaul pass = getpass("New password:"); 13926238Swpaul genkeys(public, secret, pass); 14026238Swpaul 14126238Swpaul memcpy(crypt1, secret, HEXKEYBYTES); 14226238Swpaul memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); 14326238Swpaul crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 14426238Swpaul xencrypt(crypt1, pass); 14526238Swpaul 14626238Swpaul memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1); 14726238Swpaul xdecrypt(crypt2, getpass("Retype password:")); 14826238Swpaul if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 || 14927754Scharnier memcmp(crypt2, secret, HEXKEYBYTES) != 0) 15027754Scharnier errx(1, "password incorrect"); 15126238Swpaul 15226238Swpaul#ifdef YP 15326238Swpaul (void)printf("Please wait for the database to get updated...\n"); 15426238Swpaul#endif 15527754Scharnier if ((status = setpublicmap(name, public, crypt1))) { 15626238Swpaul#ifdef YP 15727754Scharnier errx(1, "unable to update NIS database (%u): %s", 15827754Scharnier status, yperr_string(status)); 15926238Swpaul#else 16027754Scharnier errx(1, "unable to update publickey database (%u): %s", 16127754Scharnier status, err_string(status)); 16226238Swpaul#endif 16326238Swpaul } 16426238Swpaul (void)printf("Your new key has been successfully stored away.\n"); 16526238Swpaul exit(0); 16626238Swpaul /* NOTREACHED */ 16726238Swpaul} 16826238Swpaul 16927754Scharnierstatic void 17095633Smarkmusage(void) 17127754Scharnier{ 17227754Scharnier (void)fprintf(stderr, "%s\n%s\n", 173146466Sru "usage: newkey -h hostname", 174146466Sru " newkey -u username"); 17527754Scharnier exit(1); 17627754Scharnier} 17727754Scharnier 17826238Swpaul/* 17926238Swpaul * Set the entry in the public key file 18026238Swpaul */ 18187204Smarkmint 18295633Smarkmsetpublicmap(char *name, char *public, char *secret) 18326238Swpaul{ 18426238Swpaul char pkent[1024]; 18526238Swpaul 18626238Swpaul (void)sprintf(pkent, "%s:%s", public, secret); 18726238Swpaul#ifdef YP 18826238Swpaul return (mapupdate(name, PKMAP, YPOP_STORE, 18926238Swpaul strlen(name), name, strlen(pkent), pkent)); 19026238Swpaul#else 19126238Swpaul return (localupdate(name, PKFILE, YPOP_STORE, 19226238Swpaul strlen(name), name, strlen(pkent), pkent)); 19326238Swpaul#endif 19426238Swpaul } 19526238Swpaul 19626238Swpaul#ifndef YP 19726238Swpaul /* 19826238Swpaul * This returns a pointer to an error message string appropriate 19926238Swpaul * to an input error code. An input value of zero will return 20026238Swpaul * a success message. 20126238Swpaul */ 202189169Sedstatic const char * 20395633Smarkmerr_string(int code) 20426238Swpaul{ 205189169Sed const char *pmesg; 20626238Swpaul 20726238Swpaul switch (code) { 20826238Swpaul case 0: 20926238Swpaul pmesg = "update operation succeeded"; 21026238Swpaul break; 21126238Swpaul case ERR_KEY: 21226238Swpaul pmesg = "no such key in file"; 21326238Swpaul break; 21426238Swpaul case ERR_READ: 21526238Swpaul pmesg = "cannot read the database"; 21626238Swpaul break; 21726238Swpaul case ERR_WRITE: 21826238Swpaul pmesg = "cannot write to the database"; 21926238Swpaul break; 22026238Swpaul case ERR_DBASE: 22126238Swpaul pmesg = "cannot update database"; 22226238Swpaul break; 22326238Swpaul case ERR_ACCESS: 22426238Swpaul pmesg = "permission denied"; 22526238Swpaul break; 22626238Swpaul case ERR_MALLOC: 22726238Swpaul pmesg = "malloc failed"; 22826238Swpaul break; 22926238Swpaul default: 23026238Swpaul pmesg = "unknown error"; 23126238Swpaul break; 23226238Swpaul } 23326238Swpaul return (pmesg); 23426238Swpaul} 23526238Swpaul#endif 236