1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include <assert.h> 43*7c478bd9Sstevel@tonic-gate #include <stdio.h> 44*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 45*7c478bd9Sstevel@tonic-gate #include <string.h> 46*7c478bd9Sstevel@tonic-gate #include <pwd.h> 47*7c478bd9Sstevel@tonic-gate #include <shadow.h> 48*7c478bd9Sstevel@tonic-gate #include <crypt.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 50*7c478bd9Sstevel@tonic-gate #include <unistd.h> 51*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 52*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h> 53*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h> 54*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nis_dhext.h> 55*7c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 56*7c478bd9Sstevel@tonic-gate #include <nsswitch.h> 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate #define PK_FILES 1 59*7c478bd9Sstevel@tonic-gate #define PK_YP 2 60*7c478bd9Sstevel@tonic-gate #define PK_NISPLUS 3 61*7c478bd9Sstevel@tonic-gate #define PK_LDAP 4 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate #define CURMECH mechs[mcount] 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate static char CRED_TABLE[] = "cred.org_dir"; 66*7c478bd9Sstevel@tonic-gate static char PKMAP[] = "publickey.byname"; 67*7c478bd9Sstevel@tonic-gate static char PKFILE[] = "/etc/publickey"; 68*7c478bd9Sstevel@tonic-gate #define MAXHOSTNAMELEN 256 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate #define ROOTKEY_FILE "/etc/.rootkey" 71*7c478bd9Sstevel@tonic-gate #define ROOTKEY_FILE_BACKUP "/etc/.rootkey.bak" 72*7c478bd9Sstevel@tonic-gate #define MAXROOTKEY_LINE_LEN 4224 /* Good upto 16384-bit keys */ 73*7c478bd9Sstevel@tonic-gate #define MAXROOTKEY_LEN 4096 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate /* Should last up to 16384-bit keys */ 76*7c478bd9Sstevel@tonic-gate #define MAXPKENTLEN 8500 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate bool_t makenew = TRUE; /* Make new keys or reencrypt existing */ 79*7c478bd9Sstevel@tonic-gate bool_t specmech = FALSE; /* Specific mechs requested */ 80*7c478bd9Sstevel@tonic-gate bool_t force = FALSE; 81*7c478bd9Sstevel@tonic-gate int dest_service = 0; /* To which nameservice do we store key(s) */ 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate char *program_name; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate mechanism_t **mechs = NULL; /* List of DH mechanisms */ 86*7c478bd9Sstevel@tonic-gate char **plist = NULL; /* List of public key(s) */ 87*7c478bd9Sstevel@tonic-gate char **slist = NULL; /* List of secret key(s) */ 88*7c478bd9Sstevel@tonic-gate char **clist = NULL; /* List of encrypted secret key(s) */ 89*7c478bd9Sstevel@tonic-gate int numspecmech = 0; /* Number of mechanisms specified */ 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate struct passwd *pw = NULL; /* passwd entry of user */ 92*7c478bd9Sstevel@tonic-gate struct spwd *spw = NULL; /* shadow entry of user */ 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate char *netname = NULL; /* RPC netname of user */ 95*7c478bd9Sstevel@tonic-gate char local_domain[MAXNETNAMELEN + 1]; 96*7c478bd9Sstevel@tonic-gate char *sec_domain = NULL; 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate char **rpc_pws = NULL; /* List of S-RPC passwords */ 99*7c478bd9Sstevel@tonic-gate int rpc_pw_count = 0; /* Number of passwords entered by user */ 100*7c478bd9Sstevel@tonic-gate char *login_pw = NULL; /* Unencrypted login password */ 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate static int add_cred_obj(nis_object *, char *); 103*7c478bd9Sstevel@tonic-gate static nis_error auth_exists(char *, char *, char *, char *); 104*7c478bd9Sstevel@tonic-gate static void cmp_passwd(); 105*7c478bd9Sstevel@tonic-gate static nis_error cred_exists(const char *, const char *, const char *); 106*7c478bd9Sstevel@tonic-gate static void encryptkeys(); 107*7c478bd9Sstevel@tonic-gate static void error_msg(); 108*7c478bd9Sstevel@tonic-gate static char *fgets_ignorenul(); 109*7c478bd9Sstevel@tonic-gate static void getpublics(); 110*7c478bd9Sstevel@tonic-gate static void getrpcpws(); 111*7c478bd9Sstevel@tonic-gate static void getsecrets(); 112*7c478bd9Sstevel@tonic-gate static void initkeylist(bool_t); 113*7c478bd9Sstevel@tonic-gate static void keylogin(keylen_t, algtype_t); 114*7c478bd9Sstevel@tonic-gate static void keylogin_des(); 115*7c478bd9Sstevel@tonic-gate static void makenewkeys(); 116*7c478bd9Sstevel@tonic-gate static int modify_cred_obj(nis_object *, char *); 117*7c478bd9Sstevel@tonic-gate static int nisplus_update(nis_name, char *, char *, char *); 118*7c478bd9Sstevel@tonic-gate static int sanity_checks(char *, char *, char *); 119*7c478bd9Sstevel@tonic-gate static void storekeys(); 120*7c478bd9Sstevel@tonic-gate static void usage(); 121*7c478bd9Sstevel@tonic-gate static void write_rootkey(); 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate extern char *get_nisplus_principal(char *, uid_t); 124*7c478bd9Sstevel@tonic-gate extern nis_object *init_entry(); 125*7c478bd9Sstevel@tonic-gate extern int get_pk_source(char *); 126*7c478bd9Sstevel@tonic-gate extern int localupdate(char *, char *, uint_t, char *); 127*7c478bd9Sstevel@tonic-gate extern int xencrypt(); 128*7c478bd9Sstevel@tonic-gate extern int xencrypt_g(); 129*7c478bd9Sstevel@tonic-gate extern int __gen_dhkeys(); 130*7c478bd9Sstevel@tonic-gate extern int key_setnet(); 131*7c478bd9Sstevel@tonic-gate extern int key_setnet_g(); 132*7c478bd9Sstevel@tonic-gate extern int key_secretkey_is_set_g(); 133*7c478bd9Sstevel@tonic-gate extern int __getnetnamebyuid(); 134*7c478bd9Sstevel@tonic-gate extern int getdomainname(); 135*7c478bd9Sstevel@tonic-gate extern int ldap_update(char *, char *, char *, char *, char *); 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate static void 139*7c478bd9Sstevel@tonic-gate error_msg() 140*7c478bd9Sstevel@tonic-gate { 141*7c478bd9Sstevel@tonic-gate if (sec_domain && *sec_domain && 142*7c478bd9Sstevel@tonic-gate strcasecmp(sec_domain, local_domain)) { 143*7c478bd9Sstevel@tonic-gate fprintf(stderr, 144*7c478bd9Sstevel@tonic-gate "The system default domain '%s' is different from the Secure RPC\n\ 145*7c478bd9Sstevel@tonic-gate domain %s where the key is stored. The Secure RPC domainname is\n\ 146*7c478bd9Sstevel@tonic-gate defined by the directory object stored in the /var/nis/NIS_COLD_START file.\n\ 147*7c478bd9Sstevel@tonic-gate If you need to change this Secure RPC domainname, please use the nisinit(1M)\n\ 148*7c478bd9Sstevel@tonic-gate command with the `-k` option.\n", local_domain, sec_domain); 149*7c478bd9Sstevel@tonic-gate exit(1); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate static void 155*7c478bd9Sstevel@tonic-gate usage() 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-p] [-s ldap | nisplus | nis | files] \n", 158*7c478bd9Sstevel@tonic-gate program_name); 159*7c478bd9Sstevel@tonic-gate exit(1); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* Encrypt secret key(s) with login_pw */ 164*7c478bd9Sstevel@tonic-gate static void 165*7c478bd9Sstevel@tonic-gate encryptkeys() 166*7c478bd9Sstevel@tonic-gate { 167*7c478bd9Sstevel@tonic-gate int mcount, ccount = 0; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate if (mechs) { 170*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 171*7c478bd9Sstevel@tonic-gate char *crypt = NULL; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (!xencrypt_g(slist[mcount], CURMECH->keylen, 174*7c478bd9Sstevel@tonic-gate CURMECH->algtype, login_pw, netname, 175*7c478bd9Sstevel@tonic-gate &crypt, TRUE)) { 176*7c478bd9Sstevel@tonic-gate /* Could not crypt key */ 177*7c478bd9Sstevel@tonic-gate crypt = NULL; 178*7c478bd9Sstevel@tonic-gate } else 179*7c478bd9Sstevel@tonic-gate ccount++; 180*7c478bd9Sstevel@tonic-gate clist[mcount] = crypt; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate } else { 183*7c478bd9Sstevel@tonic-gate char *crypt = NULL; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate if (!(crypt = 186*7c478bd9Sstevel@tonic-gate (char *)malloc(HEXKEYBYTES + KEYCHECKSUMSIZE + 1))) { 187*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 188*7c478bd9Sstevel@tonic-gate exit(1); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate memcpy(crypt, slist[0], HEXKEYBYTES); 192*7c478bd9Sstevel@tonic-gate memcpy(crypt + HEXKEYBYTES, slist[0], KEYCHECKSUMSIZE); 193*7c478bd9Sstevel@tonic-gate crypt[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 194*7c478bd9Sstevel@tonic-gate xencrypt(crypt, login_pw); 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate clist[0] = crypt; 197*7c478bd9Sstevel@tonic-gate ccount++; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate if (!ccount) { 201*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Could not encrypt any secret keys.\n", 202*7c478bd9Sstevel@tonic-gate program_name); 203*7c478bd9Sstevel@tonic-gate exit(1); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate /* Initialize the array of public, secret, and encrypted secret keys */ 209*7c478bd9Sstevel@tonic-gate static void 210*7c478bd9Sstevel@tonic-gate initkeylist(bool_t nomech) 211*7c478bd9Sstevel@tonic-gate { 212*7c478bd9Sstevel@tonic-gate int mcount; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate if (!nomech) { 215*7c478bd9Sstevel@tonic-gate assert(mechs && mechs[0]); 216*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++); 217*7c478bd9Sstevel@tonic-gate } else 218*7c478bd9Sstevel@tonic-gate mcount = 1; 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate if (!(plist = (char **)malloc(sizeof (char *) * mcount))) { 221*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 222*7c478bd9Sstevel@tonic-gate exit(1); 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate if (!(slist = (char **)malloc(sizeof (char *) * mcount))) { 225*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 226*7c478bd9Sstevel@tonic-gate exit(1); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate if (!(clist = (char **)malloc(sizeof (char *) * mcount))) { 229*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 230*7c478bd9Sstevel@tonic-gate exit(1); 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* Retrieve public key(s) */ 236*7c478bd9Sstevel@tonic-gate static void 237*7c478bd9Sstevel@tonic-gate getpublics() 238*7c478bd9Sstevel@tonic-gate { 239*7c478bd9Sstevel@tonic-gate int mcount; 240*7c478bd9Sstevel@tonic-gate int pcount = 0; 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate if (mechs) { 243*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 244*7c478bd9Sstevel@tonic-gate char *public; 245*7c478bd9Sstevel@tonic-gate size_t hexkeylen; 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate hexkeylen = ((CURMECH->keylen / 8) * 2) + 1; 248*7c478bd9Sstevel@tonic-gate if (!(public = (char *)malloc(hexkeylen))) { 249*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", 250*7c478bd9Sstevel@tonic-gate program_name); 251*7c478bd9Sstevel@tonic-gate exit(1); 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate if (!getpublickey_g(netname, CURMECH->keylen, 254*7c478bd9Sstevel@tonic-gate CURMECH->algtype, public, 255*7c478bd9Sstevel@tonic-gate hexkeylen)) { 256*7c478bd9Sstevel@tonic-gate /* Could not get public key */ 257*7c478bd9Sstevel@tonic-gate fprintf(stderr, 258*7c478bd9Sstevel@tonic-gate "Could not get %s public key.\n", 259*7c478bd9Sstevel@tonic-gate VALID_ALIAS(CURMECH->alias) ? 260*7c478bd9Sstevel@tonic-gate CURMECH->alias : ""); 261*7c478bd9Sstevel@tonic-gate free(public); 262*7c478bd9Sstevel@tonic-gate public = NULL; 263*7c478bd9Sstevel@tonic-gate } else 264*7c478bd9Sstevel@tonic-gate pcount++; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate plist[mcount] = public; 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate } else { 269*7c478bd9Sstevel@tonic-gate char *public; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (!(public = (char *)malloc(HEXKEYBYTES + 1))) { 272*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 273*7c478bd9Sstevel@tonic-gate exit(1); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate if (!getpublickey(netname, public)) { 276*7c478bd9Sstevel@tonic-gate free(public); 277*7c478bd9Sstevel@tonic-gate public = NULL; 278*7c478bd9Sstevel@tonic-gate } else 279*7c478bd9Sstevel@tonic-gate pcount++; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate plist[0] = public; 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate if (!pcount) { 285*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: cannot get any public keys for %s.\n", 286*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 287*7c478bd9Sstevel@tonic-gate error_msg(); 288*7c478bd9Sstevel@tonic-gate fprintf(stderr, 289*7c478bd9Sstevel@tonic-gate "Make sure that the public keys are stored in the domain %s.\n", 290*7c478bd9Sstevel@tonic-gate local_domain); 291*7c478bd9Sstevel@tonic-gate exit(1); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate /* Generate a new set of public/secret key pair(s) */ 297*7c478bd9Sstevel@tonic-gate static void 298*7c478bd9Sstevel@tonic-gate makenewkeys() 299*7c478bd9Sstevel@tonic-gate { 300*7c478bd9Sstevel@tonic-gate int mcount; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate if (mechs) { 303*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 304*7c478bd9Sstevel@tonic-gate char *public, *secret; 305*7c478bd9Sstevel@tonic-gate size_t hexkeylen; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate if (slist[mcount]) 308*7c478bd9Sstevel@tonic-gate free(slist[mcount]); 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate hexkeylen = ((CURMECH->keylen / 8) * 2) + 1; 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate if (!(public = malloc(hexkeylen))) { 313*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", 314*7c478bd9Sstevel@tonic-gate program_name); 315*7c478bd9Sstevel@tonic-gate exit(1); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate if (!(secret = malloc(hexkeylen))) { 318*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", 319*7c478bd9Sstevel@tonic-gate program_name); 320*7c478bd9Sstevel@tonic-gate exit(1); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate if (!(__gen_dhkeys_g(public, secret, CURMECH->keylen, 324*7c478bd9Sstevel@tonic-gate CURMECH->algtype, login_pw))) { 325*7c478bd9Sstevel@tonic-gate /* Could not generate key pair */ 326*7c478bd9Sstevel@tonic-gate fprintf(stderr, 327*7c478bd9Sstevel@tonic-gate "WARNING Could not generate key pair %s\n", 328*7c478bd9Sstevel@tonic-gate VALID_ALIAS(CURMECH->alias) ? 329*7c478bd9Sstevel@tonic-gate CURMECH->alias : ""); 330*7c478bd9Sstevel@tonic-gate free(public); 331*7c478bd9Sstevel@tonic-gate free(secret); 332*7c478bd9Sstevel@tonic-gate public = NULL; 333*7c478bd9Sstevel@tonic-gate secret = NULL; 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate plist[mcount] = public; 337*7c478bd9Sstevel@tonic-gate slist[mcount] = secret; 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate } else { 340*7c478bd9Sstevel@tonic-gate char *public, *secret; 341*7c478bd9Sstevel@tonic-gate if (slist[0]) 342*7c478bd9Sstevel@tonic-gate free(slist[0]); 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate if (!(public = malloc(HEXKEYBYTES + 1))) { 345*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 346*7c478bd9Sstevel@tonic-gate exit(1); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate if (!(secret = malloc(HEXKEYBYTES + 1))) { 349*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 350*7c478bd9Sstevel@tonic-gate exit(1); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate __gen_dhkeys(public, secret, login_pw); 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate plist[0] = public; 356*7c478bd9Sstevel@tonic-gate slist[0] = secret; 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* 362*7c478bd9Sstevel@tonic-gate * Make sure that the entered Secure-RPC password(s) match the login 363*7c478bd9Sstevel@tonic-gate * password 364*7c478bd9Sstevel@tonic-gate */ 365*7c478bd9Sstevel@tonic-gate static void 366*7c478bd9Sstevel@tonic-gate cmp_passwd() 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate char baseprompt[] = "Please enter the login password for"; 369*7c478bd9Sstevel@tonic-gate char prompt[BUFSIZ]; 370*7c478bd9Sstevel@tonic-gate char *en_login_pw = spw->sp_pwdp; 371*7c478bd9Sstevel@tonic-gate char *try_en_login_pw; 372*7c478bd9Sstevel@tonic-gate bool_t pwmatch = FALSE; 373*7c478bd9Sstevel@tonic-gate int done = 0, tries = 0, pcount; 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate snprintf(prompt, BUFSIZ, "%s %s:", baseprompt, pw->pw_name); 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate if (en_login_pw && (strlen(en_login_pw) != 0)) { 378*7c478bd9Sstevel@tonic-gate for (pcount = 0; pcount < rpc_pw_count; pcount++) { 379*7c478bd9Sstevel@tonic-gate char *try_en_rpc_pw; 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate try_en_rpc_pw = crypt(rpc_pws[pcount], en_login_pw); 382*7c478bd9Sstevel@tonic-gate if (strcmp(try_en_rpc_pw, en_login_pw) == 0) { 383*7c478bd9Sstevel@tonic-gate login_pw = rpc_pws[pcount]; 384*7c478bd9Sstevel@tonic-gate pwmatch = TRUE; 385*7c478bd9Sstevel@tonic-gate break; 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate if (!pwmatch) { 389*7c478bd9Sstevel@tonic-gate /* pw don't match */ 390*7c478bd9Sstevel@tonic-gate while (!done) { 391*7c478bd9Sstevel@tonic-gate /* ask for the pw */ 392*7c478bd9Sstevel@tonic-gate login_pw = getpass(prompt); 393*7c478bd9Sstevel@tonic-gate if (login_pw && strlen(login_pw)) { 394*7c478bd9Sstevel@tonic-gate /* pw was not empty */ 395*7c478bd9Sstevel@tonic-gate try_en_login_pw = crypt(login_pw, 396*7c478bd9Sstevel@tonic-gate en_login_pw); 397*7c478bd9Sstevel@tonic-gate /* compare the pw's */ 398*7c478bd9Sstevel@tonic-gate if (!(strcmp(try_en_login_pw, 399*7c478bd9Sstevel@tonic-gate en_login_pw))) { 400*7c478bd9Sstevel@tonic-gate /* pw was correct */ 401*7c478bd9Sstevel@tonic-gate return; 402*7c478bd9Sstevel@tonic-gate } else { 403*7c478bd9Sstevel@tonic-gate /* pw was wrong */ 404*7c478bd9Sstevel@tonic-gate if (tries++) { 405*7c478bd9Sstevel@tonic-gate /* Sorry */ 406*7c478bd9Sstevel@tonic-gate fprintf(stderr, 407*7c478bd9Sstevel@tonic-gate "Sorry.\n"); 408*7c478bd9Sstevel@tonic-gate exit(1); 409*7c478bd9Sstevel@tonic-gate } else { 410*7c478bd9Sstevel@tonic-gate /* Try again */ 411*7c478bd9Sstevel@tonic-gate snprintf(prompt, 412*7c478bd9Sstevel@tonic-gate BUFSIZ, 413*7c478bd9Sstevel@tonic-gate "Try again. %s %s:", 414*7c478bd9Sstevel@tonic-gate baseprompt, 415*7c478bd9Sstevel@tonic-gate pw->pw_name); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate } else { 419*7c478bd9Sstevel@tonic-gate /* pw was empty */ 420*7c478bd9Sstevel@tonic-gate if (tries++) { 421*7c478bd9Sstevel@tonic-gate /* Unchanged */ 422*7c478bd9Sstevel@tonic-gate fprintf(stderr, 423*7c478bd9Sstevel@tonic-gate "%s: key-pair(s) unchanged for %s.\n", 424*7c478bd9Sstevel@tonic-gate program_name, 425*7c478bd9Sstevel@tonic-gate pw->pw_name); 426*7c478bd9Sstevel@tonic-gate exit(1); 427*7c478bd9Sstevel@tonic-gate } else { 428*7c478bd9Sstevel@tonic-gate /* Need a password */ 429*7c478bd9Sstevel@tonic-gate snprintf(prompt, BUFSIZ, 430*7c478bd9Sstevel@tonic-gate "Need a password. %s %s:", 431*7c478bd9Sstevel@tonic-gate baseprompt, 432*7c478bd9Sstevel@tonic-gate pw->pw_name); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate /* pw match */ 438*7c478bd9Sstevel@tonic-gate return; 439*7c478bd9Sstevel@tonic-gate } else { 440*7c478bd9Sstevel@tonic-gate /* no pw found */ 441*7c478bd9Sstevel@tonic-gate fprintf(stderr, 442*7c478bd9Sstevel@tonic-gate "%s: no passwd found for %s in the shadow passwd entry.\n", 443*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 444*7c478bd9Sstevel@tonic-gate exit(1); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate } 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate /* Prompt the user for a Secure-RPC password and store it in a cache. */ 450*7c478bd9Sstevel@tonic-gate static void 451*7c478bd9Sstevel@tonic-gate getrpcpws(char *flavor) 452*7c478bd9Sstevel@tonic-gate { 453*7c478bd9Sstevel@tonic-gate char *cur_pw = NULL; 454*7c478bd9Sstevel@tonic-gate char prompt[BUFSIZ + 1]; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate if (flavor) 457*7c478bd9Sstevel@tonic-gate snprintf(prompt, BUFSIZ, 458*7c478bd9Sstevel@tonic-gate "Please enter the %s Secure-RPC password for %s:", 459*7c478bd9Sstevel@tonic-gate flavor, pw->pw_name); 460*7c478bd9Sstevel@tonic-gate else 461*7c478bd9Sstevel@tonic-gate snprintf(prompt, BUFSIZ, 462*7c478bd9Sstevel@tonic-gate "Please enter the Secure-RPC password for %s:", 463*7c478bd9Sstevel@tonic-gate pw->pw_name); 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate cur_pw = getpass(prompt); 466*7c478bd9Sstevel@tonic-gate if (!cur_pw) { 467*7c478bd9Sstevel@tonic-gate /* No changes */ 468*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n", 469*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 470*7c478bd9Sstevel@tonic-gate exit(1); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate rpc_pw_count++; 474*7c478bd9Sstevel@tonic-gate if (!(rpc_pws = 475*7c478bd9Sstevel@tonic-gate (char **)realloc(rpc_pws, sizeof (char *) * rpc_pw_count))) { 476*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Realloc failure.\n", program_name); 477*7c478bd9Sstevel@tonic-gate exit(1); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate rpc_pws[rpc_pw_count - 1] = cur_pw; 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate /* Retrieve the secret key(s) for the user and attempt to decrypt them */ 484*7c478bd9Sstevel@tonic-gate static void 485*7c478bd9Sstevel@tonic-gate getsecrets() 486*7c478bd9Sstevel@tonic-gate { 487*7c478bd9Sstevel@tonic-gate int mcount, scount = 0; 488*7c478bd9Sstevel@tonic-gate int tries = 0; 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate getrpcpws(NULL); 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate if (mechs) { 493*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 494*7c478bd9Sstevel@tonic-gate char *secret; 495*7c478bd9Sstevel@tonic-gate int pcount; 496*7c478bd9Sstevel@tonic-gate size_t hexkeylen; 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate hexkeylen = ((CURMECH->keylen / 8) * 2) + 1; 499*7c478bd9Sstevel@tonic-gate if (!(secret = (char *)calloc(hexkeylen, 500*7c478bd9Sstevel@tonic-gate sizeof (char)))) { 501*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", 502*7c478bd9Sstevel@tonic-gate program_name); 503*7c478bd9Sstevel@tonic-gate exit(1); 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate for (pcount = 0; pcount < rpc_pw_count; pcount++) { 507*7c478bd9Sstevel@tonic-gate if (!getsecretkey_g(netname, CURMECH->keylen, 508*7c478bd9Sstevel@tonic-gate CURMECH->algtype, secret, 509*7c478bd9Sstevel@tonic-gate hexkeylen, 510*7c478bd9Sstevel@tonic-gate rpc_pws[pcount])) 511*7c478bd9Sstevel@tonic-gate continue; 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate if (secret[0] == 0) 514*7c478bd9Sstevel@tonic-gate continue; 515*7c478bd9Sstevel@tonic-gate else 516*7c478bd9Sstevel@tonic-gate break; 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate tries = 0; 520*7c478bd9Sstevel@tonic-gate getsecrets_tryagain_g: 521*7c478bd9Sstevel@tonic-gate if (secret[0] == 0) { 522*7c478bd9Sstevel@tonic-gate if (!tries) { 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * No existing pw can decrypt 525*7c478bd9Sstevel@tonic-gate * secret key 526*7c478bd9Sstevel@tonic-gate */ 527*7c478bd9Sstevel@tonic-gate getrpcpws(CURMECH->alias); 528*7c478bd9Sstevel@tonic-gate if (!getsecretkey_g(netname, 529*7c478bd9Sstevel@tonic-gate CURMECH->keylen, 530*7c478bd9Sstevel@tonic-gate CURMECH->algtype, 531*7c478bd9Sstevel@tonic-gate secret, 532*7c478bd9Sstevel@tonic-gate hexkeylen, 533*7c478bd9Sstevel@tonic-gate rpc_pws[pcount])) { 534*7c478bd9Sstevel@tonic-gate /* 535*7c478bd9Sstevel@tonic-gate * Could not retreive 536*7c478bd9Sstevel@tonic-gate * secret key, abort 537*7c478bd9Sstevel@tonic-gate */ 538*7c478bd9Sstevel@tonic-gate free(secret); 539*7c478bd9Sstevel@tonic-gate secret = NULL; 540*7c478bd9Sstevel@tonic-gate goto getsecrets_abort; 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (secret[0] == 0) { 544*7c478bd9Sstevel@tonic-gate /* Still no go, ask again */ 545*7c478bd9Sstevel@tonic-gate free(rpc_pws[pcount]); 546*7c478bd9Sstevel@tonic-gate rpc_pw_count--; 547*7c478bd9Sstevel@tonic-gate tries++; 548*7c478bd9Sstevel@tonic-gate printf("Try again. "); 549*7c478bd9Sstevel@tonic-gate fflush(stdout); 550*7c478bd9Sstevel@tonic-gate goto getsecrets_tryagain_g; 551*7c478bd9Sstevel@tonic-gate } else 552*7c478bd9Sstevel@tonic-gate scount++; 553*7c478bd9Sstevel@tonic-gate } else { 554*7c478bd9Sstevel@tonic-gate fprintf(stderr, 555*7c478bd9Sstevel@tonic-gate "%s: key-pair unchanged for %s.\n", 556*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 557*7c478bd9Sstevel@tonic-gate exit(1); 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate } else 560*7c478bd9Sstevel@tonic-gate scount++; 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate getsecrets_abort: 563*7c478bd9Sstevel@tonic-gate slist[mcount] = secret; 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate } else { 566*7c478bd9Sstevel@tonic-gate char *secret = NULL; 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate if (!(secret = (char *)malloc(HEXKEYBYTES + 1))) { 569*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 570*7c478bd9Sstevel@tonic-gate exit(1); 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate getsecrets_tryagain: 573*7c478bd9Sstevel@tonic-gate if (!getsecretkey(netname, secret, rpc_pws[0])) { 574*7c478bd9Sstevel@tonic-gate fprintf(stderr, 575*7c478bd9Sstevel@tonic-gate "%s: could not get secret key for '%s'\n", 576*7c478bd9Sstevel@tonic-gate program_name, netname); 577*7c478bd9Sstevel@tonic-gate exit(1); 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate if (secret[0] == 0) { 581*7c478bd9Sstevel@tonic-gate if (!tries) { 582*7c478bd9Sstevel@tonic-gate free(rpc_pws[0]); 583*7c478bd9Sstevel@tonic-gate rpc_pw_count = 0; 584*7c478bd9Sstevel@tonic-gate tries++; 585*7c478bd9Sstevel@tonic-gate printf("Try again. "); 586*7c478bd9Sstevel@tonic-gate fflush(stdout); 587*7c478bd9Sstevel@tonic-gate getrpcpws(NULL); 588*7c478bd9Sstevel@tonic-gate goto getsecrets_tryagain; 589*7c478bd9Sstevel@tonic-gate } else { 590*7c478bd9Sstevel@tonic-gate fprintf(stderr, 591*7c478bd9Sstevel@tonic-gate "%s: key-pair unchanged for %s.\n", 592*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 593*7c478bd9Sstevel@tonic-gate exit(1); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate slist[0] = secret; 598*7c478bd9Sstevel@tonic-gate return; 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate if (!scount) { 602*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 603*7c478bd9Sstevel@tonic-gate "%s: could not get nor decrypt any secret keys for '%s'\n", 604*7c478bd9Sstevel@tonic-gate program_name, netname); 605*7c478bd9Sstevel@tonic-gate error_msg(); 606*7c478bd9Sstevel@tonic-gate exit(1); 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate /* Register AUTH_DES secret key with keyserv */ 612*7c478bd9Sstevel@tonic-gate static void 613*7c478bd9Sstevel@tonic-gate keylogin_des() 614*7c478bd9Sstevel@tonic-gate { 615*7c478bd9Sstevel@tonic-gate char *secret = slist[0]; 616*7c478bd9Sstevel@tonic-gate struct key_netstarg netst; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate /* 619*7c478bd9Sstevel@tonic-gate * try to revoke the existing key/credentials, assuming 620*7c478bd9Sstevel@tonic-gate * one exists. this will effectively mark "stale" any 621*7c478bd9Sstevel@tonic-gate * cached credientials... 622*7c478bd9Sstevel@tonic-gate */ 623*7c478bd9Sstevel@tonic-gate if (key_setsecret(secret) < 0) { 624*7c478bd9Sstevel@tonic-gate return; 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate #ifdef NFS_AUTH 628*7c478bd9Sstevel@tonic-gate /* 629*7c478bd9Sstevel@tonic-gate * it looks like a credential already existed, so try and 630*7c478bd9Sstevel@tonic-gate * revoke any lingering Secure-NFS privledges. 631*7c478bd9Sstevel@tonic-gate */ 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate nra.authtype = AUTH_DES; 634*7c478bd9Sstevel@tonic-gate nra.uid = getuid(); 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate if (_nfssys(NFS_REVAUTH, &nra) < 0) 637*7c478bd9Sstevel@tonic-gate perror("Warning: NFS credentials not destroyed"); 638*7c478bd9Sstevel@tonic-gate #endif /* NFS_AUTH */ 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate memcpy(netst.st_priv_key, secret, HEXKEYBYTES); 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate netst.st_pub_key[0] = '\0'; 643*7c478bd9Sstevel@tonic-gate netst.st_netname = strdup(netname); 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* do actual key login */ 646*7c478bd9Sstevel@tonic-gate if (key_setnet(&netst) < 0) { 647*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Could not set %s's secret key\n", netname); 648*7c478bd9Sstevel@tonic-gate fprintf(stderr, "May be the keyserv is down?\n"); 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate /* Register a secret key with the keyserv */ 654*7c478bd9Sstevel@tonic-gate static void 655*7c478bd9Sstevel@tonic-gate keylogin(keylen_t keylen, algtype_t algtype) 656*7c478bd9Sstevel@tonic-gate { 657*7c478bd9Sstevel@tonic-gate int mcount; 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate if (mechs) { 660*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 661*7c478bd9Sstevel@tonic-gate if (keylen == CURMECH->keylen && 662*7c478bd9Sstevel@tonic-gate algtype == CURMECH->algtype) { 663*7c478bd9Sstevel@tonic-gate if (key_setnet_g(netname, slist[mcount], 664*7c478bd9Sstevel@tonic-gate CURMECH->keylen, 665*7c478bd9Sstevel@tonic-gate NULL, 0, 666*7c478bd9Sstevel@tonic-gate CURMECH->algtype) 667*7c478bd9Sstevel@tonic-gate < 0) 668*7c478bd9Sstevel@tonic-gate fprintf(stderr, 669*7c478bd9Sstevel@tonic-gate "Could not set %s's %s secret key\n", 670*7c478bd9Sstevel@tonic-gate netname, 671*7c478bd9Sstevel@tonic-gate VALID_ALIAS(CURMECH->alias) ? 672*7c478bd9Sstevel@tonic-gate CURMECH->alias : ""); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate } else { 676*7c478bd9Sstevel@tonic-gate if (keylen == 192 && algtype == 0) 677*7c478bd9Sstevel@tonic-gate keylogin_des(); 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate /* 683*7c478bd9Sstevel@tonic-gate * fgets is "broken" in that if it reads a NUL character it will 684*7c478bd9Sstevel@tonic-gate * always return EOF for all reads, even when there is data left in 685*7c478bd9Sstevel@tonic-gate * the file. This replacement can deal with NUL's in a calm, rational 686*7c478bd9Sstevel@tonic-gate * manner. 687*7c478bd9Sstevel@tonic-gate */ 688*7c478bd9Sstevel@tonic-gate static char * 689*7c478bd9Sstevel@tonic-gate fgets_ignorenul(char *s, int n, FILE *stream) 690*7c478bd9Sstevel@tonic-gate { 691*7c478bd9Sstevel@tonic-gate int fildes = fileno(stream); 692*7c478bd9Sstevel@tonic-gate int i = 0; 693*7c478bd9Sstevel@tonic-gate int rs = 0; 694*7c478bd9Sstevel@tonic-gate char c; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if (fildes < 0) 697*7c478bd9Sstevel@tonic-gate return (NULL); 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate while (i < n - 1) { 700*7c478bd9Sstevel@tonic-gate rs = read(fildes, &c, 1); 701*7c478bd9Sstevel@tonic-gate switch (rs) { 702*7c478bd9Sstevel@tonic-gate case 1: 703*7c478bd9Sstevel@tonic-gate break; 704*7c478bd9Sstevel@tonic-gate case 0: 705*7c478bd9Sstevel@tonic-gate /* EOF */ 706*7c478bd9Sstevel@tonic-gate if (i > 0) 707*7c478bd9Sstevel@tonic-gate s[i] = '\0'; 708*7c478bd9Sstevel@tonic-gate return (NULL); 709*7c478bd9Sstevel@tonic-gate break; 710*7c478bd9Sstevel@tonic-gate default: 711*7c478bd9Sstevel@tonic-gate return (NULL); 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate switch (c) { 714*7c478bd9Sstevel@tonic-gate case '\0': 715*7c478bd9Sstevel@tonic-gate break; 716*7c478bd9Sstevel@tonic-gate case '\n': 717*7c478bd9Sstevel@tonic-gate s[i] = c; 718*7c478bd9Sstevel@tonic-gate s[++i] = '\0'; 719*7c478bd9Sstevel@tonic-gate return (s); 720*7c478bd9Sstevel@tonic-gate default: 721*7c478bd9Sstevel@tonic-gate if (c != '\0') 722*7c478bd9Sstevel@tonic-gate s[i++] = c; 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate s[i] = '\0'; 726*7c478bd9Sstevel@tonic-gate return (s); 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate /* Write unencrypted secret key into root key file */ 731*7c478bd9Sstevel@tonic-gate static void 732*7c478bd9Sstevel@tonic-gate write_rootkey(char *secret, char *flavor, keylen_t keylen, algtype_t algtype) 733*7c478bd9Sstevel@tonic-gate { 734*7c478bd9Sstevel@tonic-gate char line[MAXROOTKEY_LINE_LEN]; 735*7c478bd9Sstevel@tonic-gate char keyent[MAXROOTKEY_LEN]; 736*7c478bd9Sstevel@tonic-gate algtype_t atent; 737*7c478bd9Sstevel@tonic-gate int rootfd, bakfd, hexkeybytes; 738*7c478bd9Sstevel@tonic-gate bool_t lineone = TRUE; 739*7c478bd9Sstevel@tonic-gate bool_t gotit = FALSE; 740*7c478bd9Sstevel@tonic-gate FILE *rootfile, *bakfile; 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate unlink(ROOTKEY_FILE_BACKUP); 743*7c478bd9Sstevel@tonic-gate if ((rename(ROOTKEY_FILE, ROOTKEY_FILE_BACKUP)) < 0) { 744*7c478bd9Sstevel@tonic-gate if ((bakfd = creat(ROOTKEY_FILE_BACKUP, 0600)) < 0) { 745*7c478bd9Sstevel@tonic-gate perror("Could not create /etc/.rootkey.bak"); 746*7c478bd9Sstevel@tonic-gate goto rootkey_err; 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate close(bakfd); 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate if ((rootfd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) < 0) { 752*7c478bd9Sstevel@tonic-gate perror("Could not open /etc/.rootkey for writing"); 753*7c478bd9Sstevel@tonic-gate fprintf(stderr, 754*7c478bd9Sstevel@tonic-gate "Attempting to restore original /etc/.rootkey\n"); 755*7c478bd9Sstevel@tonic-gate rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); 756*7c478bd9Sstevel@tonic-gate goto rootkey_err; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate if (!(rootfile = fdopen(rootfd, "w"))) { 759*7c478bd9Sstevel@tonic-gate perror("Could not open /etc/.rootkey for writing"); 760*7c478bd9Sstevel@tonic-gate fprintf(stderr, 761*7c478bd9Sstevel@tonic-gate "Attempting to restore original /etc/.rootkey\n"); 762*7c478bd9Sstevel@tonic-gate close(rootfd); 763*7c478bd9Sstevel@tonic-gate unlink(ROOTKEY_FILE); 764*7c478bd9Sstevel@tonic-gate rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); 765*7c478bd9Sstevel@tonic-gate goto rootkey_err; 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate if (!(bakfile = fopen(ROOTKEY_FILE_BACKUP, "r"))) { 768*7c478bd9Sstevel@tonic-gate perror("Could not open /etc/.rootkey.bak for reading"); 769*7c478bd9Sstevel@tonic-gate fprintf(stderr, 770*7c478bd9Sstevel@tonic-gate "Attempting to restore original /etc/.rootkey\n"); 771*7c478bd9Sstevel@tonic-gate fclose(rootfile); 772*7c478bd9Sstevel@tonic-gate unlink(ROOTKEY_FILE); 773*7c478bd9Sstevel@tonic-gate rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); 774*7c478bd9Sstevel@tonic-gate goto rootkey_err; 775*7c478bd9Sstevel@tonic-gate } 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate hexkeybytes = ((keylen + 7) / 8) * 2; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate while (fgets_ignorenul(line, MAXROOTKEY_LINE_LEN, bakfile)) { 780*7c478bd9Sstevel@tonic-gate sscanf(line, "%s %d", keyent, &atent); 781*7c478bd9Sstevel@tonic-gate /* 782*7c478bd9Sstevel@tonic-gate * 192-bit keys always go on the first line 783*7c478bd9Sstevel@tonic-gate */ 784*7c478bd9Sstevel@tonic-gate if (lineone) { 785*7c478bd9Sstevel@tonic-gate lineone = FALSE; 786*7c478bd9Sstevel@tonic-gate if (keylen == 192) { 787*7c478bd9Sstevel@tonic-gate gotit = TRUE; 788*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s\n", secret); 789*7c478bd9Sstevel@tonic-gate } else 790*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s", line); 791*7c478bd9Sstevel@tonic-gate fflush(rootfile); 792*7c478bd9Sstevel@tonic-gate } else { 793*7c478bd9Sstevel@tonic-gate if ((strlen(keyent) == hexkeybytes) && 794*7c478bd9Sstevel@tonic-gate (atent == algtype)) { 795*7c478bd9Sstevel@tonic-gate /* 796*7c478bd9Sstevel@tonic-gate * Silently remove lines with the same 797*7c478bd9Sstevel@tonic-gate * keylen/algtype 798*7c478bd9Sstevel@tonic-gate */ 799*7c478bd9Sstevel@tonic-gate if (gotit) 800*7c478bd9Sstevel@tonic-gate continue; 801*7c478bd9Sstevel@tonic-gate else 802*7c478bd9Sstevel@tonic-gate gotit = TRUE; 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s %d\n", secret, algtype); 805*7c478bd9Sstevel@tonic-gate } else 806*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s", line); 807*7c478bd9Sstevel@tonic-gate fflush(rootfile); 808*7c478bd9Sstevel@tonic-gate } 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate /* Append key to rootkey file */ 812*7c478bd9Sstevel@tonic-gate if (!gotit) { 813*7c478bd9Sstevel@tonic-gate if (keylen == 192) 814*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s\n", secret); 815*7c478bd9Sstevel@tonic-gate else { 816*7c478bd9Sstevel@tonic-gate if (lineone) 817*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "\n"); 818*7c478bd9Sstevel@tonic-gate fprintf(rootfile, "%s %d\n", secret, algtype); 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate fflush(rootfile); 822*7c478bd9Sstevel@tonic-gate fclose(rootfile); 823*7c478bd9Sstevel@tonic-gate fclose(bakfile); 824*7c478bd9Sstevel@tonic-gate unlink(ROOTKEY_FILE_BACKUP); 825*7c478bd9Sstevel@tonic-gate return; 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate rootkey_err: 828*7c478bd9Sstevel@tonic-gate fprintf(stderr, "WARNING: Could not write %s key to /etc/.rootkey\n", 829*7c478bd9Sstevel@tonic-gate flavor); 830*7c478bd9Sstevel@tonic-gate } 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate /* Returns 0 if check fails; 1 if successful. */ 834*7c478bd9Sstevel@tonic-gate static int 835*7c478bd9Sstevel@tonic-gate sanity_checks(char *nis_princ, char *domain, char *authtype) 836*7c478bd9Sstevel@tonic-gate { 837*7c478bd9Sstevel@tonic-gate char netdomainaux[MAXHOSTNAMELEN+1]; 838*7c478bd9Sstevel@tonic-gate char *princdomain, *netdomain; 839*7c478bd9Sstevel@tonic-gate int len; 840*7c478bd9Sstevel@tonic-gate 841*7c478bd9Sstevel@tonic-gate /* Sanity check 0. Do we have a nis+ principal name to work with? */ 842*7c478bd9Sstevel@tonic-gate if (nis_princ == NULL) { 843*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 844*7c478bd9Sstevel@tonic-gate "%s: you must create a \"LOCAL\" credential for '%s' first.\n", 845*7c478bd9Sstevel@tonic-gate program_name, netname); 846*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tSee nisaddcred(1).\n"); 847*7c478bd9Sstevel@tonic-gate return (0); 848*7c478bd9Sstevel@tonic-gate } 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate /* Sanity check 0.5. NIS+ principal names must be dotted. */ 851*7c478bd9Sstevel@tonic-gate len = strlen(nis_princ); 852*7c478bd9Sstevel@tonic-gate if (nis_princ[len-1] != '.') { 853*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 854*7c478bd9Sstevel@tonic-gate "%s: invalid principal name: '%s' (forgot ending dot?).\n", 855*7c478bd9Sstevel@tonic-gate program_name, nis_princ); 856*7c478bd9Sstevel@tonic-gate return (0); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate /* Sanity check 1. We only deal with one type of netnames. */ 860*7c478bd9Sstevel@tonic-gate if (strncmp(netname, "unix", 4) != 0) { 861*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 862*7c478bd9Sstevel@tonic-gate "%s: unrecognized netname type: '%s'.\n", 863*7c478bd9Sstevel@tonic-gate program_name, netname); 864*7c478bd9Sstevel@tonic-gate return (0); 865*7c478bd9Sstevel@tonic-gate } 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate /* Sanity check 2. Should only add DES cred in home domain. */ 868*7c478bd9Sstevel@tonic-gate princdomain = nis_domain_of(nis_princ); 869*7c478bd9Sstevel@tonic-gate if (strcasecmp(princdomain, domain) != 0) { 870*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 871*7c478bd9Sstevel@tonic-gate "%s: domain of principal '%s' does not match destination domain '%s'.\n", 872*7c478bd9Sstevel@tonic-gate program_name, nis_princ, domain); 873*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 874*7c478bd9Sstevel@tonic-gate "Should only add DES credential of principal in its home domain\n"); 875*7c478bd9Sstevel@tonic-gate return (0); 876*7c478bd9Sstevel@tonic-gate } 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* 879*7c478bd9Sstevel@tonic-gate * Sanity check 3: Make sure netname's domain same as principal's 880*7c478bd9Sstevel@tonic-gate * and don't have extraneous dot at the end. 881*7c478bd9Sstevel@tonic-gate */ 882*7c478bd9Sstevel@tonic-gate netdomain = (char *)strchr(netname, '@'); 883*7c478bd9Sstevel@tonic-gate if (! netdomain || netname[strlen(netname)-1] == '.') { 884*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: invalid netname: '%s'. \n", 885*7c478bd9Sstevel@tonic-gate program_name, netname); 886*7c478bd9Sstevel@tonic-gate return (0); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate netdomain++; /* skip '@' */ 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate if (strlcpy(netdomainaux, netdomain, sizeof (netdomainaux)) >= 891*7c478bd9Sstevel@tonic-gate sizeof (netdomainaux)) { 892*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: net domain name %s is too long\n", 893*7c478bd9Sstevel@tonic-gate program_name, netdomain); 894*7c478bd9Sstevel@tonic-gate return (0); 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate if (netdomainaux[strlen(netdomainaux) - 1] != '.') { 898*7c478bd9Sstevel@tonic-gate if (strlcat(netdomainaux, ".", sizeof (netdomainaux)) >= 899*7c478bd9Sstevel@tonic-gate sizeof (netdomainaux)) { 900*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 901*7c478bd9Sstevel@tonic-gate "%s: net domain name %s is too long\n", 902*7c478bd9Sstevel@tonic-gate program_name, netdomainaux); 903*7c478bd9Sstevel@tonic-gate return (0); 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate if (strcasecmp(princdomain, netdomainaux) != 0) { 908*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 909*7c478bd9Sstevel@tonic-gate "%s: domain of netname %s should be same as that of principal %s\n", 910*7c478bd9Sstevel@tonic-gate program_name, netname, nis_princ); 911*7c478bd9Sstevel@tonic-gate return (0); 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate /* Another principal owns same credentials? (exits if that happens) */ 915*7c478bd9Sstevel@tonic-gate (void) auth_exists(nis_princ, netname, authtype, domain); 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate return (1); /* all passed */ 918*7c478bd9Sstevel@tonic-gate } 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate /* Store new key information in the specified name service */ 922*7c478bd9Sstevel@tonic-gate static void 923*7c478bd9Sstevel@tonic-gate storekeys() 924*7c478bd9Sstevel@tonic-gate { 925*7c478bd9Sstevel@tonic-gate int mcount, ucount = 0; 926*7c478bd9Sstevel@tonic-gate char *ypmaster, *ypdomain = NULL, pkent[MAXPKENTLEN]; 927*7c478bd9Sstevel@tonic-gate nis_name nis_princ; 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate /* Setup */ 931*7c478bd9Sstevel@tonic-gate switch (dest_service) { 932*7c478bd9Sstevel@tonic-gate case PK_LDAP: 933*7c478bd9Sstevel@tonic-gate break; 934*7c478bd9Sstevel@tonic-gate case PK_NISPLUS: 935*7c478bd9Sstevel@tonic-gate nis_princ = get_nisplus_principal(nis_local_directory(), 936*7c478bd9Sstevel@tonic-gate geteuid()); 937*7c478bd9Sstevel@tonic-gate break; 938*7c478bd9Sstevel@tonic-gate case PK_YP: 939*7c478bd9Sstevel@tonic-gate yp_get_default_domain(&ypdomain); 940*7c478bd9Sstevel@tonic-gate if (yp_master(ypdomain, PKMAP, &ypmaster) != 0) { 941*7c478bd9Sstevel@tonic-gate fprintf(stderr, 942*7c478bd9Sstevel@tonic-gate "%s: cannot find master of NIS publickey database\n", 943*7c478bd9Sstevel@tonic-gate program_name); 944*7c478bd9Sstevel@tonic-gate exit(1); 945*7c478bd9Sstevel@tonic-gate } 946*7c478bd9Sstevel@tonic-gate fprintf(stdout, 947*7c478bd9Sstevel@tonic-gate "Sending key change request to %s ...\n", ypmaster); 948*7c478bd9Sstevel@tonic-gate break; 949*7c478bd9Sstevel@tonic-gate case PK_FILES: 950*7c478bd9Sstevel@tonic-gate if (geteuid() != 0) { 951*7c478bd9Sstevel@tonic-gate fprintf(stderr, 952*7c478bd9Sstevel@tonic-gate "%s: non-root users cannot change their key-pair in %s\n", 953*7c478bd9Sstevel@tonic-gate program_name, PKFILE); 954*7c478bd9Sstevel@tonic-gate exit(1); 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate break; 957*7c478bd9Sstevel@tonic-gate default: 958*7c478bd9Sstevel@tonic-gate fprintf(stderr, 959*7c478bd9Sstevel@tonic-gate "could not update; database %d unknown\n", 960*7c478bd9Sstevel@tonic-gate dest_service); 961*7c478bd9Sstevel@tonic-gate exit(1); 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate 964*7c478bd9Sstevel@tonic-gate if (mechs) { 965*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 966*7c478bd9Sstevel@tonic-gate char authtype[MECH_MAXATNAME]; 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate if (!plist[mcount] && !clist[mcount]) 969*7c478bd9Sstevel@tonic-gate continue; 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate __nis_mechalias2authtype(CURMECH->alias, authtype, 972*7c478bd9Sstevel@tonic-gate MECH_MAXATNAME); 973*7c478bd9Sstevel@tonic-gate if (!authtype) { 974*7c478bd9Sstevel@tonic-gate fprintf(stderr, 975*7c478bd9Sstevel@tonic-gate "Could not generate auth_type for %s.\n", 976*7c478bd9Sstevel@tonic-gate CURMECH->alias); 977*7c478bd9Sstevel@tonic-gate continue; 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate snprintf(pkent, MAXPKENTLEN, "%s:%s:%d", 981*7c478bd9Sstevel@tonic-gate plist[mcount], clist[mcount], 982*7c478bd9Sstevel@tonic-gate CURMECH->algtype); 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate switch (dest_service) { 985*7c478bd9Sstevel@tonic-gate case PK_LDAP: 986*7c478bd9Sstevel@tonic-gate if (ldap_update(CURMECH->alias, netname, 987*7c478bd9Sstevel@tonic-gate plist[mcount], clist[mcount], 988*7c478bd9Sstevel@tonic-gate login_pw)) 989*7c478bd9Sstevel@tonic-gate fprintf(stderr, 990*7c478bd9Sstevel@tonic-gate "%s: unable to update %s key in LDAP database\n", 991*7c478bd9Sstevel@tonic-gate program_name, authtype); 992*7c478bd9Sstevel@tonic-gate else 993*7c478bd9Sstevel@tonic-gate ucount++; 994*7c478bd9Sstevel@tonic-gate break; 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate case PK_NISPLUS: 997*7c478bd9Sstevel@tonic-gate if (nisplus_update(nis_princ, 998*7c478bd9Sstevel@tonic-gate authtype, 999*7c478bd9Sstevel@tonic-gate plist[mcount], 1000*7c478bd9Sstevel@tonic-gate clist[mcount])) 1001*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1002*7c478bd9Sstevel@tonic-gate "%s: unable to update %s key in nisplus database\n", 1003*7c478bd9Sstevel@tonic-gate program_name, authtype); 1004*7c478bd9Sstevel@tonic-gate else 1005*7c478bd9Sstevel@tonic-gate ucount++; 1006*7c478bd9Sstevel@tonic-gate break; 1007*7c478bd9Sstevel@tonic-gate 1008*7c478bd9Sstevel@tonic-gate case PK_YP: 1009*7c478bd9Sstevel@tonic-gate /* Should never get here. */ 1010*7c478bd9Sstevel@tonic-gate break; 1011*7c478bd9Sstevel@tonic-gate 1012*7c478bd9Sstevel@tonic-gate case PK_FILES: 1013*7c478bd9Sstevel@tonic-gate /* Should never get here. */ 1014*7c478bd9Sstevel@tonic-gate break; 1015*7c478bd9Sstevel@tonic-gate } 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate } else { 1018*7c478bd9Sstevel@tonic-gate int status = 0; 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate assert(plist[0] && clist[0]); 1021*7c478bd9Sstevel@tonic-gate snprintf(pkent, MAXPKENTLEN, "%s:%s", plist[0], clist[0]); 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate switch (dest_service) { 1024*7c478bd9Sstevel@tonic-gate case PK_LDAP: 1025*7c478bd9Sstevel@tonic-gate if (ldap_update("dh192-0", netname, 1026*7c478bd9Sstevel@tonic-gate plist[0], clist[0], 1027*7c478bd9Sstevel@tonic-gate login_pw)) { 1028*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1029*7c478bd9Sstevel@tonic-gate "%s: unable to update %s key in LDAP database\n", 1030*7c478bd9Sstevel@tonic-gate program_name); 1031*7c478bd9Sstevel@tonic-gate exit(1); 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate break; 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate case PK_NISPLUS: 1036*7c478bd9Sstevel@tonic-gate assert(plist[0] && clist[0]); 1037*7c478bd9Sstevel@tonic-gate if (nisplus_update(nis_princ, 1038*7c478bd9Sstevel@tonic-gate AUTH_DES_AUTH_TYPE, 1039*7c478bd9Sstevel@tonic-gate plist[0], 1040*7c478bd9Sstevel@tonic-gate clist[0])) { 1041*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1042*7c478bd9Sstevel@tonic-gate "%s: unable to update nisplus database\n", 1043*7c478bd9Sstevel@tonic-gate program_name); 1044*7c478bd9Sstevel@tonic-gate exit(1); 1045*7c478bd9Sstevel@tonic-gate } 1046*7c478bd9Sstevel@tonic-gate break; 1047*7c478bd9Sstevel@tonic-gate 1048*7c478bd9Sstevel@tonic-gate case PK_YP: 1049*7c478bd9Sstevel@tonic-gate if (status = yp_update(ypdomain, PKMAP, 1050*7c478bd9Sstevel@tonic-gate YPOP_STORE, netname, 1051*7c478bd9Sstevel@tonic-gate strlen(netname), pkent, 1052*7c478bd9Sstevel@tonic-gate strlen(pkent))) { 1053*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1054*7c478bd9Sstevel@tonic-gate "%s: unable to update NIS database (%u): %s\n", 1055*7c478bd9Sstevel@tonic-gate program_name, status, 1056*7c478bd9Sstevel@tonic-gate yperr_string(status)); 1057*7c478bd9Sstevel@tonic-gate exit(1); 1058*7c478bd9Sstevel@tonic-gate } 1059*7c478bd9Sstevel@tonic-gate break; 1060*7c478bd9Sstevel@tonic-gate 1061*7c478bd9Sstevel@tonic-gate case PK_FILES: 1062*7c478bd9Sstevel@tonic-gate if (localupdate(netname, PKFILE, YPOP_STORE, pkent)) { 1063*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1064*7c478bd9Sstevel@tonic-gate "%s: hence, unable to update publickey database\n", 1065*7c478bd9Sstevel@tonic-gate program_name); 1066*7c478bd9Sstevel@tonic-gate exit(1); 1067*7c478bd9Sstevel@tonic-gate } 1068*7c478bd9Sstevel@tonic-gate break; 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate default: 1071*7c478bd9Sstevel@tonic-gate /* Should never get here */ 1072*7c478bd9Sstevel@tonic-gate assert(0); 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate return; 1075*7c478bd9Sstevel@tonic-gate } 1076*7c478bd9Sstevel@tonic-gate if (!ucount) { 1077*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: unable to update any key-pairs for %s.\n", 1078*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 1079*7c478bd9Sstevel@tonic-gate exit(1); 1080*7c478bd9Sstevel@tonic-gate } 1081*7c478bd9Sstevel@tonic-gate } 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate /* Check that someone else don't have the same auth information already */ 1084*7c478bd9Sstevel@tonic-gate static 1085*7c478bd9Sstevel@tonic-gate nis_error 1086*7c478bd9Sstevel@tonic-gate auth_exists(char *princname, char *auth_name, char *auth_type, char *domain) 1087*7c478bd9Sstevel@tonic-gate { 1088*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 1089*7c478bd9Sstevel@tonic-gate nis_result *res; 1090*7c478bd9Sstevel@tonic-gate nis_error status; 1091*7c478bd9Sstevel@tonic-gate char *foundprinc; 1092*7c478bd9Sstevel@tonic-gate 1093*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "[auth_name=%s,auth_type=%s],%s.%s", 1094*7c478bd9Sstevel@tonic-gate auth_name, auth_type, CRED_TABLE, domain); 1095*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname)-1] != '.') 1096*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 1097*7c478bd9Sstevel@tonic-gate /* Don't want FOLLOW_PATH here */ 1098*7c478bd9Sstevel@tonic-gate res = nis_list(sname, 1099*7c478bd9Sstevel@tonic-gate MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, 1100*7c478bd9Sstevel@tonic-gate NULL, NULL); 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate status = res->status; 1103*7c478bd9Sstevel@tonic-gate switch (res->status) { 1104*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 1105*7c478bd9Sstevel@tonic-gate break; 1106*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 1107*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1108*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 1109*7c478bd9Sstevel@tonic-gate program_name); 1110*7c478bd9Sstevel@tonic-gate exit(1); 1111*7c478bd9Sstevel@tonic-gate break; 1112*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION: 1113*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1114*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to look up old credentials.\n", 1115*7c478bd9Sstevel@tonic-gate program_name); 1116*7c478bd9Sstevel@tonic-gate exit(1); 1117*7c478bd9Sstevel@tonic-gate break; 1118*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 1119*7c478bd9Sstevel@tonic-gate foundprinc = ENTRY_VAL(res->objects.objects_val, 0); 1120*7c478bd9Sstevel@tonic-gate if (nis_dir_cmp(foundprinc, princname) != SAME_NAME) { 1121*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1122*7c478bd9Sstevel@tonic-gate "%s: %s credentials with auth_name '%s' already belong to '%s'.\n", 1123*7c478bd9Sstevel@tonic-gate program_name, auth_type, auth_name, foundprinc); 1124*7c478bd9Sstevel@tonic-gate exit(1); 1125*7c478bd9Sstevel@tonic-gate } 1126*7c478bd9Sstevel@tonic-gate break; 1127*7c478bd9Sstevel@tonic-gate default: 1128*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1129*7c478bd9Sstevel@tonic-gate "%s: error looking at cred table, NIS+ error: %s\n", 1130*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 1131*7c478bd9Sstevel@tonic-gate exit(1); 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 1134*7c478bd9Sstevel@tonic-gate return (status); 1135*7c478bd9Sstevel@tonic-gate } 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate 1138*7c478bd9Sstevel@tonic-gate /* Check whether this principal already has this type of credentials */ 1139*7c478bd9Sstevel@tonic-gate static nis_error 1140*7c478bd9Sstevel@tonic-gate cred_exists(const char *nisprinc, const char *flavor, const char *domain) 1141*7c478bd9Sstevel@tonic-gate { 1142*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 1143*7c478bd9Sstevel@tonic-gate nis_result *res; 1144*7c478bd9Sstevel@tonic-gate nis_error status; 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate snprintf(sname, NIS_MAXNAMELEN, 1147*7c478bd9Sstevel@tonic-gate "[cname=\"%s\",auth_type=%s],%s.%s", 1148*7c478bd9Sstevel@tonic-gate nisprinc, flavor, CRED_TABLE, domain); 1149*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname)-1] != '.') 1150*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 1151*7c478bd9Sstevel@tonic-gate 1152*7c478bd9Sstevel@tonic-gate /* Don't want FOLLOW_PATH here */ 1153*7c478bd9Sstevel@tonic-gate res = nis_list(sname, 1154*7c478bd9Sstevel@tonic-gate MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, 1155*7c478bd9Sstevel@tonic-gate NULL, NULL); 1156*7c478bd9Sstevel@tonic-gate 1157*7c478bd9Sstevel@tonic-gate status = res->status; 1158*7c478bd9Sstevel@tonic-gate switch (status) { 1159*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 1160*7c478bd9Sstevel@tonic-gate break; 1161*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 1162*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1163*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 1164*7c478bd9Sstevel@tonic-gate program_name); 1165*7c478bd9Sstevel@tonic-gate exit(1); 1166*7c478bd9Sstevel@tonic-gate break; 1167*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION: 1168*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1169*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to look at credentials table\n", 1170*7c478bd9Sstevel@tonic-gate program_name); 1171*7c478bd9Sstevel@tonic-gate exit(1); 1172*7c478bd9Sstevel@tonic-gate break; 1173*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 1174*7c478bd9Sstevel@tonic-gate case NIS_S_SUCCESS: 1175*7c478bd9Sstevel@tonic-gate break; 1176*7c478bd9Sstevel@tonic-gate default: 1177*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1178*7c478bd9Sstevel@tonic-gate "%s: error looking at cred table, NIS+ error: %s\n", 1179*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 1180*7c478bd9Sstevel@tonic-gate exit(1); 1181*7c478bd9Sstevel@tonic-gate } 1182*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 1183*7c478bd9Sstevel@tonic-gate return (status); 1184*7c478bd9Sstevel@tonic-gate } 1185*7c478bd9Sstevel@tonic-gate 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate static int 1188*7c478bd9Sstevel@tonic-gate modify_cred_obj(nis_object *obj, char *domain) 1189*7c478bd9Sstevel@tonic-gate { 1190*7c478bd9Sstevel@tonic-gate int status = 0; 1191*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 1192*7c478bd9Sstevel@tonic-gate nis_result *res; 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "%s.%s", CRED_TABLE, domain); 1195*7c478bd9Sstevel@tonic-gate res = nis_modify_entry(sname, obj, 0); 1196*7c478bd9Sstevel@tonic-gate switch (res->status) { 1197*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 1198*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1199*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 1200*7c478bd9Sstevel@tonic-gate program_name); 1201*7c478bd9Sstevel@tonic-gate exit(1); 1202*7c478bd9Sstevel@tonic-gate break; 1203*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION: 1204*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1205*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to update credentials.\n", 1206*7c478bd9Sstevel@tonic-gate program_name); 1207*7c478bd9Sstevel@tonic-gate exit(1); 1208*7c478bd9Sstevel@tonic-gate break; 1209*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 1210*7c478bd9Sstevel@tonic-gate status = 1; 1211*7c478bd9Sstevel@tonic-gate break; 1212*7c478bd9Sstevel@tonic-gate default: 1213*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1214*7c478bd9Sstevel@tonic-gate "%s: error modifying credential, NIS+ error: %s.\n", 1215*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 1216*7c478bd9Sstevel@tonic-gate exit(1); 1217*7c478bd9Sstevel@tonic-gate } 1218*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 1219*7c478bd9Sstevel@tonic-gate return (status); 1220*7c478bd9Sstevel@tonic-gate } 1221*7c478bd9Sstevel@tonic-gate 1222*7c478bd9Sstevel@tonic-gate 1223*7c478bd9Sstevel@tonic-gate static int 1224*7c478bd9Sstevel@tonic-gate add_cred_obj(nis_object *obj, char *domain) 1225*7c478bd9Sstevel@tonic-gate { 1226*7c478bd9Sstevel@tonic-gate int status = 0; 1227*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 1228*7c478bd9Sstevel@tonic-gate nis_result *res; 1229*7c478bd9Sstevel@tonic-gate 1230*7c478bd9Sstevel@tonic-gate /* Assume check for cred_exists performed already */ 1231*7c478bd9Sstevel@tonic-gate 1232*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "%s.%s", CRED_TABLE, domain); 1233*7c478bd9Sstevel@tonic-gate res = nis_add_entry(sname, obj, 0); 1234*7c478bd9Sstevel@tonic-gate switch (res->status) { 1235*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 1236*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1237*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 1238*7c478bd9Sstevel@tonic-gate program_name); 1239*7c478bd9Sstevel@tonic-gate exit(1); 1240*7c478bd9Sstevel@tonic-gate break; 1241*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION: 1242*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1243*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to update credentials.\n", 1244*7c478bd9Sstevel@tonic-gate program_name); 1245*7c478bd9Sstevel@tonic-gate exit(1); 1246*7c478bd9Sstevel@tonic-gate break; 1247*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 1248*7c478bd9Sstevel@tonic-gate status = 1; 1249*7c478bd9Sstevel@tonic-gate break; 1250*7c478bd9Sstevel@tonic-gate default: 1251*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1252*7c478bd9Sstevel@tonic-gate "%s: error creating credential, NIS+ error: %s.\n", 1253*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 1254*7c478bd9Sstevel@tonic-gate exit(1); 1255*7c478bd9Sstevel@tonic-gate } 1256*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 1257*7c478bd9Sstevel@tonic-gate return (status); 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate 1261*7c478bd9Sstevel@tonic-gate /* Update NIS+ table with new key information */ 1262*7c478bd9Sstevel@tonic-gate static int 1263*7c478bd9Sstevel@tonic-gate nisplus_update(nis_name nis_princ, char *authtype, char *public, char *crypt) 1264*7c478bd9Sstevel@tonic-gate { 1265*7c478bd9Sstevel@tonic-gate nis_object *obj = init_entry(); 1266*7c478bd9Sstevel@tonic-gate int status; 1267*7c478bd9Sstevel@tonic-gate bool_t addition; 1268*7c478bd9Sstevel@tonic-gate char *userdomain, *cmpdomain, *domain; 1269*7c478bd9Sstevel@tonic-gate 1270*7c478bd9Sstevel@tonic-gate if (!(userdomain = strchr(netname, '@'))) { 1271*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: invalid netname: '%s'.\n", 1272*7c478bd9Sstevel@tonic-gate program_name, netname); 1273*7c478bd9Sstevel@tonic-gate exit(1); 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate userdomain++; 1276*7c478bd9Sstevel@tonic-gate 1277*7c478bd9Sstevel@tonic-gate cmpdomain = strdup(userdomain); 1278*7c478bd9Sstevel@tonic-gate if (cmpdomain[strlen(cmpdomain) - 1] != '.') 1279*7c478bd9Sstevel@tonic-gate strcat(cmpdomain, "."); 1280*7c478bd9Sstevel@tonic-gate 1281*7c478bd9Sstevel@tonic-gate domain = nis_domain_of(nis_princ); 1282*7c478bd9Sstevel@tonic-gate if (strcasecmp(domain, cmpdomain) != 0) 1283*7c478bd9Sstevel@tonic-gate domain = nis_local_directory(); 1284*7c478bd9Sstevel@tonic-gate 1285*7c478bd9Sstevel@tonic-gate if (!sanity_checks(nis_princ, domain, authtype)) 1286*7c478bd9Sstevel@tonic-gate exit(1); 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate addition = (cred_exists(nis_princ, authtype, domain) == NIS_NOTFOUND); 1289*7c478bd9Sstevel@tonic-gate 1290*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 0) = nis_princ; 1291*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 0) = strlen(nis_princ) + 1; 1292*7c478bd9Sstevel@tonic-gate 1293*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 1) = authtype; 1294*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 1) = strlen(authtype) + 1; 1295*7c478bd9Sstevel@tonic-gate 1296*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 2) = netname; 1297*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 2) = strlen(netname) + 1; 1298*7c478bd9Sstevel@tonic-gate 1299*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 3) = public; 1300*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 3) = strlen(public) + 1; 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 4) = crypt; 1303*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 4) = strlen(crypt) + 1; 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate if (addition) { 1306*7c478bd9Sstevel@tonic-gate obj->zo_owner = nis_princ; 1307*7c478bd9Sstevel@tonic-gate obj->zo_group = nis_local_group(); 1308*7c478bd9Sstevel@tonic-gate obj->zo_domain = domain; 1309*7c478bd9Sstevel@tonic-gate /* owner: r, group: rmcd */ 1310*7c478bd9Sstevel@tonic-gate obj->zo_access = ((NIS_READ_ACC<<16)| 1311*7c478bd9Sstevel@tonic-gate (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| 1312*7c478bd9Sstevel@tonic-gate NIS_DESTROY_ACC)<<8); 1313*7c478bd9Sstevel@tonic-gate status = add_cred_obj(obj, domain); 1314*7c478bd9Sstevel@tonic-gate } else { 1315*7c478bd9Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED; 1316*7c478bd9Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val[4].ec_flags |= EN_MODIFIED; 1317*7c478bd9Sstevel@tonic-gate status = modify_cred_obj(obj, domain); 1318*7c478bd9Sstevel@tonic-gate } 1319*7c478bd9Sstevel@tonic-gate return (status == 1 ? 0 : 1); 1320*7c478bd9Sstevel@tonic-gate } 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate 1323*7c478bd9Sstevel@tonic-gate void 1324*7c478bd9Sstevel@tonic-gate addmechtolist(char *mechtype) 1325*7c478bd9Sstevel@tonic-gate { 1326*7c478bd9Sstevel@tonic-gate mechanism_t **realmechlist; 1327*7c478bd9Sstevel@tonic-gate int i; 1328*7c478bd9Sstevel@tonic-gate 1329*7c478bd9Sstevel@tonic-gate if (realmechlist = __nis_get_mechanisms(FALSE)) { 1330*7c478bd9Sstevel@tonic-gate /* Match requested mech with list */ 1331*7c478bd9Sstevel@tonic-gate for (i = 0; realmechlist[i]; i++) { 1332*7c478bd9Sstevel@tonic-gate if (realmechlist[i]->alias) 1333*7c478bd9Sstevel@tonic-gate if (strcmp(realmechlist[i]->alias, mechtype) 1334*7c478bd9Sstevel@tonic-gate == 0) { 1335*7c478bd9Sstevel@tonic-gate /* 1336*7c478bd9Sstevel@tonic-gate * Match, add it to the mechs. 1337*7c478bd9Sstevel@tonic-gate * Don't worry about qop or 1338*7c478bd9Sstevel@tonic-gate * secserv since they are not 1339*7c478bd9Sstevel@tonic-gate * used by chkey. 1340*7c478bd9Sstevel@tonic-gate */ 1341*7c478bd9Sstevel@tonic-gate numspecmech++; 1342*7c478bd9Sstevel@tonic-gate if ((mechs = 1343*7c478bd9Sstevel@tonic-gate (mechanism_t **)realloc(mechs, 1344*7c478bd9Sstevel@tonic-gate sizeof (mechanism_t *) * (numspecmech + 1))) == 1345*7c478bd9Sstevel@tonic-gate NULL) { 1346*7c478bd9Sstevel@tonic-gate perror("Can not change keys"); 1347*7c478bd9Sstevel@tonic-gate exit(1); 1348*7c478bd9Sstevel@tonic-gate } 1349*7c478bd9Sstevel@tonic-gate 1350*7c478bd9Sstevel@tonic-gate if ((mechs[numspecmech - 1] = 1351*7c478bd9Sstevel@tonic-gate (mechanism_t *)malloc(sizeof (mechanism_t))) == NULL) { 1352*7c478bd9Sstevel@tonic-gate perror("Can not change keys"); 1353*7c478bd9Sstevel@tonic-gate exit(1); 1354*7c478bd9Sstevel@tonic-gate } 1355*7c478bd9Sstevel@tonic-gate if (realmechlist[i]->mechname) 1356*7c478bd9Sstevel@tonic-gate mechs[numspecmech - 1]->mechname = 1357*7c478bd9Sstevel@tonic-gate strdup(realmechlist[i]->mechname); 1358*7c478bd9Sstevel@tonic-gate if (realmechlist[i]->alias) 1359*7c478bd9Sstevel@tonic-gate mechs[numspecmech - 1]->alias = 1360*7c478bd9Sstevel@tonic-gate strdup(realmechlist[i]->alias); 1361*7c478bd9Sstevel@tonic-gate mechs[numspecmech - 1]->keylen = 1362*7c478bd9Sstevel@tonic-gate realmechlist[i]->keylen; 1363*7c478bd9Sstevel@tonic-gate mechs[numspecmech - 1]->algtype = 1364*7c478bd9Sstevel@tonic-gate realmechlist[i]->algtype; 1365*7c478bd9Sstevel@tonic-gate mechs[numspecmech] = NULL; 1366*7c478bd9Sstevel@tonic-gate __nis_release_mechanisms(realmechlist); 1367*7c478bd9Sstevel@tonic-gate return; 1368*7c478bd9Sstevel@tonic-gate } 1369*7c478bd9Sstevel@tonic-gate } 1370*7c478bd9Sstevel@tonic-gate 1371*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1372*7c478bd9Sstevel@tonic-gate "WARNING: Mechanism '%s' not configured, skipping...\n", 1373*7c478bd9Sstevel@tonic-gate mechtype); 1374*7c478bd9Sstevel@tonic-gate __nis_release_mechanisms(realmechlist); 1375*7c478bd9Sstevel@tonic-gate return; 1376*7c478bd9Sstevel@tonic-gate } 1377*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1378*7c478bd9Sstevel@tonic-gate "WARNING: Mechanism '%s' not configured, skipping...\n", 1379*7c478bd9Sstevel@tonic-gate mechtype); 1380*7c478bd9Sstevel@tonic-gate } 1381*7c478bd9Sstevel@tonic-gate 1382*7c478bd9Sstevel@tonic-gate 1383*7c478bd9Sstevel@tonic-gate void 1384*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1385*7c478bd9Sstevel@tonic-gate { 1386*7c478bd9Sstevel@tonic-gate int c, mcount; 1387*7c478bd9Sstevel@tonic-gate uid_t uid; 1388*7c478bd9Sstevel@tonic-gate uid_t orig_euid; 1389*7c478bd9Sstevel@tonic-gate char *service = NULL; 1390*7c478bd9Sstevel@tonic-gate program_name = argv[0]; 1391*7c478bd9Sstevel@tonic-gate 1392*7c478bd9Sstevel@tonic-gate mechs = __nis_get_mechanisms(FALSE); 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "fps:m:")) != -1) { 1395*7c478bd9Sstevel@tonic-gate switch (c) { 1396*7c478bd9Sstevel@tonic-gate case 'f': 1397*7c478bd9Sstevel@tonic-gate /* 1398*7c478bd9Sstevel@tonic-gate * Not documented as of on1093. 1399*7c478bd9Sstevel@tonic-gate * Temporarily supported 1400*7c478bd9Sstevel@tonic-gate */ 1401*7c478bd9Sstevel@tonic-gate force++; 1402*7c478bd9Sstevel@tonic-gate break; 1403*7c478bd9Sstevel@tonic-gate case 'p': 1404*7c478bd9Sstevel@tonic-gate makenew = FALSE; 1405*7c478bd9Sstevel@tonic-gate break; 1406*7c478bd9Sstevel@tonic-gate case 's': 1407*7c478bd9Sstevel@tonic-gate if (!service) 1408*7c478bd9Sstevel@tonic-gate service = strdup(optarg); 1409*7c478bd9Sstevel@tonic-gate else 1410*7c478bd9Sstevel@tonic-gate usage(); 1411*7c478bd9Sstevel@tonic-gate break; 1412*7c478bd9Sstevel@tonic-gate case 'm': 1413*7c478bd9Sstevel@tonic-gate if (mechs && specmech == FALSE) { 1414*7c478bd9Sstevel@tonic-gate __nis_release_mechanisms(mechs); 1415*7c478bd9Sstevel@tonic-gate mechs = NULL; 1416*7c478bd9Sstevel@tonic-gate } 1417*7c478bd9Sstevel@tonic-gate specmech = TRUE; 1418*7c478bd9Sstevel@tonic-gate addmechtolist(optarg); 1419*7c478bd9Sstevel@tonic-gate break; 1420*7c478bd9Sstevel@tonic-gate default: 1421*7c478bd9Sstevel@tonic-gate usage(); 1422*7c478bd9Sstevel@tonic-gate } 1423*7c478bd9Sstevel@tonic-gate } 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate if (optind < argc) 1426*7c478bd9Sstevel@tonic-gate usage(); 1427*7c478bd9Sstevel@tonic-gate 1428*7c478bd9Sstevel@tonic-gate dest_service = get_pk_source(service); 1429*7c478bd9Sstevel@tonic-gate 1430*7c478bd9Sstevel@tonic-gate if (!(netname = malloc(MAXNETNAMELEN + 1))) { 1431*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Malloc failure.\n", program_name); 1432*7c478bd9Sstevel@tonic-gate exit(1); 1433*7c478bd9Sstevel@tonic-gate } 1434*7c478bd9Sstevel@tonic-gate if (!__getnetnamebyuid(netname, uid = getuid())) { 1435*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: cannot generate netname for uid %d\n", 1436*7c478bd9Sstevel@tonic-gate program_name, uid); 1437*7c478bd9Sstevel@tonic-gate exit(1); 1438*7c478bd9Sstevel@tonic-gate } 1439*7c478bd9Sstevel@tonic-gate sec_domain = strdup(strchr(netname, '@') + 1); 1440*7c478bd9Sstevel@tonic-gate getdomainname(local_domain, MAXNETNAMELEN); 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate if (makenew) 1443*7c478bd9Sstevel@tonic-gate fprintf(stdout, "Generating new key for '%s'.\n", netname); 1444*7c478bd9Sstevel@tonic-gate else 1445*7c478bd9Sstevel@tonic-gate fprintf(stdout, "Reencrypting key for '%s'.\n", netname); 1446*7c478bd9Sstevel@tonic-gate 1447*7c478bd9Sstevel@tonic-gate if (mechs) { 1448*7c478bd9Sstevel@tonic-gate if (dest_service == PK_YP || dest_service == PK_FILES) { 1449*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1450*7c478bd9Sstevel@tonic-gate "%s: can not add non-DES public keys to %s, skipping.\n", 1451*7c478bd9Sstevel@tonic-gate program_name, service); 1452*7c478bd9Sstevel@tonic-gate __nis_release_mechanisms(mechs); 1453*7c478bd9Sstevel@tonic-gate mechs = NULL; 1454*7c478bd9Sstevel@tonic-gate initkeylist(TRUE); 1455*7c478bd9Sstevel@tonic-gate } else 1456*7c478bd9Sstevel@tonic-gate initkeylist(FALSE); 1457*7c478bd9Sstevel@tonic-gate } else 1458*7c478bd9Sstevel@tonic-gate initkeylist(TRUE); 1459*7c478bd9Sstevel@tonic-gate 1460*7c478bd9Sstevel@tonic-gate uid = getuid(); 1461*7c478bd9Sstevel@tonic-gate orig_euid = geteuid(); 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate /* Get password information */ 1464*7c478bd9Sstevel@tonic-gate if ((pw = getpwuid(uid)) == NULL) { 1465*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1466*7c478bd9Sstevel@tonic-gate "%s: Can not find passwd information for %d.\n", 1467*7c478bd9Sstevel@tonic-gate program_name, uid); 1468*7c478bd9Sstevel@tonic-gate exit(1); 1469*7c478bd9Sstevel@tonic-gate } 1470*7c478bd9Sstevel@tonic-gate 1471*7c478bd9Sstevel@tonic-gate /* Set eUID to user */ 1472*7c478bd9Sstevel@tonic-gate seteuid(uid); 1473*7c478bd9Sstevel@tonic-gate 1474*7c478bd9Sstevel@tonic-gate /* Obtain a list of decrypted secret keys */ 1475*7c478bd9Sstevel@tonic-gate getsecrets(); 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate /* Keylogin user if not already done */ 1478*7c478bd9Sstevel@tonic-gate if (mechs) { 1479*7c478bd9Sstevel@tonic-gate int mcount; 1480*7c478bd9Sstevel@tonic-gate 1481*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 1482*7c478bd9Sstevel@tonic-gate keylen_t keylen = CURMECH->keylen; 1483*7c478bd9Sstevel@tonic-gate algtype_t algtype = CURMECH->algtype; 1484*7c478bd9Sstevel@tonic-gate 1485*7c478bd9Sstevel@tonic-gate if (!key_secretkey_is_set_g(keylen, algtype) && 1486*7c478bd9Sstevel@tonic-gate slist[mcount]) { 1487*7c478bd9Sstevel@tonic-gate keylogin(CURMECH->keylen, CURMECH->algtype); 1488*7c478bd9Sstevel@tonic-gate if ((uid == 0) && (makenew == FALSE)) 1489*7c478bd9Sstevel@tonic-gate write_rootkey(slist[mcount], 1490*7c478bd9Sstevel@tonic-gate VALID_ALIAS(CURMECH->alias) ? 1491*7c478bd9Sstevel@tonic-gate CURMECH->alias : 1492*7c478bd9Sstevel@tonic-gate "", 1493*7c478bd9Sstevel@tonic-gate keylen, algtype); 1494*7c478bd9Sstevel@tonic-gate } 1495*7c478bd9Sstevel@tonic-gate } 1496*7c478bd9Sstevel@tonic-gate } else { 1497*7c478bd9Sstevel@tonic-gate assert(slist[0]); 1498*7c478bd9Sstevel@tonic-gate if (!key_secretkey_is_set()) { 1499*7c478bd9Sstevel@tonic-gate keylogin_des(); 1500*7c478bd9Sstevel@tonic-gate if ((uid == 0) && (makenew == FALSE)) 1501*7c478bd9Sstevel@tonic-gate write_rootkey(slist[0], "des", 192, 0); 1502*7c478bd9Sstevel@tonic-gate } 1503*7c478bd9Sstevel@tonic-gate } 1504*7c478bd9Sstevel@tonic-gate 1505*7c478bd9Sstevel@tonic-gate /* Set eUID back to root */ 1506*7c478bd9Sstevel@tonic-gate (void) seteuid(orig_euid); 1507*7c478bd9Sstevel@tonic-gate 1508*7c478bd9Sstevel@tonic-gate /* 1509*7c478bd9Sstevel@tonic-gate * Call getspnam() after the keylogin has been done so we have 1510*7c478bd9Sstevel@tonic-gate * the best chance of having read access to the encrypted pw. 1511*7c478bd9Sstevel@tonic-gate * 1512*7c478bd9Sstevel@tonic-gate * The eUID must be 0 for the getspnam() so the name service 1513*7c478bd9Sstevel@tonic-gate * switch can handle the following eUID sensitive cases: 1514*7c478bd9Sstevel@tonic-gate * 1515*7c478bd9Sstevel@tonic-gate * files/compat: read /etc/shadow 1516*7c478bd9Sstevel@tonic-gate * 1517*7c478bd9Sstevel@tonic-gate * nisplus: try to read the encrypted pw as the root 1518*7c478bd9Sstevel@tonic-gate * principal and if that fails, and if the 1519*7c478bd9Sstevel@tonic-gate * user's secret key is set, seteuid(user) 1520*7c478bd9Sstevel@tonic-gate * and retry the read. 1521*7c478bd9Sstevel@tonic-gate */ 1522*7c478bd9Sstevel@tonic-gate if ((spw = getspnam(pw->pw_name)) == 0) { 1523*7c478bd9Sstevel@tonic-gate 1524*7c478bd9Sstevel@tonic-gate /* Set eUID back to user */ 1525*7c478bd9Sstevel@tonic-gate (void) seteuid(uid); 1526*7c478bd9Sstevel@tonic-gate 1527*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1528*7c478bd9Sstevel@tonic-gate "%s: cannot find shadow entry for %s.\n", 1529*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 1530*7c478bd9Sstevel@tonic-gate exit(1); 1531*7c478bd9Sstevel@tonic-gate } 1532*7c478bd9Sstevel@tonic-gate 1533*7c478bd9Sstevel@tonic-gate /* Set eUID back to user */ 1534*7c478bd9Sstevel@tonic-gate (void) seteuid(uid); 1535*7c478bd9Sstevel@tonic-gate 1536*7c478bd9Sstevel@tonic-gate if (strcmp(spw->sp_pwdp, "*NP*") == 0) { 1537*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1538*7c478bd9Sstevel@tonic-gate "%s: do not have read access to the passwd field for %s\n", 1539*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 1540*7c478bd9Sstevel@tonic-gate exit(1); 1541*7c478bd9Sstevel@tonic-gate } 1542*7c478bd9Sstevel@tonic-gate 1543*7c478bd9Sstevel@tonic-gate /* 1544*7c478bd9Sstevel@tonic-gate * force will be only supported for a while 1545*7c478bd9Sstevel@tonic-gate * -- it is NOT documented as of s1093 1546*7c478bd9Sstevel@tonic-gate */ 1547*7c478bd9Sstevel@tonic-gate if (force) { 1548*7c478bd9Sstevel@tonic-gate char *prompt = "Please enter New password:"; 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate login_pw = getpass(prompt); 1551*7c478bd9Sstevel@tonic-gate if (!login_pw || !(strlen(login_pw))) { 1552*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n", 1553*7c478bd9Sstevel@tonic-gate program_name, pw->pw_name); 1554*7c478bd9Sstevel@tonic-gate exit(1); 1555*7c478bd9Sstevel@tonic-gate } 1556*7c478bd9Sstevel@tonic-gate } else { 1557*7c478bd9Sstevel@tonic-gate /* 1558*7c478bd9Sstevel@tonic-gate * Reconsile rpc_pws and login_pw. 1559*7c478bd9Sstevel@tonic-gate * 1560*7c478bd9Sstevel@tonic-gate * This function will either return with login_pw == rpc_pw 1561*7c478bd9Sstevel@tonic-gate * (and thus, the new pw to encrypt keys) or it will exit. 1562*7c478bd9Sstevel@tonic-gate */ 1563*7c478bd9Sstevel@tonic-gate cmp_passwd(); 1564*7c478bd9Sstevel@tonic-gate } 1565*7c478bd9Sstevel@tonic-gate 1566*7c478bd9Sstevel@tonic-gate if (makenew) 1567*7c478bd9Sstevel@tonic-gate makenewkeys(); 1568*7c478bd9Sstevel@tonic-gate else 1569*7c478bd9Sstevel@tonic-gate getpublics(); 1570*7c478bd9Sstevel@tonic-gate 1571*7c478bd9Sstevel@tonic-gate encryptkeys(); 1572*7c478bd9Sstevel@tonic-gate 1573*7c478bd9Sstevel@tonic-gate storekeys(); 1574*7c478bd9Sstevel@tonic-gate 1575*7c478bd9Sstevel@tonic-gate if (makenew) { 1576*7c478bd9Sstevel@tonic-gate if (uid == 0) { 1577*7c478bd9Sstevel@tonic-gate if (mechs) { 1578*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) { 1579*7c478bd9Sstevel@tonic-gate if (!slist[mcount]) 1580*7c478bd9Sstevel@tonic-gate continue; 1581*7c478bd9Sstevel@tonic-gate write_rootkey(slist[mcount], 1582*7c478bd9Sstevel@tonic-gate CURMECH->alias, 1583*7c478bd9Sstevel@tonic-gate CURMECH->keylen, 1584*7c478bd9Sstevel@tonic-gate CURMECH->algtype); 1585*7c478bd9Sstevel@tonic-gate } 1586*7c478bd9Sstevel@tonic-gate } else { 1587*7c478bd9Sstevel@tonic-gate assert(slist[0]); 1588*7c478bd9Sstevel@tonic-gate write_rootkey(slist[0], "des", 192, 0); 1589*7c478bd9Sstevel@tonic-gate } 1590*7c478bd9Sstevel@tonic-gate } 1591*7c478bd9Sstevel@tonic-gate if (mechs) { 1592*7c478bd9Sstevel@tonic-gate for (mcount = 0; CURMECH; mcount++) 1593*7c478bd9Sstevel@tonic-gate keylogin(CURMECH->keylen, 1594*7c478bd9Sstevel@tonic-gate CURMECH->algtype); 1595*7c478bd9Sstevel@tonic-gate } else 1596*7c478bd9Sstevel@tonic-gate keylogin_des(); 1597*7c478bd9Sstevel@tonic-gate } 1598*7c478bd9Sstevel@tonic-gate exit(0); 1599*7c478bd9Sstevel@tonic-gate } 1600