13089Swyllys /* 23089Swyllys * CDDL HEADER START 33089Swyllys * 43089Swyllys * The contents of this file are subject to the terms of the 53089Swyllys * Common Development and Distribution License (the "License"). 63089Swyllys * You may not use this file except in compliance with the License. 73089Swyllys * 83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93089Swyllys * or http://www.opensolaris.org/os/licensing. 103089Swyllys * See the License for the specific language governing permissions 113089Swyllys * and limitations under the License. 123089Swyllys * 133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each 143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153089Swyllys * If applicable, add the following below this CDDL HEADER, with the 163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying 173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner] 183089Swyllys * 193089Swyllys * CDDL HEADER END 203089Swyllys * 215051Swyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 223089Swyllys * Use is subject to license terms. 233089Swyllys */ 243089Swyllys 253089Swyllys #pragma ident "%Z%%M% %I% %E% SMI" 263089Swyllys 273089Swyllys #include <stdio.h> 283089Swyllys #include <strings.h> 293089Swyllys #include <ctype.h> 303089Swyllys #include <libgen.h> 313089Swyllys #include <libintl.h> 323089Swyllys #include <errno.h> 333089Swyllys #include <kmfapiP.h> 343089Swyllys #include <cryptoutil.h> 35*5626Shylee #include <sys/stat.h> 36*5626Shylee #include <sys/param.h> 373089Swyllys #include "util.h" 383089Swyllys 393089Swyllys #define KC_IGNORE_DATE 0x0000001 403089Swyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002 413089Swyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004 423089Swyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008 433089Swyllys #define KC_TA_NAME 0x0000010 443089Swyllys #define KC_TA_SERIAL 0x0000020 453089Swyllys #define KC_OCSP_RESPONDER_URI 0x0000040 463089Swyllys #define KC_OCSP_PROXY 0x0000080 473089Swyllys #define KC_OCSP_URI_FROM_CERT 0x0000100 483089Swyllys #define KC_OCSP_RESP_LIFETIME 0x0000200 493089Swyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 503089Swyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800 513089Swyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000 523089Swyllys #define KC_OCSP_NONE 0x0002000 533089Swyllys #define KC_CRL_BASEFILENAME 0x0004000 543089Swyllys #define KC_CRL_DIRECTORY 0x0008000 553089Swyllys #define KC_CRL_GET_URI 0x0010000 563089Swyllys #define KC_CRL_PROXY 0x0020000 573089Swyllys #define KC_CRL_IGNORE_SIGN 0x0040000 583089Swyllys #define KC_CRL_IGNORE_DATE 0x0080000 593089Swyllys #define KC_CRL_NONE 0x0100000 603089Swyllys #define KC_KEYUSAGE 0x0200000 613089Swyllys #define KC_KEYUSAGE_NONE 0x0400000 623089Swyllys #define KC_EKUS 0x0800000 633089Swyllys #define KC_EKUS_NONE 0x1000000 643089Swyllys 65*5626Shylee static int err; /* To store errno which may be overwritten by gettext() */ 66*5626Shylee 67*5626Shylee 683089Swyllys int 69*5626Shylee kc_modify_policy(int argc, char *argv[]) 703089Swyllys { 713089Swyllys KMF_RETURN ret; 723089Swyllys int rv = KC_OK; 733089Swyllys int opt; 743089Swyllys extern int optind_av; 753089Swyllys extern char *optarg_av; 763089Swyllys char *filename = NULL; 773089Swyllys uint32_t flags = 0; 783089Swyllys boolean_t ocsp_none_opt = B_FALSE; 793089Swyllys boolean_t crl_none_opt = B_FALSE; 803089Swyllys boolean_t ku_none_opt = B_FALSE; 813089Swyllys boolean_t eku_none_opt = B_FALSE; 823089Swyllys int ocsp_set_attr = 0; 833089Swyllys int crl_set_attr = 0; 843089Swyllys KMF_POLICY_RECORD oplc, plc; 853089Swyllys 863089Swyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 873089Swyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); 883089Swyllys 893089Swyllys while ((opt = getopt_av(argc, argv, 905051Swyllys "i:(dbfile)" 915051Swyllys "p:(policy)" 925051Swyllys "d:(ignore-date)" 935051Swyllys "e:(ignore-unknown-eku)" 945051Swyllys "a:(ignore-trust-anchor)" 955051Swyllys "v:(validity-adjusttime)" 965051Swyllys "t:(ta-name)" 975051Swyllys "s:(ta-serial)" 985051Swyllys "o:(ocsp-responder)" 995051Swyllys "P:(ocsp-proxy)" 1005051Swyllys "r:(ocsp-use-cert-responder)" 1015051Swyllys "T:(ocsp-response-lifetime)" 1025051Swyllys "R:(ocsp-ignore-response-sign)" 1035051Swyllys "n:(ocsp-responder-cert-name)" 1045051Swyllys "A:(ocsp-responder-cert-serial)" 1055051Swyllys "y:(ocsp-none)" 1065051Swyllys "c:(crl-basefilename)" 1075051Swyllys "I:(crl-directory)" 1085051Swyllys "g:(crl-get-crl-uri)" 1095051Swyllys "X:(crl-proxy)" 1105051Swyllys "S:(crl-ignore-crl-sign)" 1115051Swyllys "D:(crl-ignore-crl-date)" 1125051Swyllys "z:(crl-none)" 1135051Swyllys "u:(keyusage)" 1145051Swyllys "Y:(keyusage-none)" 1155051Swyllys "E:(ekunames)" 1165051Swyllys "O:(ekuoids)" 1175051Swyllys "Z:(eku-none)")) != EOF) { 1183089Swyllys switch (opt) { 1193089Swyllys case 'i': 1203089Swyllys filename = get_string(optarg_av, &rv); 1213089Swyllys if (filename == NULL) { 1223089Swyllys (void) fprintf(stderr, 1233089Swyllys gettext("Error dbfile input.\n")); 1243089Swyllys } 1253089Swyllys break; 1263089Swyllys case 'p': 1273089Swyllys plc.name = get_string(optarg_av, &rv); 1283089Swyllys if (plc.name == NULL) { 1293089Swyllys (void) fprintf(stderr, 1303089Swyllys gettext("Error policy name.\n")); 1313089Swyllys } 1323089Swyllys break; 1333089Swyllys case 'd': 1343089Swyllys plc.ignore_date = get_boolean(optarg_av); 1353089Swyllys if (plc.ignore_date == -1) { 1363089Swyllys (void) fprintf(stderr, 1373089Swyllys gettext("Error boolean input.\n")); 1383089Swyllys rv = KC_ERR_USAGE; 1393089Swyllys } else { 1403089Swyllys flags |= KC_IGNORE_DATE; 1413089Swyllys } 1423089Swyllys break; 1433089Swyllys case 'e': 1443089Swyllys plc.ignore_unknown_ekus = 1453089Swyllys get_boolean(optarg_av); 1463089Swyllys if (plc.ignore_unknown_ekus == -1) { 1473089Swyllys (void) fprintf(stderr, 1483089Swyllys gettext("Error boolean input.\n")); 1493089Swyllys rv = KC_ERR_USAGE; 1503089Swyllys } else { 1513089Swyllys flags |= KC_IGNORE_UNKNOWN_EKUS; 1523089Swyllys } 1533089Swyllys break; 1543089Swyllys case 'a': 1553089Swyllys plc.ignore_trust_anchor = 1563089Swyllys get_boolean(optarg_av); 1573089Swyllys if (plc.ignore_trust_anchor == -1) { 1583089Swyllys (void) fprintf(stderr, 1593089Swyllys gettext("Error boolean input.\n")); 1603089Swyllys rv = KC_ERR_USAGE; 1613089Swyllys } else { 1623089Swyllys flags |= KC_IGNORE_TRUST_ANCHOR; 1633089Swyllys } 1643089Swyllys break; 1653089Swyllys case 'v': 1663089Swyllys plc.validity_adjusttime = 1673089Swyllys get_string(optarg_av, &rv); 1683089Swyllys if (plc.validity_adjusttime == NULL) { 1693089Swyllys (void) fprintf(stderr, 1703089Swyllys gettext("Error time input.\n")); 1713089Swyllys } else { 1723089Swyllys uint32_t adj; 1733089Swyllys /* for syntax checking */ 1743089Swyllys if (str2lifetime( 1753089Swyllys plc.validity_adjusttime, 1763089Swyllys &adj) < 0) { 1773089Swyllys (void) fprintf(stderr, 1783089Swyllys gettext("Error time " 1793089Swyllys "input.\n")); 1803089Swyllys rv = KC_ERR_USAGE; 1813089Swyllys } else { 1823089Swyllys flags |= KC_VALIDITY_ADJUSTTIME; 1833089Swyllys } 1843089Swyllys } 1853089Swyllys break; 1863089Swyllys case 't': 1873089Swyllys plc.ta_name = get_string(optarg_av, &rv); 1883089Swyllys if (plc.ta_name == NULL) { 1893089Swyllys (void) fprintf(stderr, 1903089Swyllys gettext("Error name input.\n")); 1913089Swyllys } else { 1923089Swyllys KMF_X509_NAME taDN; 1933089Swyllys /* for syntax checking */ 1945051Swyllys if (kmf_dn_parser(plc.ta_name, 1953089Swyllys &taDN) != KMF_OK) { 1963089Swyllys (void) fprintf(stderr, 1973089Swyllys gettext("Error name " 1983089Swyllys "input.\n")); 1993089Swyllys rv = KC_ERR_USAGE; 2003089Swyllys } else { 2015051Swyllys kmf_free_dn(&taDN); 2023089Swyllys flags |= KC_TA_NAME; 2033089Swyllys } 2043089Swyllys } 2053089Swyllys break; 2063089Swyllys case 's': 2073089Swyllys plc.ta_serial = get_string(optarg_av, &rv); 2083089Swyllys if (plc.ta_serial == NULL) { 2093089Swyllys (void) fprintf(stderr, 2103089Swyllys gettext("Error serial input.\n")); 2113089Swyllys } else { 2123089Swyllys uchar_t *bytes = NULL; 2133089Swyllys size_t bytelen; 2143089Swyllys 2155051Swyllys ret = kmf_hexstr_to_bytes( 2163089Swyllys (uchar_t *)plc.ta_serial, 2173089Swyllys &bytes, &bytelen); 2183089Swyllys if (ret != KMF_OK || bytes == NULL) { 2193089Swyllys (void) fprintf(stderr, 2203089Swyllys gettext("serial number " 2213089Swyllys "must be specified as a " 2223089Swyllys "hex number " 2233089Swyllys "(ex: 0x0102030405" 2243089Swyllys "ffeeddee)\n")); 2253089Swyllys rv = KC_ERR_USAGE; 2263089Swyllys break; 2273089Swyllys } 2283089Swyllys if (bytes != NULL) 2293089Swyllys free(bytes); 2303089Swyllys flags |= KC_TA_SERIAL; 2313089Swyllys } 2323089Swyllys break; 2333089Swyllys case 'o': 2343089Swyllys plc.VAL_OCSP_RESPONDER_URI = 2355051Swyllys get_string(optarg_av, &rv); 2363089Swyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 2373089Swyllys (void) fprintf(stderr, 2383089Swyllys gettext("Error responder " 2393089Swyllys "input.\n")); 2403089Swyllys } else { 2413089Swyllys flags |= KC_OCSP_RESPONDER_URI; 2423089Swyllys ocsp_set_attr++; 2433089Swyllys } 2443089Swyllys break; 2453089Swyllys case 'P': 2463089Swyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 2473089Swyllys if (plc.VAL_OCSP_PROXY == NULL) { 2483089Swyllys (void) fprintf(stderr, 2493089Swyllys gettext("Error proxy input.\n")); 2503089Swyllys } else { 2513089Swyllys flags |= KC_OCSP_PROXY; 2523089Swyllys ocsp_set_attr++; 2533089Swyllys } 2543089Swyllys break; 2553089Swyllys case 'r': 2563089Swyllys plc.VAL_OCSP_URI_FROM_CERT = 2573089Swyllys get_boolean(optarg_av); 2583089Swyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 2593089Swyllys (void) fprintf(stderr, 2603089Swyllys gettext("Error boolean input.\n")); 2613089Swyllys rv = KC_ERR_USAGE; 2623089Swyllys } else { 2633089Swyllys flags |= KC_OCSP_URI_FROM_CERT; 2643089Swyllys ocsp_set_attr++; 2653089Swyllys } 2663089Swyllys break; 2673089Swyllys case 'T': 2683089Swyllys plc.VAL_OCSP_RESP_LIFETIME = 2693089Swyllys get_string(optarg_av, &rv); 2703089Swyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 2713089Swyllys (void) fprintf(stderr, 2723089Swyllys gettext("Error time input.\n")); 2733089Swyllys } else { 2743089Swyllys uint32_t adj; 2753089Swyllys /* for syntax checking */ 2763089Swyllys if (str2lifetime( 2773089Swyllys plc.VAL_OCSP_RESP_LIFETIME, 2783089Swyllys &adj) < 0) { 2793089Swyllys (void) fprintf(stderr, 2803089Swyllys gettext("Error time " 2813089Swyllys "input.\n")); 2823089Swyllys rv = KC_ERR_USAGE; 2833089Swyllys } else { 2843089Swyllys flags |= KC_OCSP_RESP_LIFETIME; 2853089Swyllys ocsp_set_attr++; 2863089Swyllys } 2873089Swyllys } 2883089Swyllys break; 2893089Swyllys case 'R': 2903089Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 2913089Swyllys get_boolean(optarg_av); 2923089Swyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 2933089Swyllys (void) fprintf(stderr, 2943089Swyllys gettext("Error boolean input.\n")); 2953089Swyllys rv = KC_ERR_USAGE; 2963089Swyllys } else { 2973089Swyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 2983089Swyllys ocsp_set_attr++; 2993089Swyllys } 3003089Swyllys break; 3013089Swyllys case 'n': 3023089Swyllys plc.VAL_OCSP_RESP_CERT_NAME = 3033089Swyllys get_string(optarg_av, &rv); 3043089Swyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 3053089Swyllys (void) fprintf(stderr, 3063089Swyllys gettext("Error name input.\n")); 3073089Swyllys } else { 3083089Swyllys KMF_X509_NAME respDN; 3093089Swyllys /* for syntax checking */ 3105051Swyllys if (kmf_dn_parser( 3113089Swyllys plc.VAL_OCSP_RESP_CERT_NAME, 3123089Swyllys &respDN) != KMF_OK) { 3133089Swyllys (void) fprintf(stderr, 3143089Swyllys gettext("Error name " 3153089Swyllys "input.\n")); 3163089Swyllys rv = KC_ERR_USAGE; 3173089Swyllys } else { 3185051Swyllys kmf_free_dn(&respDN); 3193089Swyllys flags |= KC_OCSP_RESP_CERT_NAME; 3203089Swyllys ocsp_set_attr++; 3213089Swyllys } 3223089Swyllys } 3233089Swyllys break; 3243089Swyllys case 'A': 3253089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 3263089Swyllys get_string(optarg_av, &rv); 3273089Swyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 3283089Swyllys (void) fprintf(stderr, 3293089Swyllys gettext("Error serial input.\n")); 3303089Swyllys } else { 3313089Swyllys uchar_t *bytes = NULL; 3323089Swyllys size_t bytelen; 3333089Swyllys 3345051Swyllys ret = kmf_hexstr_to_bytes((uchar_t *) 3353089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 3363089Swyllys &bytes, &bytelen); 3373089Swyllys if (ret != KMF_OK || bytes == NULL) { 3383089Swyllys (void) fprintf(stderr, 3393089Swyllys gettext("serial number " 3403089Swyllys "must be specified as a " 3413089Swyllys "hex number " 3423089Swyllys "(ex: 0x0102030405" 3433089Swyllys "ffeeddee)\n")); 3443089Swyllys rv = KC_ERR_USAGE; 3453089Swyllys break; 3463089Swyllys } 3473089Swyllys if (bytes != NULL) 3483089Swyllys free(bytes); 3493089Swyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 3503089Swyllys ocsp_set_attr++; 3513089Swyllys } 3523089Swyllys break; 3533089Swyllys case 'y': 3543089Swyllys ocsp_none_opt = get_boolean(optarg_av); 3553089Swyllys if (ocsp_none_opt == -1) { 3563089Swyllys (void) fprintf(stderr, 3573089Swyllys gettext("Error boolean input.\n")); 3583089Swyllys rv = KC_ERR_USAGE; 3593089Swyllys } else { 3603089Swyllys flags |= KC_OCSP_NONE; 3613089Swyllys } 3623089Swyllys break; 3633089Swyllys case 'c': 3643089Swyllys plc.VAL_CRL_BASEFILENAME = 3653089Swyllys get_string(optarg_av, &rv); 3663089Swyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 3673089Swyllys (void) fprintf(stderr, gettext( 3683089Swyllys "Error basefilename input.\n")); 3693089Swyllys } else { 3703089Swyllys flags |= KC_CRL_BASEFILENAME; 3713089Swyllys crl_set_attr++; 3723089Swyllys } 3733089Swyllys break; 3743089Swyllys case 'I': 3753089Swyllys plc.VAL_CRL_DIRECTORY = 3763089Swyllys get_string(optarg_av, &rv); 3773089Swyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 3783089Swyllys (void) fprintf(stderr, 3793089Swyllys gettext("Error boolean input.\n")); 3803089Swyllys } else { 3813089Swyllys flags |= KC_CRL_DIRECTORY; 3823089Swyllys crl_set_attr++; 3833089Swyllys } 3843089Swyllys break; 3853089Swyllys case 'g': 3863089Swyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 3873089Swyllys if (plc.VAL_CRL_GET_URI == -1) { 3883089Swyllys (void) fprintf(stderr, 3893089Swyllys gettext("Error boolean input.\n")); 3903089Swyllys rv = KC_ERR_USAGE; 3913089Swyllys } else { 3923089Swyllys flags |= KC_CRL_GET_URI; 3933089Swyllys crl_set_attr++; 3943089Swyllys } 3953089Swyllys break; 3963089Swyllys case 'X': 3973089Swyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 3983089Swyllys if (plc.VAL_CRL_PROXY == NULL) { 3993089Swyllys (void) fprintf(stderr, 4003089Swyllys gettext("Error proxy input.\n")); 4013089Swyllys } else { 4023089Swyllys flags |= KC_CRL_PROXY; 4033089Swyllys crl_set_attr++; 4043089Swyllys } 4053089Swyllys break; 4063089Swyllys case 'S': 4073089Swyllys plc.VAL_CRL_IGNORE_SIGN = 4083089Swyllys get_boolean(optarg_av); 4093089Swyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 4103089Swyllys (void) fprintf(stderr, 4113089Swyllys gettext("Error boolean input.\n")); 4123089Swyllys rv = KC_ERR_USAGE; 4133089Swyllys } else { 4143089Swyllys flags |= KC_CRL_IGNORE_SIGN; 4153089Swyllys crl_set_attr++; 4163089Swyllys } 4173089Swyllys break; 4183089Swyllys case 'D': 4193089Swyllys plc.VAL_CRL_IGNORE_DATE = 4205051Swyllys get_boolean(optarg_av); 4213089Swyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 4223089Swyllys (void) fprintf(stderr, 4233089Swyllys gettext("Error boolean input.\n")); 4243089Swyllys rv = KC_ERR_USAGE; 4253089Swyllys } else { 4263089Swyllys flags |= KC_CRL_IGNORE_DATE; 4273089Swyllys crl_set_attr++; 4283089Swyllys } 4293089Swyllys break; 4303089Swyllys case 'z': 4313089Swyllys crl_none_opt = get_boolean(optarg_av); 4323089Swyllys if (crl_none_opt == -1) { 4333089Swyllys (void) fprintf(stderr, 4343089Swyllys gettext("Error boolean input.\n")); 4353089Swyllys rv = KC_ERR_USAGE; 4363089Swyllys } else { 4373089Swyllys flags |= KC_CRL_NONE; 4383089Swyllys } 4393089Swyllys break; 4403089Swyllys case 'u': 4413089Swyllys plc.ku_bits = parseKUlist(optarg_av); 4423089Swyllys if (plc.ku_bits == 0) { 4433089Swyllys (void) fprintf(stderr, gettext( 4443089Swyllys "Error keyusage input.\n")); 4453089Swyllys rv = KC_ERR_USAGE; 4463089Swyllys } else { 4473089Swyllys flags |= KC_KEYUSAGE; 4483089Swyllys } 4493089Swyllys break; 4503089Swyllys case 'Y': 4513089Swyllys ku_none_opt = get_boolean(optarg_av); 4523089Swyllys if (ku_none_opt == -1) { 4533089Swyllys (void) fprintf(stderr, 4543089Swyllys gettext("Error boolean input.\n")); 4553089Swyllys rv = KC_ERR_USAGE; 4563089Swyllys } else { 4573089Swyllys flags |= KC_KEYUSAGE_NONE; 4583089Swyllys } 4593089Swyllys break; 4603089Swyllys case 'E': 4613089Swyllys if (parseEKUNames(optarg_av, &plc) != 0) { 4623089Swyllys (void) fprintf(stderr, 4633089Swyllys gettext("Error EKU input.\n")); 4643089Swyllys rv = KC_ERR_USAGE; 4653089Swyllys } else { 4663089Swyllys flags |= KC_EKUS; 4673089Swyllys } 4683089Swyllys break; 4693089Swyllys case 'O': 4703089Swyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 4713089Swyllys (void) fprintf(stderr, 4723089Swyllys gettext("Error EKU OID input.\n")); 4733089Swyllys rv = KC_ERR_USAGE; 4743089Swyllys } else { 4753089Swyllys flags |= KC_EKUS; 4763089Swyllys } 4773089Swyllys break; 4783089Swyllys case 'Z': 4793089Swyllys eku_none_opt = get_boolean(optarg_av); 4803089Swyllys if (eku_none_opt == -1) { 4813089Swyllys (void) fprintf(stderr, 4823089Swyllys gettext("Error boolean input.\n")); 4833089Swyllys rv = KC_ERR_USAGE; 4843089Swyllys } else { 4853089Swyllys flags |= KC_EKUS_NONE; 4863089Swyllys } 4873089Swyllys break; 4883089Swyllys default: 4893089Swyllys (void) fprintf(stderr, 4903089Swyllys gettext("Error input option.\n")); 4913089Swyllys rv = KC_ERR_USAGE; 4923089Swyllys break; 4933089Swyllys } 4943089Swyllys if (rv != KC_OK) 4953089Swyllys goto out; 4963089Swyllys } 4973089Swyllys 4983089Swyllys /* No additional args allowed. */ 4993089Swyllys argc -= optind_av; 5003089Swyllys if (argc) { 5013089Swyllys (void) fprintf(stderr, 5023089Swyllys gettext("Error input option\n")); 5033089Swyllys rv = KC_ERR_USAGE; 5043089Swyllys goto out; 5053089Swyllys } 5063089Swyllys 5073089Swyllys if (filename == NULL) { 5083089Swyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 5093089Swyllys if (filename == NULL) { 5103089Swyllys rv = KC_ERR_MEMORY; 5113089Swyllys goto out; 5123089Swyllys } 5133089Swyllys } 5143089Swyllys 5153089Swyllys /* 5163089Swyllys * Must have a policy name. The policy name can not be default 5173089Swyllys * if using the default policy file. 5183089Swyllys */ 5193089Swyllys if (plc.name == NULL) { 5203089Swyllys (void) fprintf(stderr, 5213089Swyllys gettext("You must specify a policy name.\n")); 5223089Swyllys rv = KC_ERR_USAGE; 5233089Swyllys goto out; 5243089Swyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 5253089Swyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 5263089Swyllys (void) fprintf(stderr, 5273089Swyllys gettext("Can not modify the default policy in the default " 5283089Swyllys "policy file.\n")); 5293089Swyllys rv = KC_ERR_USAGE; 5303089Swyllys goto out; 5313089Swyllys } 5323089Swyllys 5333089Swyllys /* Check the access permission of the policy DB */ 5343089Swyllys if (access(filename, W_OK) < 0) { 5353089Swyllys int err = errno; 5363089Swyllys (void) fprintf(stderr, 5373089Swyllys gettext("Cannot access \"%s\" for modify - %s\n"), 5383089Swyllys filename, strerror(err)); 5393089Swyllys rv = KC_ERR_ACCESS; 5403089Swyllys goto out; 5413089Swyllys } 5423089Swyllys 5433089Swyllys /* Try to load the named policy from the DB */ 5445051Swyllys ret = kmf_get_policy(filename, plc.name, &oplc); 5453089Swyllys if (ret != KMF_OK) { 5463089Swyllys (void) fprintf(stderr, 5473089Swyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 5483089Swyllys plc.name); 5493089Swyllys return (KC_ERR_FIND_POLICY); 5503089Swyllys } 5513089Swyllys 5523089Swyllys /* Update the general policy attributes. */ 5533089Swyllys if (flags & KC_IGNORE_DATE) 5543089Swyllys oplc.ignore_date = plc.ignore_date; 5553089Swyllys 5563089Swyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 5573089Swyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 5583089Swyllys 5593089Swyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 5603089Swyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 5613089Swyllys 5623089Swyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 5633089Swyllys if (oplc.validity_adjusttime) 5643089Swyllys free(oplc.validity_adjusttime); 5653089Swyllys oplc.validity_adjusttime = 5665051Swyllys plc.validity_adjusttime; 5673089Swyllys } 5683089Swyllys 5693089Swyllys if (flags & KC_TA_NAME) { 5703089Swyllys if (oplc.ta_name) 5713089Swyllys free(oplc.ta_name); 5723089Swyllys oplc.ta_name = plc.ta_name; 5733089Swyllys } 5743089Swyllys if (flags & KC_TA_SERIAL) { 5753089Swyllys if (oplc.ta_serial) 5763089Swyllys free(oplc.ta_serial); 5773089Swyllys oplc.ta_serial = plc.ta_serial; 5783089Swyllys } 5793089Swyllys 5803089Swyllys /* Update the OCSP policy */ 5813089Swyllys if (ocsp_none_opt == B_TRUE) { 5823089Swyllys if (ocsp_set_attr > 0) { 5833089Swyllys (void) fprintf(stderr, 5843089Swyllys gettext("Can not set ocsp-none=true and other " 5853089Swyllys "OCSP attributes at the same time.\n")); 5863089Swyllys rv = KC_ERR_USAGE; 5873089Swyllys goto out; 5883089Swyllys } 5893089Swyllys 5903089Swyllys /* 5913089Swyllys * If the original policy does not have OCSP checking, 5923089Swyllys * then we do not need to do anything. If the original 5933089Swyllys * policy has the OCSP checking, then we need to release the 5943089Swyllys * space of OCSP attributes and turn the OCSP checking off. 5953089Swyllys */ 5963089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 5973089Swyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 5983089Swyllys free(oplc.VAL_OCSP_BASIC.responderURI); 5993089Swyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 6003089Swyllys } 6013089Swyllys 6023089Swyllys if (oplc.VAL_OCSP_BASIC.proxy) { 6033089Swyllys free(oplc.VAL_OCSP_BASIC.proxy); 6043089Swyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 6053089Swyllys } 6063089Swyllys 6073089Swyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 6083089Swyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 6093089Swyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 6103089Swyllys } 6113089Swyllys 6123089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 6133089Swyllys free(oplc.VAL_OCSP_RESP_CERT.name); 6143089Swyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 6153089Swyllys } 6163089Swyllys 6173089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 6183089Swyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 6193089Swyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 6203089Swyllys } 6213089Swyllys 6223089Swyllys /* Turn off the OCSP checking */ 6233089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 6243089Swyllys } 6253089Swyllys 6263089Swyllys } else { 6273089Swyllys /* 6283089Swyllys * If the "ocsp-none" option is not set or is set to false, 6293089Swyllys * then we only need to do the modification if there is at 6303089Swyllys * least one OCSP attribute is specified. 6313089Swyllys */ 6323089Swyllys if (ocsp_set_attr > 0) { 6333089Swyllys if (flags & KC_OCSP_RESPONDER_URI) { 6343089Swyllys if (oplc.VAL_OCSP_RESPONDER_URI) 6353089Swyllys free(oplc.VAL_OCSP_RESPONDER_URI); 6363089Swyllys oplc.VAL_OCSP_RESPONDER_URI = 6375051Swyllys plc.VAL_OCSP_RESPONDER_URI; 6383089Swyllys } 6393089Swyllys 6403089Swyllys if (flags & KC_OCSP_PROXY) { 6413089Swyllys if (oplc.VAL_OCSP_PROXY) 6423089Swyllys free(oplc.VAL_OCSP_PROXY); 6433089Swyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 6443089Swyllys } 6453089Swyllys 6463089Swyllys if (flags & KC_OCSP_URI_FROM_CERT) 6473089Swyllys oplc.VAL_OCSP_URI_FROM_CERT = 6485051Swyllys plc.VAL_OCSP_URI_FROM_CERT; 6493089Swyllys 6503089Swyllys if (flags & KC_OCSP_RESP_LIFETIME) { 6513089Swyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 6523089Swyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 6533089Swyllys oplc.VAL_OCSP_RESP_LIFETIME = 6545051Swyllys plc.VAL_OCSP_RESP_LIFETIME; 6553089Swyllys } 6563089Swyllys 6573089Swyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 6583089Swyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 6595051Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 6603089Swyllys 6613089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 6623089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 6633089Swyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 6643089Swyllys oplc.VAL_OCSP_RESP_CERT_NAME = 6655051Swyllys plc.VAL_OCSP_RESP_CERT_NAME; 6663089Swyllys } 6673089Swyllys 6683089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 6693089Swyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 6703089Swyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 6713089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 6725051Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 6733089Swyllys } 6743089Swyllys 6753089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 6763089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 6773089Swyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 6783089Swyllys else 6793089Swyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 6803089Swyllys 6813089Swyllys /* Turn on the OCSP checking */ 6823089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 6833089Swyllys } 6843089Swyllys } 6853089Swyllys 6863089Swyllys /* Update the CRL policy */ 6873089Swyllys if (crl_none_opt == B_TRUE) { 6883089Swyllys if (crl_set_attr > 0) { 6893089Swyllys (void) fprintf(stderr, 6903089Swyllys gettext("Can not set crl-none=true and other CRL " 6913089Swyllys "attributes at the same time.\n")); 6923089Swyllys rv = KC_ERR_USAGE; 6933089Swyllys goto out; 6943089Swyllys } 6953089Swyllys 6963089Swyllys /* 6973089Swyllys * If the original policy does not have CRL checking, 6983089Swyllys * then we do not need to do anything. If the original 6993089Swyllys * policy has the CRL checking, then we need to release the 7003089Swyllys * space of CRL attributes and turn the CRL checking off. 7013089Swyllys */ 7023089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 7033089Swyllys if (oplc.VAL_CRL_BASEFILENAME) { 7043089Swyllys free(oplc.VAL_CRL_BASEFILENAME); 7053089Swyllys oplc.VAL_CRL_BASEFILENAME = NULL; 7063089Swyllys } 7073089Swyllys 7083089Swyllys if (oplc.VAL_CRL_DIRECTORY) { 7093089Swyllys free(oplc.VAL_CRL_DIRECTORY); 7103089Swyllys oplc.VAL_CRL_DIRECTORY = NULL; 7113089Swyllys } 7123089Swyllys 7133089Swyllys if (oplc.VAL_CRL_PROXY) { 7143089Swyllys free(oplc.VAL_CRL_PROXY); 7153089Swyllys oplc.VAL_CRL_PROXY = NULL; 7163089Swyllys } 7173089Swyllys 7183089Swyllys /* Turn off the CRL checking */ 7193089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 7203089Swyllys } 7213089Swyllys } else { 7223089Swyllys /* 7233089Swyllys * If the "ocsp-none" option is not set or is set to false, 7243089Swyllys * then we only need to do the modification if there is at 7253089Swyllys * least one CRL attribute is specified. 7263089Swyllys */ 7273089Swyllys if (crl_set_attr > 0) { 7283089Swyllys if (flags & KC_CRL_BASEFILENAME) { 7293089Swyllys if (oplc.VAL_CRL_BASEFILENAME) 7303089Swyllys free(oplc.VAL_CRL_BASEFILENAME); 7313089Swyllys oplc.VAL_CRL_BASEFILENAME = 7323089Swyllys plc.VAL_CRL_BASEFILENAME; 7333089Swyllys } 7343089Swyllys 7353089Swyllys if (flags & KC_CRL_DIRECTORY) { 7363089Swyllys if (oplc.VAL_CRL_DIRECTORY) 7373089Swyllys free(oplc.VAL_CRL_DIRECTORY); 7383089Swyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 7393089Swyllys } 7403089Swyllys 7413089Swyllys if (flags & KC_CRL_GET_URI) { 7423089Swyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 7433089Swyllys } 7443089Swyllys 7453089Swyllys if (flags & KC_CRL_PROXY) { 7463089Swyllys if (oplc.VAL_CRL_PROXY) 7473089Swyllys free(oplc.VAL_CRL_PROXY); 7483089Swyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 7493089Swyllys } 7503089Swyllys 7513089Swyllys if (flags & KC_CRL_IGNORE_SIGN) { 7523089Swyllys oplc.VAL_CRL_IGNORE_SIGN = 7533089Swyllys plc.VAL_CRL_IGNORE_SIGN; 7543089Swyllys } 7553089Swyllys 7563089Swyllys if (flags & KC_CRL_IGNORE_DATE) { 7573089Swyllys oplc.VAL_CRL_IGNORE_DATE = 7583089Swyllys plc.VAL_CRL_IGNORE_DATE; 7593089Swyllys } 7603089Swyllys 7613089Swyllys /* Turn on the CRL checking */ 7623089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 7633089Swyllys } 7643089Swyllys } 7653089Swyllys 7663089Swyllys /* Update the Key Usage */ 7673089Swyllys if (ku_none_opt == B_TRUE) { 7683089Swyllys if (flags & KC_KEYUSAGE) { 7693089Swyllys (void) fprintf(stderr, 7703089Swyllys gettext("Can not set keyusage-none=true and " 7713089Swyllys "modify the keyusage value at the same time.\n")); 7723089Swyllys rv = KC_ERR_USAGE; 7733089Swyllys goto out; 7743089Swyllys } 7753089Swyllys 7763089Swyllys oplc.ku_bits = 0; 7773089Swyllys } else { 7783089Swyllys /* 7793089Swyllys * If the "keyusage-none" option is not set or is set to 7803089Swyllys * false, then we only need to do the modification if 7813089Swyllys * the keyusage value is specified. 7823089Swyllys */ 7833089Swyllys if (flags & KC_KEYUSAGE) 7843089Swyllys oplc.ku_bits = plc.ku_bits; 7853089Swyllys } 7863089Swyllys 7873089Swyllys 7883089Swyllys /* Update the Extended Key Usage */ 7893089Swyllys if (eku_none_opt == B_TRUE) { 7903089Swyllys if (flags & KC_EKUS) { 7913089Swyllys (void) fprintf(stderr, 7923089Swyllys gettext("Can not set eku-none=true and modify " 7933089Swyllys "EKU values at the same time.\n")); 7943089Swyllys rv = KC_ERR_USAGE; 7953089Swyllys goto out; 7963089Swyllys } 7973089Swyllys 7983089Swyllys /* Release current EKU list (if any) */ 7993089Swyllys if (oplc.eku_set.eku_count > 0) { 8005051Swyllys kmf_free_eku_policy(&oplc.eku_set); 8013089Swyllys oplc.eku_set.eku_count = 0; 8023089Swyllys oplc.eku_set.ekulist = NULL; 8033089Swyllys } 8043089Swyllys } else { 8053089Swyllys /* 8063089Swyllys * If the "eku-none" option is not set or is set to false, 8073089Swyllys * then we only need to do the modification if either 8083089Swyllys * "ekuname" or "ekuoids" is specified. 8093089Swyllys */ 8103089Swyllys if (flags & KC_EKUS) { 8113089Swyllys /* Release current EKU list (if any) */ 8125051Swyllys kmf_free_eku_policy(&oplc.eku_set); 8133089Swyllys oplc.eku_set = plc.eku_set; 8143089Swyllys } 8153089Swyllys } 8163089Swyllys 8173089Swyllys /* Do a sanity check on the modified policy */ 8185051Swyllys ret = kmf_verify_policy(&oplc); 8193089Swyllys if (ret != KMF_OK) { 8203089Swyllys print_sanity_error(ret); 8213089Swyllys rv = KC_ERR_VERIFY_POLICY; 8223089Swyllys goto out; 8233089Swyllys } 8243089Swyllys 8253089Swyllys /* The modify operation is a delete followed by an add */ 8265051Swyllys ret = kmf_delete_policy_from_db(oplc.name, filename); 8273089Swyllys if (ret != KMF_OK) { 8283089Swyllys rv = KC_ERR_DELETE_POLICY; 8293089Swyllys goto out; 8303089Swyllys } 8313089Swyllys 8323089Swyllys /* 8333089Swyllys * Now add the modified policy back to the DB. 8343089Swyllys */ 8355051Swyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE); 8363089Swyllys if (ret != KMF_OK) { 8373089Swyllys (void) fprintf(stderr, 8383089Swyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 8393089Swyllys rv = KC_ERR_ADD_POLICY; 8403089Swyllys goto out; 8413089Swyllys } 8423089Swyllys 8433089Swyllys out: 8443089Swyllys if (filename != NULL) 8453089Swyllys free(filename); 8463089Swyllys 8475051Swyllys kmf_free_policy_record(&oplc); 8483089Swyllys 8493089Swyllys return (rv); 8503089Swyllys } 851*5626Shylee 852*5626Shylee 853*5626Shylee static int 854*5626Shylee kc_modify_plugin(int argc, char *argv[]) 855*5626Shylee { 856*5626Shylee int rv = KC_OK; 857*5626Shylee int opt; 858*5626Shylee extern int optind_av; 859*5626Shylee extern char *optarg_av; 860*5626Shylee char *keystore_name = NULL; 861*5626Shylee char *option = NULL; 862*5626Shylee boolean_t modify_plugin = B_FALSE; 863*5626Shylee boolean_t has_option_arg = B_FALSE; 864*5626Shylee conf_entry_t *entry = NULL; 865*5626Shylee FILE *pfile = NULL; 866*5626Shylee FILE *pfile_tmp = NULL; 867*5626Shylee char tmpfile_name[MAXPATHLEN]; 868*5626Shylee char buffer[MAXPATHLEN]; 869*5626Shylee char buffer2[MAXPATHLEN]; 870*5626Shylee 871*5626Shylee while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)")) 872*5626Shylee != EOF) { 873*5626Shylee switch (opt) { 874*5626Shylee case 'p': 875*5626Shylee if (modify_plugin) { 876*5626Shylee (void) fprintf(stderr, 877*5626Shylee gettext("duplicate plugin input.\n")); 878*5626Shylee rv = KC_ERR_USAGE; 879*5626Shylee } else { 880*5626Shylee modify_plugin = B_TRUE; 881*5626Shylee } 882*5626Shylee break; 883*5626Shylee case 'k': 884*5626Shylee if (keystore_name != NULL) 885*5626Shylee rv = KC_ERR_USAGE; 886*5626Shylee else { 887*5626Shylee keystore_name = get_string(optarg_av, &rv); 888*5626Shylee if (keystore_name == NULL) { 889*5626Shylee (void) fprintf(stderr, gettext( 890*5626Shylee "Error keystore input.\n")); 891*5626Shylee rv = KC_ERR_USAGE; 892*5626Shylee } 893*5626Shylee } 894*5626Shylee break; 895*5626Shylee case 'o': 896*5626Shylee if (has_option_arg) { 897*5626Shylee (void) fprintf(stderr, 898*5626Shylee gettext("duplicate option input.\n")); 899*5626Shylee rv = KC_ERR_USAGE; 900*5626Shylee } else { 901*5626Shylee has_option_arg = B_TRUE; 902*5626Shylee option = get_string(optarg_av, NULL); 903*5626Shylee } 904*5626Shylee break; 905*5626Shylee default: 906*5626Shylee (void) fprintf(stderr, 907*5626Shylee gettext("Error input option.\n")); 908*5626Shylee rv = KC_ERR_USAGE; 909*5626Shylee break; 910*5626Shylee } 911*5626Shylee 912*5626Shylee if (rv != KC_OK) 913*5626Shylee goto out; 914*5626Shylee } 915*5626Shylee 916*5626Shylee /* No additional args allowed. */ 917*5626Shylee argc -= optind_av; 918*5626Shylee if (argc) { 919*5626Shylee (void) fprintf(stderr, 920*5626Shylee gettext("Error input option\n")); 921*5626Shylee rv = KC_ERR_USAGE; 922*5626Shylee goto out; 923*5626Shylee } 924*5626Shylee 925*5626Shylee if (keystore_name == NULL || has_option_arg == B_FALSE) { 926*5626Shylee (void) fprintf(stderr, 927*5626Shylee gettext("Error input option\n")); 928*5626Shylee rv = KC_ERR_USAGE; 929*5626Shylee goto out; 930*5626Shylee } 931*5626Shylee 932*5626Shylee if (strcasecmp(keystore_name, "nss") == 0 || 933*5626Shylee strcasecmp(keystore_name, "pkcs11") == 0 || 934*5626Shylee strcasecmp(keystore_name, "file") == 0) { 935*5626Shylee (void) fprintf(stderr, 936*5626Shylee gettext("Can not modify the built-in keystore %s\n"), 937*5626Shylee keystore_name); 938*5626Shylee rv = KC_ERR_USAGE; 939*5626Shylee goto out; 940*5626Shylee } 941*5626Shylee 942*5626Shylee entry = get_keystore_entry(keystore_name); 943*5626Shylee if (entry == NULL) { 944*5626Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"), 945*5626Shylee keystore_name); 946*5626Shylee rv = KC_ERR_USAGE; 947*5626Shylee goto out; 948*5626Shylee } 949*5626Shylee 950*5626Shylee if ((entry->option == NULL && option == NULL) || 951*5626Shylee (entry->option != NULL && option != NULL && 952*5626Shylee strcmp(entry->option, option) == 0)) { 953*5626Shylee (void) fprintf(stderr, gettext("No change - " 954*5626Shylee "the new option is same as the old option.\n")); 955*5626Shylee rv = KC_OK; 956*5626Shylee goto out; 957*5626Shylee } 958*5626Shylee 959*5626Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { 960*5626Shylee err = errno; 961*5626Shylee (void) fprintf(stderr, 962*5626Shylee gettext("failed to update the configuration - %s\n"), 963*5626Shylee strerror(err)); 964*5626Shylee rv = KC_ERR_ACCESS; 965*5626Shylee goto out; 966*5626Shylee } 967*5626Shylee 968*5626Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 969*5626Shylee err = errno; 970*5626Shylee (void) fprintf(stderr, 971*5626Shylee gettext("failed to lock the configuration - %s\n"), 972*5626Shylee strerror(err)); 973*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 974*5626Shylee goto out; 975*5626Shylee } 976*5626Shylee 977*5626Shylee /* 978*5626Shylee * Create a temporary file in the /etc/crypto directory. 979*5626Shylee */ 980*5626Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); 981*5626Shylee if (mkstemp(tmpfile_name) == -1) { 982*5626Shylee err = errno; 983*5626Shylee (void) fprintf(stderr, 984*5626Shylee gettext("failed to create a temporary file - %s\n"), 985*5626Shylee strerror(err)); 986*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 987*5626Shylee goto out; 988*5626Shylee } 989*5626Shylee 990*5626Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 991*5626Shylee err = errno; 992*5626Shylee (void) fprintf(stderr, 993*5626Shylee gettext("failed to open %s - %s\n"), 994*5626Shylee tmpfile_name, strerror(err)); 995*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 996*5626Shylee goto out; 997*5626Shylee } 998*5626Shylee 999*5626Shylee /* 1000*5626Shylee * Loop thru the config file and update the entry. 1001*5626Shylee */ 1002*5626Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 1003*5626Shylee char *name; 1004*5626Shylee int len; 1005*5626Shylee 1006*5626Shylee if (buffer[0] == '#') { 1007*5626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1008*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 1009*5626Shylee goto out; 1010*5626Shylee } else { 1011*5626Shylee continue; 1012*5626Shylee } 1013*5626Shylee } 1014*5626Shylee 1015*5626Shylee /* 1016*5626Shylee * make a copy of the original buffer to buffer2. Also get 1017*5626Shylee * rid of the trailing '\n' from buffer2. 1018*5626Shylee */ 1019*5626Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN); 1020*5626Shylee len = strlen(buffer2); 1021*5626Shylee if (buffer2[len-1] == '\n') { 1022*5626Shylee len--; 1023*5626Shylee } 1024*5626Shylee buffer2[len] = '\0'; 1025*5626Shylee 1026*5626Shylee if ((name = strtok(buffer2, SEP_COLON)) == NULL) { 1027*5626Shylee rv = KC_ERR_UNINSTALL; 1028*5626Shylee goto out; 1029*5626Shylee } 1030*5626Shylee 1031*5626Shylee if (strcmp(name, keystore_name) == 0) { 1032*5626Shylee /* found the entry */ 1033*5626Shylee if (option == NULL) 1034*5626Shylee (void) snprintf(buffer, MAXPATHLEN, 1035*5626Shylee "%s:%s%s\n", keystore_name, 1036*5626Shylee CONF_MODULEPATH, entry->modulepath); 1037*5626Shylee else 1038*5626Shylee (void) snprintf(buffer, MAXPATHLEN, 1039*5626Shylee "%s:%s%s;%s%s\n", keystore_name, 1040*5626Shylee CONF_MODULEPATH, entry->modulepath, 1041*5626Shylee CONF_OPTION, option); 1042*5626Shylee 1043*5626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1044*5626Shylee err = errno; 1045*5626Shylee (void) fprintf(stderr, gettext( 1046*5626Shylee "failed to write to %s: %s\n"), 1047*5626Shylee tmpfile_name, strerror(err)); 1048*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 1049*5626Shylee goto out; 1050*5626Shylee } 1051*5626Shylee } else { 1052*5626Shylee 1053*5626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1054*5626Shylee rv = KC_ERR_UNINSTALL; 1055*5626Shylee goto out; 1056*5626Shylee } 1057*5626Shylee } 1058*5626Shylee } 1059*5626Shylee 1060*5626Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { 1061*5626Shylee err = errno; 1062*5626Shylee (void) fprintf(stderr, gettext( 1063*5626Shylee "failed to update the configuration - %s"), strerror(err)); 1064*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 1065*5626Shylee goto out; 1066*5626Shylee } 1067*5626Shylee 1068*5626Shylee if (chmod(_PATH_KMF_CONF, 1069*5626Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 1070*5626Shylee err = errno; 1071*5626Shylee (void) fprintf(stderr, gettext( 1072*5626Shylee "failed to update the configuration - %s\n"), 1073*5626Shylee strerror(err)); 1074*5626Shylee rv = KC_ERR_MODIFY_PLUGIN; 1075*5626Shylee goto out; 1076*5626Shylee } 1077*5626Shylee 1078*5626Shylee out: 1079*5626Shylee if (entry != NULL) 1080*5626Shylee free_entry(entry); 1081*5626Shylee 1082*5626Shylee if (pfile != NULL) 1083*5626Shylee (void) fclose(pfile); 1084*5626Shylee 1085*5626Shylee if (rv != KC_OK && pfile_tmp != NULL) 1086*5626Shylee (void) unlink(tmpfile_name); 1087*5626Shylee 1088*5626Shylee if (pfile_tmp != NULL) 1089*5626Shylee (void) fclose(pfile_tmp); 1090*5626Shylee 1091*5626Shylee return (rv); 1092*5626Shylee } 1093*5626Shylee 1094*5626Shylee 1095*5626Shylee int 1096*5626Shylee kc_modify(int argc, char *argv[]) 1097*5626Shylee { 1098*5626Shylee if (argc > 2 && 1099*5626Shylee strcmp(argv[0], "modify") == 0 && 1100*5626Shylee strcmp(argv[1], "plugin") == 0) { 1101*5626Shylee return (kc_modify_plugin(argc, argv)); 1102*5626Shylee } else { 1103*5626Shylee return (kc_modify_policy(argc, argv)); 1104*5626Shylee } 1105*5626Shylee } 1106