1*431deaa0Shylee /* 2*431deaa0Shylee * CDDL HEADER START 3*431deaa0Shylee * 4*431deaa0Shylee * The contents of this file are subject to the terms of the 5*431deaa0Shylee * Common Development and Distribution License (the "License"). 6*431deaa0Shylee * You may not use this file except in compliance with the License. 7*431deaa0Shylee * 8*431deaa0Shylee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*431deaa0Shylee * or http://www.opensolaris.org/os/licensing. 10*431deaa0Shylee * See the License for the specific language governing permissions 11*431deaa0Shylee * and limitations under the License. 12*431deaa0Shylee * 13*431deaa0Shylee * When distributing Covered Code, include this CDDL HEADER in each 14*431deaa0Shylee * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*431deaa0Shylee * If applicable, add the following below this CDDL HEADER, with the 16*431deaa0Shylee * fields enclosed by brackets "[]" replaced with your own identifying 17*431deaa0Shylee * information: Portions Copyright [yyyy] [name of copyright owner] 18*431deaa0Shylee * 19*431deaa0Shylee * CDDL HEADER END 20*431deaa0Shylee * 21*431deaa0Shylee * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 22*431deaa0Shylee * Use is subject to license terms. 23*431deaa0Shylee */ 24*431deaa0Shylee 25*431deaa0Shylee #pragma ident "%Z%%M% %I% %E% SMI" 26*431deaa0Shylee 27*431deaa0Shylee #include <stdio.h> 28*431deaa0Shylee #include <strings.h> 29*431deaa0Shylee #include <ctype.h> 30*431deaa0Shylee #include <libgen.h> 31*431deaa0Shylee #include <libintl.h> 32*431deaa0Shylee #include <errno.h> 33*431deaa0Shylee #include <kmfapiP.h> 34*431deaa0Shylee #include <sys/stat.h> 35*431deaa0Shylee #include <sys/param.h> 36*431deaa0Shylee #include <cryptoutil.h> 37*431deaa0Shylee #include "util.h" 38*431deaa0Shylee 39*431deaa0Shylee static int err; /* To store errno which may be overwritten by gettext() */ 40*431deaa0Shylee 41*431deaa0Shylee int 42*431deaa0Shylee kc_uninstall(int argc, char *argv[]) 43*431deaa0Shylee { 44*431deaa0Shylee int rv = KC_OK; 45*431deaa0Shylee int opt; 46*431deaa0Shylee extern int optind_av; 47*431deaa0Shylee extern char *optarg_av; 48*431deaa0Shylee char *keystore_name = NULL; 49*431deaa0Shylee conf_entry_t *entry = NULL; 50*431deaa0Shylee FILE *pfile = NULL; 51*431deaa0Shylee FILE *pfile_tmp = NULL; 52*431deaa0Shylee char tmpfile_name[MAXPATHLEN]; 53*431deaa0Shylee char buffer[MAXPATHLEN]; 54*431deaa0Shylee char buffer2[MAXPATHLEN]; 55*431deaa0Shylee boolean_t found; 56*431deaa0Shylee boolean_t in_package; 57*431deaa0Shylee 58*431deaa0Shylee while ((opt = getopt_av(argc, argv, "k:(keystore)")) != EOF) { 59*431deaa0Shylee switch (opt) { 60*431deaa0Shylee case 'k': 61*431deaa0Shylee if (keystore_name != NULL) 62*431deaa0Shylee rv = KC_ERR_USAGE; 63*431deaa0Shylee else { 64*431deaa0Shylee keystore_name = get_string(optarg_av, &rv); 65*431deaa0Shylee if (keystore_name == NULL) { 66*431deaa0Shylee (void) fprintf(stderr, gettext( 67*431deaa0Shylee "Error keystore input.\n")); 68*431deaa0Shylee } 69*431deaa0Shylee } 70*431deaa0Shylee break; 71*431deaa0Shylee default: 72*431deaa0Shylee (void) fprintf(stderr, 73*431deaa0Shylee gettext("Error input option.\n")); 74*431deaa0Shylee rv = KC_ERR_USAGE; 75*431deaa0Shylee break; 76*431deaa0Shylee } 77*431deaa0Shylee if (rv != KC_OK) 78*431deaa0Shylee goto out; 79*431deaa0Shylee } 80*431deaa0Shylee 81*431deaa0Shylee /* No additional args allowed. */ 82*431deaa0Shylee argc -= optind_av; 83*431deaa0Shylee if (argc) { 84*431deaa0Shylee (void) fprintf(stderr, 85*431deaa0Shylee gettext("Error input option\n")); 86*431deaa0Shylee rv = KC_ERR_USAGE; 87*431deaa0Shylee goto out; 88*431deaa0Shylee } 89*431deaa0Shylee 90*431deaa0Shylee if (keystore_name == NULL) { 91*431deaa0Shylee (void) fprintf(stderr, 92*431deaa0Shylee gettext("Error input option\n")); 93*431deaa0Shylee rv = KC_ERR_USAGE; 94*431deaa0Shylee goto out; 95*431deaa0Shylee } 96*431deaa0Shylee 97*431deaa0Shylee if (strcasecmp(keystore_name, "nss") == 0 || 98*431deaa0Shylee strcasecmp(keystore_name, "pkcs11") == 0 || 99*431deaa0Shylee strcasecmp(keystore_name, "file") == 0) { 100*431deaa0Shylee (void) fprintf(stderr, 101*431deaa0Shylee gettext("Can not uninstall the built-in keystore %s\n"), 102*431deaa0Shylee keystore_name); 103*431deaa0Shylee rv = KC_ERR_UNINSTALL; 104*431deaa0Shylee goto out; 105*431deaa0Shylee } 106*431deaa0Shylee 107*431deaa0Shylee entry = get_keystore_entry(keystore_name); 108*431deaa0Shylee if (entry == NULL) { 109*431deaa0Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"), 110*431deaa0Shylee keystore_name); 111*431deaa0Shylee rv = KC_ERR_USAGE; 112*431deaa0Shylee goto out; 113*431deaa0Shylee } 114*431deaa0Shylee 115*431deaa0Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { 116*431deaa0Shylee err = errno; 117*431deaa0Shylee (void) fprintf(stderr, 118*431deaa0Shylee gettext("failed to update the configuration - %s\n"), 119*431deaa0Shylee strerror(err)); 120*431deaa0Shylee rv = KC_ERR_ACCESS; 121*431deaa0Shylee goto out; 122*431deaa0Shylee } 123*431deaa0Shylee 124*431deaa0Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 125*431deaa0Shylee err = errno; 126*431deaa0Shylee (void) fprintf(stderr, 127*431deaa0Shylee gettext("failed to lock the configuration - %s\n"), 128*431deaa0Shylee strerror(err)); 129*431deaa0Shylee rv = KC_ERR_UNINSTALL; 130*431deaa0Shylee goto out; 131*431deaa0Shylee } 132*431deaa0Shylee 133*431deaa0Shylee /* 134*431deaa0Shylee * Create a temporary file in the /etc/crypto directory. 135*431deaa0Shylee */ 136*431deaa0Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); 137*431deaa0Shylee if (mkstemp(tmpfile_name) == -1) { 138*431deaa0Shylee err = errno; 139*431deaa0Shylee (void) fprintf(stderr, 140*431deaa0Shylee gettext("failed to create a temporary file - %s\n"), 141*431deaa0Shylee strerror(err)); 142*431deaa0Shylee rv = KC_ERR_UNINSTALL; 143*431deaa0Shylee goto out; 144*431deaa0Shylee } 145*431deaa0Shylee 146*431deaa0Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 147*431deaa0Shylee err = errno; 148*431deaa0Shylee (void) fprintf(stderr, 149*431deaa0Shylee gettext("failed to open a temporary file - %s\n"), 150*431deaa0Shylee strerror(err)); 151*431deaa0Shylee rv = KC_ERR_UNINSTALL; 152*431deaa0Shylee goto out; 153*431deaa0Shylee } 154*431deaa0Shylee 155*431deaa0Shylee /* 156*431deaa0Shylee * Loop thru the config file. If the plugin to be uninstalled is in 157*431deaa0Shylee * a package, then just comment it off. 158*431deaa0Shylee */ 159*431deaa0Shylee in_package = B_FALSE; 160*431deaa0Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 161*431deaa0Shylee found = B_FALSE; 162*431deaa0Shylee if (buffer[0] != ' ' && buffer[0] != '\n' && 163*431deaa0Shylee buffer[0] != '\t') { 164*431deaa0Shylee if (strstr(buffer, " Start ") != NULL) { 165*431deaa0Shylee in_package = B_TRUE; 166*431deaa0Shylee } else if (strstr(buffer, " End ") != NULL) { 167*431deaa0Shylee in_package = B_FALSE; 168*431deaa0Shylee } else if (buffer[0] != '#') { 169*431deaa0Shylee char *name; 170*431deaa0Shylee int len; 171*431deaa0Shylee 172*431deaa0Shylee /* 173*431deaa0Shylee * make a copy of the original buffer to 174*431deaa0Shylee * buffer2. Also get rid of the trailing 175*431deaa0Shylee * '\n' from buffer2. 176*431deaa0Shylee */ 177*431deaa0Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN); 178*431deaa0Shylee /* get rid of trailing '\n' */ 179*431deaa0Shylee len = strlen(buffer2); 180*431deaa0Shylee if (buffer2[len-1] == '\n') { 181*431deaa0Shylee len--; 182*431deaa0Shylee } 183*431deaa0Shylee buffer2[len] = '\0'; 184*431deaa0Shylee 185*431deaa0Shylee if ((name = strtok(buffer2, SEP_COLON)) == 186*431deaa0Shylee NULL) { 187*431deaa0Shylee rv = KC_ERR_UNINSTALL; 188*431deaa0Shylee goto out; 189*431deaa0Shylee } 190*431deaa0Shylee 191*431deaa0Shylee if (strcmp(keystore_name, name) == 0) 192*431deaa0Shylee found = B_TRUE; 193*431deaa0Shylee } 194*431deaa0Shylee } 195*431deaa0Shylee 196*431deaa0Shylee if (found) { 197*431deaa0Shylee /* 198*431deaa0Shylee * If found and not in_package, then don't write 199*431deaa0Shylee * this line to the result file. 200*431deaa0Shylee */ 201*431deaa0Shylee if (in_package) { 202*431deaa0Shylee (void) snprintf(buffer2, sizeof (buffer2), 203*431deaa0Shylee "%s%s", "#", buffer); 204*431deaa0Shylee 205*431deaa0Shylee if (fputs(buffer2, pfile_tmp) == EOF) { 206*431deaa0Shylee rv = KC_ERR_UNINSTALL; 207*431deaa0Shylee goto out; 208*431deaa0Shylee } 209*431deaa0Shylee } 210*431deaa0Shylee } else { 211*431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 212*431deaa0Shylee rv = KC_ERR_UNINSTALL; 213*431deaa0Shylee goto out; 214*431deaa0Shylee } 215*431deaa0Shylee } 216*431deaa0Shylee } 217*431deaa0Shylee 218*431deaa0Shylee out: 219*431deaa0Shylee if (pfile != NULL) 220*431deaa0Shylee (void) fclose(pfile); 221*431deaa0Shylee 222*431deaa0Shylee if (rv != KC_OK && pfile_tmp != NULL) 223*431deaa0Shylee (void) unlink(tmpfile_name); 224*431deaa0Shylee 225*431deaa0Shylee if (pfile_tmp != NULL) 226*431deaa0Shylee (void) fclose(pfile_tmp); 227*431deaa0Shylee 228*431deaa0Shylee if (rv == KC_OK) { 229*431deaa0Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { 230*431deaa0Shylee err = errno; 231*431deaa0Shylee (void) fprintf(stderr, gettext( 232*431deaa0Shylee "failed to update the configuration - %s"), 233*431deaa0Shylee strerror(err)); 234*431deaa0Shylee return (KC_ERR_UNINSTALL); 235*431deaa0Shylee } 236*431deaa0Shylee 237*431deaa0Shylee if (chmod(_PATH_KMF_CONF, 238*431deaa0Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 239*431deaa0Shylee err = errno; 240*431deaa0Shylee (void) fprintf(stderr, gettext( 241*431deaa0Shylee "failed to update the configuration - %s\n"), 242*431deaa0Shylee strerror(err)); 243*431deaa0Shylee return (KC_ERR_UNINSTALL); 244*431deaa0Shylee } 245*431deaa0Shylee } 246*431deaa0Shylee 247*431deaa0Shylee return (rv); 248*431deaa0Shylee } 249