xref: /titanic_54/usr/src/cmd/cmd-crypto/kmfcfg/modify.c (revision 269e59f9a28bf47e0f463e64fc5af4a408b73b21)
199ebb4caSwyllys /*
299ebb4caSwyllys  * CDDL HEADER START
399ebb4caSwyllys  *
499ebb4caSwyllys  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
799ebb4caSwyllys  *
899ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
1099ebb4caSwyllys  * See the License for the specific language governing permissions
1199ebb4caSwyllys  * and limitations under the License.
1299ebb4caSwyllys  *
1399ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
1699ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4caSwyllys  *
1999ebb4caSwyllys  * CDDL HEADER END
2099ebb4caSwyllys  *
21*269e59f9SJan Pechanec  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2299ebb4caSwyllys  */
2399ebb4caSwyllys 
2499ebb4caSwyllys #include <stdio.h>
2599ebb4caSwyllys #include <strings.h>
2699ebb4caSwyllys #include <ctype.h>
2799ebb4caSwyllys #include <libgen.h>
2899ebb4caSwyllys #include <libintl.h>
2999ebb4caSwyllys #include <errno.h>
3099ebb4caSwyllys #include <kmfapiP.h>
3199ebb4caSwyllys #include <cryptoutil.h>
32431deaa0Shylee #include <sys/stat.h>
33431deaa0Shylee #include <sys/param.h>
3499ebb4caSwyllys #include "util.h"
3599ebb4caSwyllys 
3699ebb4caSwyllys #define	KC_IGNORE_DATE			0x0000001
3799ebb4caSwyllys #define	KC_IGNORE_UNKNOWN_EKUS		0x0000002
3899ebb4caSwyllys #define	KC_IGNORE_TRUST_ANCHOR		0x0000004
3999ebb4caSwyllys #define	KC_VALIDITY_ADJUSTTIME		0x0000008
4099ebb4caSwyllys #define	KC_TA_NAME			0x0000010
4199ebb4caSwyllys #define	KC_TA_SERIAL			0x0000020
4299ebb4caSwyllys #define	KC_OCSP_RESPONDER_URI		0x0000040
4399ebb4caSwyllys #define	KC_OCSP_PROXY			0x0000080
4499ebb4caSwyllys #define	KC_OCSP_URI_FROM_CERT		0x0000100
4599ebb4caSwyllys #define	KC_OCSP_RESP_LIFETIME		0x0000200
4699ebb4caSwyllys #define	KC_OCSP_IGNORE_RESP_SIGN 	0x0000400
4799ebb4caSwyllys #define	KC_OCSP_RESP_CERT_NAME		0x0000800
4899ebb4caSwyllys #define	KC_OCSP_RESP_CERT_SERIAL	0x0001000
4999ebb4caSwyllys #define	KC_OCSP_NONE			0x0002000
5099ebb4caSwyllys #define	KC_CRL_BASEFILENAME		0x0004000
5199ebb4caSwyllys #define	KC_CRL_DIRECTORY		0x0008000
5299ebb4caSwyllys #define	KC_CRL_GET_URI			0x0010000
5399ebb4caSwyllys #define	KC_CRL_PROXY			0x0020000
5499ebb4caSwyllys #define	KC_CRL_IGNORE_SIGN		0x0040000
5599ebb4caSwyllys #define	KC_CRL_IGNORE_DATE		0x0080000
5699ebb4caSwyllys #define	KC_CRL_NONE			0x0100000
5799ebb4caSwyllys #define	KC_KEYUSAGE			0x0200000
5899ebb4caSwyllys #define	KC_KEYUSAGE_NONE		0x0400000
5999ebb4caSwyllys #define	KC_EKUS				0x0800000
6099ebb4caSwyllys #define	KC_EKUS_NONE			0x1000000
61*269e59f9SJan Pechanec #define	KC_MAPPER_OPTIONS		0x2000000
6299ebb4caSwyllys 
63431deaa0Shylee static int err; /* To store errno which may be overwritten by gettext() */
64431deaa0Shylee 
65*269e59f9SJan Pechanec #define	UPDATE_IF_DIFFERENT(old, new) \
66*269e59f9SJan Pechanec 	if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \
67*269e59f9SJan Pechanec 	    (old == NULL && new != NULL)) { \
68*269e59f9SJan Pechanec 		if (old != NULL) \
69*269e59f9SJan Pechanec 			free(old); \
70*269e59f9SJan Pechanec 		old = new; \
71*269e59f9SJan Pechanec 	}
72431deaa0Shylee 
7399ebb4caSwyllys int
74431deaa0Shylee kc_modify_policy(int argc, char *argv[])
7599ebb4caSwyllys {
7699ebb4caSwyllys 	KMF_RETURN	ret;
7799ebb4caSwyllys 	int 		rv = KC_OK;
7899ebb4caSwyllys 	int		opt;
7999ebb4caSwyllys 	extern int	optind_av;
8099ebb4caSwyllys 	extern char	*optarg_av;
8199ebb4caSwyllys 	char		*filename = NULL;
82*269e59f9SJan Pechanec 	char		*mapper_name = NULL;
83*269e59f9SJan Pechanec 	char		*mapper_dir = NULL;
84*269e59f9SJan Pechanec 	char		*mapper_pathname = NULL;
8599ebb4caSwyllys 	uint32_t	flags = 0;
8699ebb4caSwyllys 	boolean_t	ocsp_none_opt = B_FALSE;
8799ebb4caSwyllys 	boolean_t	crl_none_opt = B_FALSE;
8899ebb4caSwyllys 	boolean_t	ku_none_opt = B_FALSE;
8999ebb4caSwyllys 	boolean_t	eku_none_opt = B_FALSE;
9099ebb4caSwyllys 	int		ocsp_set_attr = 0;
9199ebb4caSwyllys 	int		crl_set_attr = 0;
9299ebb4caSwyllys 	KMF_POLICY_RECORD oplc, plc;
9399ebb4caSwyllys 
9499ebb4caSwyllys 	(void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));
9599ebb4caSwyllys 	(void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD));
9699ebb4caSwyllys 
9799ebb4caSwyllys 	while ((opt = getopt_av(argc, argv,
9899ebb4caSwyllys 	    "i:(dbfile)"
9999ebb4caSwyllys 	    "p:(policy)"
10099ebb4caSwyllys 	    "d:(ignore-date)"
10199ebb4caSwyllys 	    "e:(ignore-unknown-eku)"
10299ebb4caSwyllys 	    "a:(ignore-trust-anchor)"
10399ebb4caSwyllys 	    "v:(validity-adjusttime)"
10499ebb4caSwyllys 	    "t:(ta-name)"
10599ebb4caSwyllys 	    "s:(ta-serial)"
10699ebb4caSwyllys 	    "o:(ocsp-responder)"
10799ebb4caSwyllys 	    "P:(ocsp-proxy)"
10899ebb4caSwyllys 	    "r:(ocsp-use-cert-responder)"
10999ebb4caSwyllys 	    "T:(ocsp-response-lifetime)"
11099ebb4caSwyllys 	    "R:(ocsp-ignore-response-sign)"
11199ebb4caSwyllys 	    "n:(ocsp-responder-cert-name)"
11299ebb4caSwyllys 	    "A:(ocsp-responder-cert-serial)"
11399ebb4caSwyllys 	    "y:(ocsp-none)"
11499ebb4caSwyllys 	    "c:(crl-basefilename)"
11599ebb4caSwyllys 	    "I:(crl-directory)"
11699ebb4caSwyllys 	    "g:(crl-get-crl-uri)"
11799ebb4caSwyllys 	    "X:(crl-proxy)"
11899ebb4caSwyllys 	    "S:(crl-ignore-crl-sign)"
11999ebb4caSwyllys 	    "D:(crl-ignore-crl-date)"
12099ebb4caSwyllys 	    "z:(crl-none)"
12199ebb4caSwyllys 	    "u:(keyusage)"
12299ebb4caSwyllys 	    "Y:(keyusage-none)"
12399ebb4caSwyllys 	    "E:(ekunames)"
12499ebb4caSwyllys 	    "O:(ekuoids)"
125*269e59f9SJan Pechanec 	    "m:(mapper-name)"
126*269e59f9SJan Pechanec 	    "M:(mapper-directory)"
127*269e59f9SJan Pechanec 	    "Q:(mapper-pathname)"
128*269e59f9SJan Pechanec 	    "q:(mapper-options)"
12999ebb4caSwyllys 	    "Z:(eku-none)")) != EOF) {
13099ebb4caSwyllys 		switch (opt) {
13199ebb4caSwyllys 			case 'i':
13299ebb4caSwyllys 				filename = get_string(optarg_av, &rv);
13399ebb4caSwyllys 				if (filename == NULL) {
13499ebb4caSwyllys 					(void) fprintf(stderr,
13599ebb4caSwyllys 					    gettext("Error dbfile input.\n"));
13699ebb4caSwyllys 				}
13799ebb4caSwyllys 				break;
13899ebb4caSwyllys 			case 'p':
13999ebb4caSwyllys 				plc.name = get_string(optarg_av, &rv);
14099ebb4caSwyllys 				if (plc.name == NULL) {
14199ebb4caSwyllys 					(void) fprintf(stderr,
14299ebb4caSwyllys 					    gettext("Error policy name.\n"));
14399ebb4caSwyllys 				}
14499ebb4caSwyllys 				break;
14599ebb4caSwyllys 			case 'd':
14699ebb4caSwyllys 				plc.ignore_date = get_boolean(optarg_av);
14799ebb4caSwyllys 				if (plc.ignore_date == -1) {
14899ebb4caSwyllys 					(void) fprintf(stderr,
14999ebb4caSwyllys 					    gettext("Error boolean input.\n"));
15099ebb4caSwyllys 					rv = KC_ERR_USAGE;
15199ebb4caSwyllys 				} else {
15299ebb4caSwyllys 					flags |= KC_IGNORE_DATE;
15399ebb4caSwyllys 				}
15499ebb4caSwyllys 				break;
15599ebb4caSwyllys 			case 'e':
15699ebb4caSwyllys 				plc.ignore_unknown_ekus =
15799ebb4caSwyllys 				    get_boolean(optarg_av);
15899ebb4caSwyllys 				if (plc.ignore_unknown_ekus == -1) {
15999ebb4caSwyllys 					(void) fprintf(stderr,
16099ebb4caSwyllys 					    gettext("Error boolean input.\n"));
16199ebb4caSwyllys 					rv = KC_ERR_USAGE;
16299ebb4caSwyllys 				} else {
16399ebb4caSwyllys 					flags |= KC_IGNORE_UNKNOWN_EKUS;
16499ebb4caSwyllys 				}
16599ebb4caSwyllys 				break;
16699ebb4caSwyllys 			case 'a':
16799ebb4caSwyllys 				plc.ignore_trust_anchor =
16899ebb4caSwyllys 				    get_boolean(optarg_av);
16999ebb4caSwyllys 				if (plc.ignore_trust_anchor == -1) {
17099ebb4caSwyllys 					(void) fprintf(stderr,
17199ebb4caSwyllys 					    gettext("Error boolean input.\n"));
17299ebb4caSwyllys 					rv = KC_ERR_USAGE;
17399ebb4caSwyllys 				} else {
17499ebb4caSwyllys 					flags |= KC_IGNORE_TRUST_ANCHOR;
17599ebb4caSwyllys 				}
17699ebb4caSwyllys 				break;
17799ebb4caSwyllys 			case 'v':
17899ebb4caSwyllys 				plc.validity_adjusttime =
17999ebb4caSwyllys 				    get_string(optarg_av, &rv);
18099ebb4caSwyllys 				if (plc.validity_adjusttime == NULL) {
18199ebb4caSwyllys 					(void) fprintf(stderr,
18299ebb4caSwyllys 					    gettext("Error time input.\n"));
18399ebb4caSwyllys 				} else {
18499ebb4caSwyllys 					uint32_t adj;
18599ebb4caSwyllys 					/* for syntax checking */
18699ebb4caSwyllys 					if (str2lifetime(
18799ebb4caSwyllys 					    plc.validity_adjusttime,
18899ebb4caSwyllys 					    &adj) < 0) {
18999ebb4caSwyllys 						(void) fprintf(stderr,
19099ebb4caSwyllys 						    gettext("Error time "
19199ebb4caSwyllys 						    "input.\n"));
19299ebb4caSwyllys 						rv = KC_ERR_USAGE;
19399ebb4caSwyllys 					} else {
19499ebb4caSwyllys 						flags |= KC_VALIDITY_ADJUSTTIME;
19599ebb4caSwyllys 					}
19699ebb4caSwyllys 				}
19799ebb4caSwyllys 				break;
19899ebb4caSwyllys 			case 't':
19999ebb4caSwyllys 				plc.ta_name = get_string(optarg_av, &rv);
20099ebb4caSwyllys 				if (plc.ta_name == NULL) {
20199ebb4caSwyllys 					(void) fprintf(stderr,
20299ebb4caSwyllys 					    gettext("Error name input.\n"));
20399ebb4caSwyllys 				} else {
20499ebb4caSwyllys 					KMF_X509_NAME taDN;
20599ebb4caSwyllys 					/* for syntax checking */
20630a5e8faSwyllys 					if (kmf_dn_parser(plc.ta_name,
20799ebb4caSwyllys 					    &taDN) != KMF_OK) {
20899ebb4caSwyllys 						(void) fprintf(stderr,
20999ebb4caSwyllys 						    gettext("Error name "
21099ebb4caSwyllys 						    "input.\n"));
21199ebb4caSwyllys 						rv = KC_ERR_USAGE;
21299ebb4caSwyllys 					} else {
21330a5e8faSwyllys 						kmf_free_dn(&taDN);
21499ebb4caSwyllys 						flags |= KC_TA_NAME;
21599ebb4caSwyllys 					}
21699ebb4caSwyllys 				}
21799ebb4caSwyllys 				break;
21899ebb4caSwyllys 			case 's':
21999ebb4caSwyllys 				plc.ta_serial = get_string(optarg_av, &rv);
22099ebb4caSwyllys 				if (plc.ta_serial == NULL) {
22199ebb4caSwyllys 					(void) fprintf(stderr,
22299ebb4caSwyllys 					    gettext("Error serial input.\n"));
22399ebb4caSwyllys 				} else {
22499ebb4caSwyllys 					uchar_t *bytes = NULL;
22599ebb4caSwyllys 					size_t bytelen;
22699ebb4caSwyllys 
22730a5e8faSwyllys 					ret = kmf_hexstr_to_bytes(
22899ebb4caSwyllys 					    (uchar_t *)plc.ta_serial,
22999ebb4caSwyllys 					    &bytes, &bytelen);
23099ebb4caSwyllys 					if (ret != KMF_OK || bytes == NULL) {
23199ebb4caSwyllys 						(void) fprintf(stderr,
23299ebb4caSwyllys 						    gettext("serial number "
23399ebb4caSwyllys 						    "must be specified as a "
23499ebb4caSwyllys 						    "hex number "
23599ebb4caSwyllys 						    "(ex: 0x0102030405"
23699ebb4caSwyllys 						    "ffeeddee)\n"));
23799ebb4caSwyllys 						rv = KC_ERR_USAGE;
23899ebb4caSwyllys 						break;
23999ebb4caSwyllys 					}
24099ebb4caSwyllys 					if (bytes != NULL)
24199ebb4caSwyllys 						free(bytes);
24299ebb4caSwyllys 					flags |= KC_TA_SERIAL;
24399ebb4caSwyllys 				}
24499ebb4caSwyllys 				break;
24599ebb4caSwyllys 			case 'o':
24699ebb4caSwyllys 				plc.VAL_OCSP_RESPONDER_URI =
24799ebb4caSwyllys 				    get_string(optarg_av, &rv);
24899ebb4caSwyllys 				if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
24999ebb4caSwyllys 					(void) fprintf(stderr,
25099ebb4caSwyllys 					    gettext("Error responder "
25199ebb4caSwyllys 					    "input.\n"));
25299ebb4caSwyllys 				} else {
25399ebb4caSwyllys 					flags |= KC_OCSP_RESPONDER_URI;
25499ebb4caSwyllys 					ocsp_set_attr++;
25599ebb4caSwyllys 				}
25699ebb4caSwyllys 				break;
25799ebb4caSwyllys 			case 'P':
25899ebb4caSwyllys 				plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv);
25999ebb4caSwyllys 				if (plc.VAL_OCSP_PROXY == NULL) {
26099ebb4caSwyllys 					(void) fprintf(stderr,
26199ebb4caSwyllys 					    gettext("Error proxy input.\n"));
26299ebb4caSwyllys 				} else {
26399ebb4caSwyllys 					flags |= KC_OCSP_PROXY;
26499ebb4caSwyllys 					ocsp_set_attr++;
26599ebb4caSwyllys 				}
26699ebb4caSwyllys 				break;
26799ebb4caSwyllys 			case 'r':
26899ebb4caSwyllys 				plc.VAL_OCSP_URI_FROM_CERT =
26999ebb4caSwyllys 				    get_boolean(optarg_av);
27099ebb4caSwyllys 				if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
27199ebb4caSwyllys 					(void) fprintf(stderr,
27299ebb4caSwyllys 					    gettext("Error boolean input.\n"));
27399ebb4caSwyllys 					rv = KC_ERR_USAGE;
27499ebb4caSwyllys 				} else {
27599ebb4caSwyllys 					flags |= KC_OCSP_URI_FROM_CERT;
27699ebb4caSwyllys 					ocsp_set_attr++;
27799ebb4caSwyllys 				}
27899ebb4caSwyllys 				break;
27999ebb4caSwyllys 			case 'T':
28099ebb4caSwyllys 				plc.VAL_OCSP_RESP_LIFETIME =
28199ebb4caSwyllys 				    get_string(optarg_av, &rv);
28299ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
28399ebb4caSwyllys 					(void) fprintf(stderr,
28499ebb4caSwyllys 					    gettext("Error time input.\n"));
28599ebb4caSwyllys 				} else {
28699ebb4caSwyllys 					uint32_t adj;
28799ebb4caSwyllys 					/* for syntax checking */
28899ebb4caSwyllys 					if (str2lifetime(
28999ebb4caSwyllys 					    plc.VAL_OCSP_RESP_LIFETIME,
29099ebb4caSwyllys 					    &adj) < 0) {
29199ebb4caSwyllys 						(void) fprintf(stderr,
29299ebb4caSwyllys 						    gettext("Error time "
29399ebb4caSwyllys 						    "input.\n"));
29499ebb4caSwyllys 						rv = KC_ERR_USAGE;
29599ebb4caSwyllys 					} else {
29699ebb4caSwyllys 						flags |= KC_OCSP_RESP_LIFETIME;
29799ebb4caSwyllys 						ocsp_set_attr++;
29899ebb4caSwyllys 					}
29999ebb4caSwyllys 				}
30099ebb4caSwyllys 				break;
30199ebb4caSwyllys 			case 'R':
30299ebb4caSwyllys 				plc.VAL_OCSP_IGNORE_RESP_SIGN =
30399ebb4caSwyllys 				    get_boolean(optarg_av);
30499ebb4caSwyllys 				if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
30599ebb4caSwyllys 					(void) fprintf(stderr,
30699ebb4caSwyllys 					    gettext("Error boolean input.\n"));
30799ebb4caSwyllys 					rv = KC_ERR_USAGE;
30899ebb4caSwyllys 				} else {
30999ebb4caSwyllys 					flags |= KC_OCSP_IGNORE_RESP_SIGN;
31099ebb4caSwyllys 					ocsp_set_attr++;
31199ebb4caSwyllys 				}
31299ebb4caSwyllys 				break;
31399ebb4caSwyllys 			case 'n':
31499ebb4caSwyllys 				plc.VAL_OCSP_RESP_CERT_NAME =
31599ebb4caSwyllys 				    get_string(optarg_av, &rv);
31699ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
31799ebb4caSwyllys 					(void) fprintf(stderr,
31899ebb4caSwyllys 					    gettext("Error name input.\n"));
31999ebb4caSwyllys 				} else {
32099ebb4caSwyllys 					KMF_X509_NAME respDN;
32199ebb4caSwyllys 					/* for syntax checking */
32230a5e8faSwyllys 					if (kmf_dn_parser(
32399ebb4caSwyllys 					    plc.VAL_OCSP_RESP_CERT_NAME,
32499ebb4caSwyllys 					    &respDN) != KMF_OK) {
32599ebb4caSwyllys 						(void) fprintf(stderr,
32699ebb4caSwyllys 						    gettext("Error name "
32799ebb4caSwyllys 						    "input.\n"));
32899ebb4caSwyllys 						rv = KC_ERR_USAGE;
32999ebb4caSwyllys 					} else {
33030a5e8faSwyllys 						kmf_free_dn(&respDN);
33199ebb4caSwyllys 						flags |= KC_OCSP_RESP_CERT_NAME;
33299ebb4caSwyllys 						ocsp_set_attr++;
33399ebb4caSwyllys 					}
33499ebb4caSwyllys 				}
33599ebb4caSwyllys 				break;
33699ebb4caSwyllys 			case 'A':
33799ebb4caSwyllys 				plc.VAL_OCSP_RESP_CERT_SERIAL =
33899ebb4caSwyllys 				    get_string(optarg_av, &rv);
33999ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
34099ebb4caSwyllys 					(void) fprintf(stderr,
34199ebb4caSwyllys 					    gettext("Error serial input.\n"));
34299ebb4caSwyllys 				} else {
34399ebb4caSwyllys 					uchar_t *bytes = NULL;
34499ebb4caSwyllys 					size_t bytelen;
34599ebb4caSwyllys 
34630a5e8faSwyllys 					ret = kmf_hexstr_to_bytes((uchar_t *)
34799ebb4caSwyllys 					    plc.VAL_OCSP_RESP_CERT_SERIAL,
34899ebb4caSwyllys 					    &bytes, &bytelen);
34999ebb4caSwyllys 					if (ret != KMF_OK || bytes == NULL) {
35099ebb4caSwyllys 						(void) fprintf(stderr,
35199ebb4caSwyllys 						    gettext("serial number "
35299ebb4caSwyllys 						    "must be specified as a "
35399ebb4caSwyllys 						    "hex number "
35499ebb4caSwyllys 						    "(ex: 0x0102030405"
35599ebb4caSwyllys 						    "ffeeddee)\n"));
35699ebb4caSwyllys 						rv = KC_ERR_USAGE;
35799ebb4caSwyllys 						break;
35899ebb4caSwyllys 					}
35999ebb4caSwyllys 					if (bytes != NULL)
36099ebb4caSwyllys 						free(bytes);
36199ebb4caSwyllys 					flags |= KC_OCSP_RESP_CERT_SERIAL;
36299ebb4caSwyllys 					ocsp_set_attr++;
36399ebb4caSwyllys 				}
36499ebb4caSwyllys 				break;
36599ebb4caSwyllys 			case 'y':
36699ebb4caSwyllys 				ocsp_none_opt = get_boolean(optarg_av);
36799ebb4caSwyllys 				if (ocsp_none_opt == -1) {
36899ebb4caSwyllys 					(void) fprintf(stderr,
36999ebb4caSwyllys 					    gettext("Error boolean input.\n"));
37099ebb4caSwyllys 					rv = KC_ERR_USAGE;
37199ebb4caSwyllys 				} else {
37299ebb4caSwyllys 					flags |= KC_OCSP_NONE;
37399ebb4caSwyllys 				}
37499ebb4caSwyllys 				break;
37599ebb4caSwyllys 			case 'c':
37699ebb4caSwyllys 				plc.VAL_CRL_BASEFILENAME =
37799ebb4caSwyllys 				    get_string(optarg_av, &rv);
37899ebb4caSwyllys 				if (plc.VAL_CRL_BASEFILENAME == NULL) {
37999ebb4caSwyllys 					(void) fprintf(stderr, gettext(
38099ebb4caSwyllys 					    "Error basefilename input.\n"));
38199ebb4caSwyllys 				} else {
38299ebb4caSwyllys 					flags |= KC_CRL_BASEFILENAME;
38399ebb4caSwyllys 					crl_set_attr++;
38499ebb4caSwyllys 				}
38599ebb4caSwyllys 				break;
38699ebb4caSwyllys 			case 'I':
38799ebb4caSwyllys 				plc.VAL_CRL_DIRECTORY =
38899ebb4caSwyllys 				    get_string(optarg_av, &rv);
38999ebb4caSwyllys 				if (plc.VAL_CRL_DIRECTORY == NULL) {
39099ebb4caSwyllys 					(void) fprintf(stderr,
39199ebb4caSwyllys 					    gettext("Error boolean input.\n"));
39299ebb4caSwyllys 				} else {
39399ebb4caSwyllys 					flags |= KC_CRL_DIRECTORY;
39499ebb4caSwyllys 					crl_set_attr++;
39599ebb4caSwyllys 				}
39699ebb4caSwyllys 				break;
39799ebb4caSwyllys 			case 'g':
39899ebb4caSwyllys 				plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
39999ebb4caSwyllys 				if (plc.VAL_CRL_GET_URI == -1) {
40099ebb4caSwyllys 					(void) fprintf(stderr,
40199ebb4caSwyllys 					    gettext("Error boolean input.\n"));
40299ebb4caSwyllys 					rv = KC_ERR_USAGE;
40399ebb4caSwyllys 				} else {
40499ebb4caSwyllys 					flags |= KC_CRL_GET_URI;
40599ebb4caSwyllys 					crl_set_attr++;
40699ebb4caSwyllys 				}
40799ebb4caSwyllys 				break;
40899ebb4caSwyllys 			case 'X':
40999ebb4caSwyllys 				plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
41099ebb4caSwyllys 				if (plc.VAL_CRL_PROXY == NULL) {
41199ebb4caSwyllys 					(void) fprintf(stderr,
41299ebb4caSwyllys 					    gettext("Error proxy input.\n"));
41399ebb4caSwyllys 				} else {
41499ebb4caSwyllys 					flags |= KC_CRL_PROXY;
41599ebb4caSwyllys 					crl_set_attr++;
41699ebb4caSwyllys 				}
41799ebb4caSwyllys 				break;
41899ebb4caSwyllys 			case 'S':
41999ebb4caSwyllys 				plc.VAL_CRL_IGNORE_SIGN =
42099ebb4caSwyllys 				    get_boolean(optarg_av);
42199ebb4caSwyllys 				if (plc.VAL_CRL_IGNORE_SIGN == -1) {
42299ebb4caSwyllys 					(void) fprintf(stderr,
42399ebb4caSwyllys 					    gettext("Error boolean input.\n"));
42499ebb4caSwyllys 					rv = KC_ERR_USAGE;
42599ebb4caSwyllys 				} else {
42699ebb4caSwyllys 					flags |= KC_CRL_IGNORE_SIGN;
42799ebb4caSwyllys 					crl_set_attr++;
42899ebb4caSwyllys 				}
42999ebb4caSwyllys 				break;
43099ebb4caSwyllys 			case 'D':
43199ebb4caSwyllys 				plc.VAL_CRL_IGNORE_DATE =
43299ebb4caSwyllys 				    get_boolean(optarg_av);
43399ebb4caSwyllys 				if (plc.VAL_CRL_IGNORE_DATE == -1) {
43499ebb4caSwyllys 					(void) fprintf(stderr,
43599ebb4caSwyllys 					    gettext("Error boolean input.\n"));
43699ebb4caSwyllys 					rv = KC_ERR_USAGE;
43799ebb4caSwyllys 				} else {
43899ebb4caSwyllys 					flags |= KC_CRL_IGNORE_DATE;
43999ebb4caSwyllys 					crl_set_attr++;
44099ebb4caSwyllys 				}
44199ebb4caSwyllys 				break;
44299ebb4caSwyllys 			case 'z':
44399ebb4caSwyllys 				crl_none_opt = get_boolean(optarg_av);
44499ebb4caSwyllys 				if (crl_none_opt == -1) {
44599ebb4caSwyllys 					(void) fprintf(stderr,
44699ebb4caSwyllys 					    gettext("Error boolean input.\n"));
44799ebb4caSwyllys 					rv = KC_ERR_USAGE;
44899ebb4caSwyllys 				} else {
44999ebb4caSwyllys 					flags |= KC_CRL_NONE;
45099ebb4caSwyllys 				}
45199ebb4caSwyllys 				break;
45299ebb4caSwyllys 			case 'u':
45399ebb4caSwyllys 				plc.ku_bits = parseKUlist(optarg_av);
45499ebb4caSwyllys 				if (plc.ku_bits == 0) {
45599ebb4caSwyllys 					(void) fprintf(stderr, gettext(
45699ebb4caSwyllys 					    "Error keyusage input.\n"));
45799ebb4caSwyllys 					rv = KC_ERR_USAGE;
45899ebb4caSwyllys 				} else {
45999ebb4caSwyllys 					flags |= KC_KEYUSAGE;
46099ebb4caSwyllys 				}
46199ebb4caSwyllys 				break;
46299ebb4caSwyllys 			case 'Y':
46399ebb4caSwyllys 				ku_none_opt = get_boolean(optarg_av);
46499ebb4caSwyllys 				if (ku_none_opt == -1) {
46599ebb4caSwyllys 					(void) fprintf(stderr,
46699ebb4caSwyllys 					    gettext("Error boolean input.\n"));
46799ebb4caSwyllys 					rv = KC_ERR_USAGE;
46899ebb4caSwyllys 				} else {
46999ebb4caSwyllys 					flags |= KC_KEYUSAGE_NONE;
47099ebb4caSwyllys 				}
47199ebb4caSwyllys 				break;
47299ebb4caSwyllys 			case 'E':
47399ebb4caSwyllys 				if (parseEKUNames(optarg_av, &plc) != 0) {
47499ebb4caSwyllys 					(void) fprintf(stderr,
47599ebb4caSwyllys 					    gettext("Error EKU input.\n"));
47699ebb4caSwyllys 					rv = KC_ERR_USAGE;
47799ebb4caSwyllys 				} else {
47899ebb4caSwyllys 					flags |= KC_EKUS;
47999ebb4caSwyllys 				}
48099ebb4caSwyllys 				break;
48199ebb4caSwyllys 			case 'O':
48299ebb4caSwyllys 				if (parseEKUOIDs(optarg_av, &plc) != 0) {
48399ebb4caSwyllys 					(void) fprintf(stderr,
48499ebb4caSwyllys 					    gettext("Error EKU OID input.\n"));
48599ebb4caSwyllys 					rv = KC_ERR_USAGE;
48699ebb4caSwyllys 				} else {
48799ebb4caSwyllys 					flags |= KC_EKUS;
48899ebb4caSwyllys 				}
48999ebb4caSwyllys 				break;
49099ebb4caSwyllys 			case 'Z':
49199ebb4caSwyllys 				eku_none_opt = get_boolean(optarg_av);
49299ebb4caSwyllys 				if (eku_none_opt == -1) {
49399ebb4caSwyllys 					(void) fprintf(stderr,
49499ebb4caSwyllys 					    gettext("Error boolean input.\n"));
49599ebb4caSwyllys 					rv = KC_ERR_USAGE;
49699ebb4caSwyllys 				} else {
49799ebb4caSwyllys 					flags |= KC_EKUS_NONE;
49899ebb4caSwyllys 				}
49999ebb4caSwyllys 				break;
500*269e59f9SJan Pechanec 			case 'm':
501*269e59f9SJan Pechanec 				mapper_name = get_string(optarg_av, &rv);
502*269e59f9SJan Pechanec 				if (mapper_name == NULL) {
503*269e59f9SJan Pechanec 					(void) fprintf(stderr,
504*269e59f9SJan Pechanec 					    gettext("Error mapper-name "
505*269e59f9SJan Pechanec 					    "input.\n"));
506*269e59f9SJan Pechanec 				}
507*269e59f9SJan Pechanec 				break;
508*269e59f9SJan Pechanec 			case 'M':
509*269e59f9SJan Pechanec 				mapper_dir = get_string(optarg_av, &rv);
510*269e59f9SJan Pechanec 				if (mapper_dir == NULL) {
511*269e59f9SJan Pechanec 					(void) fprintf(stderr,
512*269e59f9SJan Pechanec 					    gettext("Error mapper-directory "
513*269e59f9SJan Pechanec 					    "input.\n"));
514*269e59f9SJan Pechanec 				}
515*269e59f9SJan Pechanec 				break;
516*269e59f9SJan Pechanec 			case 'Q':
517*269e59f9SJan Pechanec 				mapper_pathname = get_string(optarg_av, &rv);
518*269e59f9SJan Pechanec 				if (mapper_pathname == NULL) {
519*269e59f9SJan Pechanec 					(void) fprintf(stderr,
520*269e59f9SJan Pechanec 					    gettext("Error mapper-pathname "
521*269e59f9SJan Pechanec 					    "input.\n"));
522*269e59f9SJan Pechanec 				}
523*269e59f9SJan Pechanec 				break;
524*269e59f9SJan Pechanec 			case 'q':
525*269e59f9SJan Pechanec 				plc.mapper.options = get_string(optarg_av, &rv);
526*269e59f9SJan Pechanec 				rv = 0; /* its ok for this to be NULL */
527*269e59f9SJan Pechanec 				flags |= KC_MAPPER_OPTIONS;
528*269e59f9SJan Pechanec 				break;
52999ebb4caSwyllys 			default:
53099ebb4caSwyllys 				(void) fprintf(stderr,
53199ebb4caSwyllys 				    gettext("Error input option.\n"));
53299ebb4caSwyllys 				rv = KC_ERR_USAGE;
53399ebb4caSwyllys 				break;
53499ebb4caSwyllys 		}
53599ebb4caSwyllys 		if (rv != KC_OK)
53699ebb4caSwyllys 			goto out;
53799ebb4caSwyllys 	}
53899ebb4caSwyllys 
53999ebb4caSwyllys 	/* No additional args allowed. */
54099ebb4caSwyllys 	argc -= optind_av;
54199ebb4caSwyllys 	if (argc) {
54299ebb4caSwyllys 		(void) fprintf(stderr,
54399ebb4caSwyllys 		    gettext("Error input option\n"));
54499ebb4caSwyllys 		rv = KC_ERR_USAGE;
54599ebb4caSwyllys 		goto out;
54699ebb4caSwyllys 	}
54799ebb4caSwyllys 
54899ebb4caSwyllys 	if (filename == NULL) {
54999ebb4caSwyllys 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
55099ebb4caSwyllys 		if (filename == NULL) {
55199ebb4caSwyllys 			rv = KC_ERR_MEMORY;
55299ebb4caSwyllys 			goto out;
55399ebb4caSwyllys 		}
55499ebb4caSwyllys 	}
55599ebb4caSwyllys 
55699ebb4caSwyllys 	/*
55799ebb4caSwyllys 	 * Must have a policy name. The policy name can not be default
55899ebb4caSwyllys 	 * if using the default policy file.
55999ebb4caSwyllys 	 */
56099ebb4caSwyllys 	if (plc.name == NULL) {
56199ebb4caSwyllys 		(void) fprintf(stderr,
56299ebb4caSwyllys 		    gettext("You must specify a policy name.\n"));
56399ebb4caSwyllys 		rv = KC_ERR_USAGE;
56499ebb4caSwyllys 		goto out;
56599ebb4caSwyllys 	} else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
56699ebb4caSwyllys 	    strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
56799ebb4caSwyllys 		(void) fprintf(stderr,
56899ebb4caSwyllys 		    gettext("Can not modify the default policy in the default "
56999ebb4caSwyllys 		    "policy file.\n"));
57099ebb4caSwyllys 		rv = KC_ERR_USAGE;
57199ebb4caSwyllys 		goto out;
57299ebb4caSwyllys 	}
57399ebb4caSwyllys 
57499ebb4caSwyllys 	/* Check the access permission of the policy DB */
57599ebb4caSwyllys 	if (access(filename, W_OK) < 0) {
57699ebb4caSwyllys 		int err = errno;
57799ebb4caSwyllys 		(void) fprintf(stderr,
57899ebb4caSwyllys 		    gettext("Cannot access \"%s\" for modify - %s\n"),
57999ebb4caSwyllys 		    filename, strerror(err));
58099ebb4caSwyllys 		rv = KC_ERR_ACCESS;
58199ebb4caSwyllys 		goto out;
58299ebb4caSwyllys 	}
58399ebb4caSwyllys 
58499ebb4caSwyllys 	/* Try to load the named policy from the DB */
58530a5e8faSwyllys 	ret = kmf_get_policy(filename, plc.name, &oplc);
58699ebb4caSwyllys 	if (ret != KMF_OK) {
58799ebb4caSwyllys 		(void) fprintf(stderr,
58899ebb4caSwyllys 		    gettext("Error loading policy \"%s\" from %s\n"), filename,
58999ebb4caSwyllys 		    plc.name);
59099ebb4caSwyllys 		return (KC_ERR_FIND_POLICY);
59199ebb4caSwyllys 	}
59299ebb4caSwyllys 
59399ebb4caSwyllys 	/* Update the general policy attributes. */
59499ebb4caSwyllys 	if (flags & KC_IGNORE_DATE)
59599ebb4caSwyllys 		oplc.ignore_date = plc.ignore_date;
59699ebb4caSwyllys 
59799ebb4caSwyllys 	if (flags & KC_IGNORE_UNKNOWN_EKUS)
59899ebb4caSwyllys 		oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus;
59999ebb4caSwyllys 
60099ebb4caSwyllys 	if (flags & KC_IGNORE_TRUST_ANCHOR)
60199ebb4caSwyllys 		oplc.ignore_trust_anchor = plc.ignore_trust_anchor;
60299ebb4caSwyllys 
60399ebb4caSwyllys 	if (flags & KC_VALIDITY_ADJUSTTIME) {
60499ebb4caSwyllys 		if (oplc.validity_adjusttime)
60599ebb4caSwyllys 			free(oplc.validity_adjusttime);
60699ebb4caSwyllys 		oplc.validity_adjusttime =
60799ebb4caSwyllys 		    plc.validity_adjusttime;
60899ebb4caSwyllys 	}
60999ebb4caSwyllys 
61099ebb4caSwyllys 	if (flags & KC_TA_NAME) {
61199ebb4caSwyllys 		if (oplc.ta_name)
61299ebb4caSwyllys 			free(oplc.ta_name);
61399ebb4caSwyllys 		oplc.ta_name = plc.ta_name;
61499ebb4caSwyllys 	}
61599ebb4caSwyllys 	if (flags & KC_TA_SERIAL) {
61699ebb4caSwyllys 		if (oplc.ta_serial)
61799ebb4caSwyllys 			free(oplc.ta_serial);
61899ebb4caSwyllys 		oplc.ta_serial = plc.ta_serial;
61999ebb4caSwyllys 	}
62099ebb4caSwyllys 
621*269e59f9SJan Pechanec 	/*
622*269e59f9SJan Pechanec 	 * There are some combinations of attributes that are not valid.
623*269e59f9SJan Pechanec 	 *
624*269e59f9SJan Pechanec 	 * First, setting mapper-name (with optional mapper-directory) and
625*269e59f9SJan Pechanec 	 * mapper-pathname is mutually exclusive.
626*269e59f9SJan Pechanec 	 */
627*269e59f9SJan Pechanec 	if ((mapper_name != NULL && mapper_pathname != NULL) ||
628*269e59f9SJan Pechanec 	    (mapper_name != NULL && oplc.mapper.pathname != NULL) ||
629*269e59f9SJan Pechanec 	    (mapper_pathname != NULL && oplc.mapper.mapname != NULL) ||
630*269e59f9SJan Pechanec 	    /* Mapper directory can be set only if mapper name is set. */
631*269e59f9SJan Pechanec 	    (mapper_dir != NULL && mapper_pathname != NULL) ||
632*269e59f9SJan Pechanec 	    (mapper_dir != NULL && mapper_name == NULL &&
633*269e59f9SJan Pechanec 	    oplc.mapper.mapname == NULL) ||
634*269e59f9SJan Pechanec 	    (mapper_dir != NULL && oplc.mapper.pathname != NULL) ||
635*269e59f9SJan Pechanec 	    /* Options can be set only if mapper name or pathname is set. */
636*269e59f9SJan Pechanec 	    ((plc.mapper.options != NULL || oplc.mapper.options != NULL) &&
637*269e59f9SJan Pechanec 	    (mapper_name == NULL && oplc.mapper.mapname == NULL &&
638*269e59f9SJan Pechanec 	    mapper_pathname == NULL && oplc.mapper.pathname == NULL))) {
639*269e59f9SJan Pechanec 		(void) fprintf(stderr,
640*269e59f9SJan Pechanec 		    gettext("Error in mapper input options\n"));
641*269e59f9SJan Pechanec 		if (mapper_name != NULL)
642*269e59f9SJan Pechanec 			free(mapper_name);
643*269e59f9SJan Pechanec 		if (mapper_pathname != NULL)
644*269e59f9SJan Pechanec 			free(mapper_pathname);
645*269e59f9SJan Pechanec 		if (mapper_dir != NULL)
646*269e59f9SJan Pechanec 			free(mapper_dir);
647*269e59f9SJan Pechanec 		if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL)
648*269e59f9SJan Pechanec 			free(plc.mapper.options);
649*269e59f9SJan Pechanec 		rv = KC_ERR_USAGE;
650*269e59f9SJan Pechanec 		goto out;
651*269e59f9SJan Pechanec 	} else {
652*269e59f9SJan Pechanec 		if (mapper_name != NULL)
653*269e59f9SJan Pechanec 			plc.mapper.mapname = mapper_name;
654*269e59f9SJan Pechanec 		if (mapper_pathname != NULL)
655*269e59f9SJan Pechanec 			plc.mapper.pathname = mapper_pathname;
656*269e59f9SJan Pechanec 		if (mapper_dir != NULL)
657*269e59f9SJan Pechanec 			plc.mapper.dir = mapper_dir;
658*269e59f9SJan Pechanec 	}
659*269e59f9SJan Pechanec 
660*269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname);
661*269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname);
662*269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir);
663*269e59f9SJan Pechanec 
664*269e59f9SJan Pechanec 	if (flags & KC_MAPPER_OPTIONS) {
665*269e59f9SJan Pechanec 		if (oplc.mapper.options != NULL)
666*269e59f9SJan Pechanec 			free(oplc.mapper.options);
667*269e59f9SJan Pechanec 		oplc.mapper.options = plc.mapper.options;
668*269e59f9SJan Pechanec 	}
669*269e59f9SJan Pechanec 
67099ebb4caSwyllys 	/* Update the OCSP policy */
67199ebb4caSwyllys 	if (ocsp_none_opt == B_TRUE) {
67299ebb4caSwyllys 		if (ocsp_set_attr > 0) {
67399ebb4caSwyllys 			(void) fprintf(stderr,
67499ebb4caSwyllys 			    gettext("Can not set ocsp-none=true and other "
67599ebb4caSwyllys 			    "OCSP attributes at the same time.\n"));
67699ebb4caSwyllys 			rv = KC_ERR_USAGE;
67799ebb4caSwyllys 			goto out;
67899ebb4caSwyllys 		}
67999ebb4caSwyllys 
68099ebb4caSwyllys 		/*
68199ebb4caSwyllys 		 * If the original policy does not have OCSP checking,
68299ebb4caSwyllys 		 * then we do not need to do anything.  If the original
68399ebb4caSwyllys 		 * policy has the OCSP checking, then we need to release the
68499ebb4caSwyllys 		 * space of OCSP attributes and turn the OCSP checking off.
68599ebb4caSwyllys 		 */
68699ebb4caSwyllys 		if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) {
68799ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.responderURI) {
68899ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.responderURI);
68999ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.responderURI = NULL;
69099ebb4caSwyllys 			}
69199ebb4caSwyllys 
69299ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.proxy) {
69399ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.proxy);
69499ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.proxy = NULL;
69599ebb4caSwyllys 			}
69699ebb4caSwyllys 
69799ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.response_lifetime) {
69899ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.response_lifetime);
69999ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.response_lifetime = NULL;
70099ebb4caSwyllys 			}
70199ebb4caSwyllys 
70299ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_NAME) {
70399ebb4caSwyllys 				free(oplc.VAL_OCSP_RESP_CERT.name);
70499ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT.name = NULL;
70599ebb4caSwyllys 			}
70699ebb4caSwyllys 
70799ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_SERIAL) {
70899ebb4caSwyllys 				free(oplc.VAL_OCSP_RESP_CERT.serial);
70999ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT.serial = NULL;
71099ebb4caSwyllys 			}
71199ebb4caSwyllys 
71299ebb4caSwyllys 			/* Turn off the OCSP checking */
71399ebb4caSwyllys 			oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP;
71499ebb4caSwyllys 		}
71599ebb4caSwyllys 
71699ebb4caSwyllys 	} else {
71799ebb4caSwyllys 		/*
71899ebb4caSwyllys 		 * If the "ocsp-none" option is not set or is set to false,
71999ebb4caSwyllys 		 * then we only need to do the modification if there is at
72099ebb4caSwyllys 		 * least one OCSP attribute is specified.
72199ebb4caSwyllys 		 */
72299ebb4caSwyllys 		if (ocsp_set_attr > 0) {
72399ebb4caSwyllys 			if (flags & KC_OCSP_RESPONDER_URI) {
72499ebb4caSwyllys 				if (oplc.VAL_OCSP_RESPONDER_URI)
72599ebb4caSwyllys 					free(oplc.VAL_OCSP_RESPONDER_URI);
72699ebb4caSwyllys 				oplc.VAL_OCSP_RESPONDER_URI =
72799ebb4caSwyllys 				    plc.VAL_OCSP_RESPONDER_URI;
72899ebb4caSwyllys 			}
72999ebb4caSwyllys 
73099ebb4caSwyllys 			if (flags & KC_OCSP_PROXY) {
73199ebb4caSwyllys 				if (oplc.VAL_OCSP_PROXY)
73299ebb4caSwyllys 					free(oplc.VAL_OCSP_PROXY);
73399ebb4caSwyllys 				oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY;
73499ebb4caSwyllys 			}
73599ebb4caSwyllys 
73699ebb4caSwyllys 			if (flags & KC_OCSP_URI_FROM_CERT)
73799ebb4caSwyllys 				oplc.VAL_OCSP_URI_FROM_CERT =
73899ebb4caSwyllys 				    plc.VAL_OCSP_URI_FROM_CERT;
73999ebb4caSwyllys 
74099ebb4caSwyllys 			if (flags & KC_OCSP_RESP_LIFETIME) {
74199ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_LIFETIME)
74299ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_LIFETIME);
74399ebb4caSwyllys 				oplc.VAL_OCSP_RESP_LIFETIME =
74499ebb4caSwyllys 				    plc.VAL_OCSP_RESP_LIFETIME;
74599ebb4caSwyllys 			}
74699ebb4caSwyllys 
74799ebb4caSwyllys 			if (flags & KC_OCSP_IGNORE_RESP_SIGN)
74899ebb4caSwyllys 				oplc.VAL_OCSP_IGNORE_RESP_SIGN =
74999ebb4caSwyllys 				    plc.VAL_OCSP_IGNORE_RESP_SIGN;
75099ebb4caSwyllys 
75199ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_NAME) {
75299ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_CERT_NAME)
75399ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_CERT_NAME);
75499ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT_NAME =
75599ebb4caSwyllys 				    plc.VAL_OCSP_RESP_CERT_NAME;
75699ebb4caSwyllys 			}
75799ebb4caSwyllys 
75899ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_SERIAL) {
75999ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_CERT_SERIAL)
76099ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_CERT_SERIAL);
76199ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT_SERIAL =
76299ebb4caSwyllys 				    plc.VAL_OCSP_RESP_CERT_SERIAL;
76399ebb4caSwyllys 			}
76499ebb4caSwyllys 
76599ebb4caSwyllys 			if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL &&
76699ebb4caSwyllys 			    oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL)
76799ebb4caSwyllys 				oplc.VAL_OCSP.has_resp_cert = B_TRUE;
76899ebb4caSwyllys 			else
76999ebb4caSwyllys 				oplc.VAL_OCSP.has_resp_cert = B_FALSE;
77099ebb4caSwyllys 
77199ebb4caSwyllys 			/* Turn on the OCSP checking */
77299ebb4caSwyllys 			oplc.revocation |= KMF_REVOCATION_METHOD_OCSP;
77399ebb4caSwyllys 		}
77499ebb4caSwyllys 	}
77599ebb4caSwyllys 
77699ebb4caSwyllys 	/* Update the CRL policy */
77799ebb4caSwyllys 	if (crl_none_opt == B_TRUE) {
77899ebb4caSwyllys 		if (crl_set_attr > 0) {
77999ebb4caSwyllys 			(void) fprintf(stderr,
78099ebb4caSwyllys 			    gettext("Can not set crl-none=true and other CRL "
78199ebb4caSwyllys 			    "attributes at the same time.\n"));
78299ebb4caSwyllys 			rv = KC_ERR_USAGE;
78399ebb4caSwyllys 			goto out;
78499ebb4caSwyllys 		}
78599ebb4caSwyllys 
78699ebb4caSwyllys 		/*
78799ebb4caSwyllys 		 * If the original policy does not have CRL checking,
78899ebb4caSwyllys 		 * then we do not need to do anything.  If the original
78999ebb4caSwyllys 		 * policy has the CRL checking, then we need to release the
79099ebb4caSwyllys 		 * space of CRL attributes and turn the CRL checking off.
79199ebb4caSwyllys 		 */
79299ebb4caSwyllys 		if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) {
79399ebb4caSwyllys 			if (oplc.VAL_CRL_BASEFILENAME) {
79499ebb4caSwyllys 				free(oplc.VAL_CRL_BASEFILENAME);
79599ebb4caSwyllys 				oplc.VAL_CRL_BASEFILENAME = NULL;
79699ebb4caSwyllys 			}
79799ebb4caSwyllys 
79899ebb4caSwyllys 			if (oplc.VAL_CRL_DIRECTORY) {
79999ebb4caSwyllys 				free(oplc.VAL_CRL_DIRECTORY);
80099ebb4caSwyllys 				oplc.VAL_CRL_DIRECTORY = NULL;
80199ebb4caSwyllys 			}
80299ebb4caSwyllys 
80399ebb4caSwyllys 			if (oplc.VAL_CRL_PROXY) {
80499ebb4caSwyllys 				free(oplc.VAL_CRL_PROXY);
80599ebb4caSwyllys 				oplc.VAL_CRL_PROXY = NULL;
80699ebb4caSwyllys 			}
80799ebb4caSwyllys 
80899ebb4caSwyllys 			/* Turn off the CRL checking */
80999ebb4caSwyllys 			oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL;
81099ebb4caSwyllys 		}
81199ebb4caSwyllys 	} else {
81299ebb4caSwyllys 		/*
81399ebb4caSwyllys 		 * If the "ocsp-none" option is not set or is set to false,
81499ebb4caSwyllys 		 * then we only need to do the modification if there is at
81599ebb4caSwyllys 		 * least one CRL attribute is specified.
81699ebb4caSwyllys 		 */
81799ebb4caSwyllys 		if (crl_set_attr > 0) {
81899ebb4caSwyllys 			if (flags & KC_CRL_BASEFILENAME) {
81999ebb4caSwyllys 				if (oplc.VAL_CRL_BASEFILENAME)
82099ebb4caSwyllys 					free(oplc.VAL_CRL_BASEFILENAME);
82199ebb4caSwyllys 				oplc.VAL_CRL_BASEFILENAME =
82299ebb4caSwyllys 				    plc.VAL_CRL_BASEFILENAME;
82399ebb4caSwyllys 			}
82499ebb4caSwyllys 
82599ebb4caSwyllys 			if (flags & KC_CRL_DIRECTORY) {
82699ebb4caSwyllys 				if (oplc.VAL_CRL_DIRECTORY)
82799ebb4caSwyllys 					free(oplc.VAL_CRL_DIRECTORY);
82899ebb4caSwyllys 				oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY;
82999ebb4caSwyllys 			}
83099ebb4caSwyllys 
83199ebb4caSwyllys 			if (flags & KC_CRL_GET_URI) {
83299ebb4caSwyllys 				oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI;
83399ebb4caSwyllys 			}
83499ebb4caSwyllys 
83599ebb4caSwyllys 			if (flags & KC_CRL_PROXY) {
83699ebb4caSwyllys 				if (oplc.VAL_CRL_PROXY)
83799ebb4caSwyllys 					free(oplc.VAL_CRL_PROXY);
83899ebb4caSwyllys 				oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY;
83999ebb4caSwyllys 			}
84099ebb4caSwyllys 
84199ebb4caSwyllys 			if (flags & KC_CRL_IGNORE_SIGN) {
84299ebb4caSwyllys 				oplc.VAL_CRL_IGNORE_SIGN =
84399ebb4caSwyllys 				    plc.VAL_CRL_IGNORE_SIGN;
84499ebb4caSwyllys 			}
84599ebb4caSwyllys 
84699ebb4caSwyllys 			if (flags & KC_CRL_IGNORE_DATE) {
84799ebb4caSwyllys 				oplc.VAL_CRL_IGNORE_DATE =
84899ebb4caSwyllys 				    plc.VAL_CRL_IGNORE_DATE;
84999ebb4caSwyllys 			}
85099ebb4caSwyllys 
85199ebb4caSwyllys 			/* Turn on the CRL checking */
85299ebb4caSwyllys 			oplc.revocation |= KMF_REVOCATION_METHOD_CRL;
85399ebb4caSwyllys 		}
85499ebb4caSwyllys 	}
85599ebb4caSwyllys 
85699ebb4caSwyllys 	/* Update the Key Usage */
85799ebb4caSwyllys 	if (ku_none_opt == B_TRUE) {
85899ebb4caSwyllys 		if (flags & KC_KEYUSAGE) {
85999ebb4caSwyllys 			(void) fprintf(stderr,
86099ebb4caSwyllys 			    gettext("Can not set keyusage-none=true and "
86199ebb4caSwyllys 			    "modify the keyusage value at the same time.\n"));
86299ebb4caSwyllys 			rv = KC_ERR_USAGE;
86399ebb4caSwyllys 			goto out;
86499ebb4caSwyllys 		}
86599ebb4caSwyllys 
86699ebb4caSwyllys 		oplc.ku_bits = 0;
86799ebb4caSwyllys 	} else {
86899ebb4caSwyllys 		/*
86999ebb4caSwyllys 		 * If the "keyusage-none" option is not set or is set to
87099ebb4caSwyllys 		 * false, then we only need to do the modification if
87199ebb4caSwyllys 		 * the keyusage value is specified.
87299ebb4caSwyllys 		 */
87399ebb4caSwyllys 		if (flags & KC_KEYUSAGE)
87499ebb4caSwyllys 			oplc.ku_bits = plc.ku_bits;
87599ebb4caSwyllys 	}
87699ebb4caSwyllys 
87799ebb4caSwyllys 
87899ebb4caSwyllys 	/* Update the Extended Key Usage */
87999ebb4caSwyllys 	if (eku_none_opt == B_TRUE) {
88099ebb4caSwyllys 		if (flags & KC_EKUS) {
88199ebb4caSwyllys 			(void) fprintf(stderr,
88299ebb4caSwyllys 			    gettext("Can not set eku-none=true and modify "
88399ebb4caSwyllys 			    "EKU values at the same time.\n"));
88499ebb4caSwyllys 			rv = KC_ERR_USAGE;
88599ebb4caSwyllys 			goto out;
88699ebb4caSwyllys 		}
88799ebb4caSwyllys 
88899ebb4caSwyllys 		/* Release current EKU list (if any) */
88999ebb4caSwyllys 		if (oplc.eku_set.eku_count > 0) {
89030a5e8faSwyllys 			kmf_free_eku_policy(&oplc.eku_set);
89199ebb4caSwyllys 			oplc.eku_set.eku_count = 0;
89299ebb4caSwyllys 			oplc.eku_set.ekulist = NULL;
89399ebb4caSwyllys 		}
89499ebb4caSwyllys 	} else {
89599ebb4caSwyllys 		/*
89699ebb4caSwyllys 		 * If the "eku-none" option is not set or is set to false,
89799ebb4caSwyllys 		 * then we only need to do the modification if either
89899ebb4caSwyllys 		 * "ekuname" or "ekuoids" is specified.
89999ebb4caSwyllys 		 */
90099ebb4caSwyllys 		if (flags & KC_EKUS) {
90199ebb4caSwyllys 			/* Release current EKU list (if any) */
90230a5e8faSwyllys 			kmf_free_eku_policy(&oplc.eku_set);
90399ebb4caSwyllys 			oplc.eku_set = plc.eku_set;
90499ebb4caSwyllys 		}
90599ebb4caSwyllys 	}
90699ebb4caSwyllys 
90799ebb4caSwyllys 	/* Do a sanity check on the modified policy */
90830a5e8faSwyllys 	ret = kmf_verify_policy(&oplc);
90999ebb4caSwyllys 	if (ret != KMF_OK) {
91099ebb4caSwyllys 		print_sanity_error(ret);
91199ebb4caSwyllys 		rv = KC_ERR_VERIFY_POLICY;
91299ebb4caSwyllys 		goto out;
91399ebb4caSwyllys 	}
91499ebb4caSwyllys 
91599ebb4caSwyllys 	/* The modify operation is a delete followed by an add */
91630a5e8faSwyllys 	ret = kmf_delete_policy_from_db(oplc.name, filename);
91799ebb4caSwyllys 	if (ret != KMF_OK) {
91899ebb4caSwyllys 		rv = KC_ERR_DELETE_POLICY;
91999ebb4caSwyllys 		goto out;
92099ebb4caSwyllys 	}
92199ebb4caSwyllys 
92299ebb4caSwyllys 	/*
92399ebb4caSwyllys 	 * Now add the modified policy back to the DB.
92499ebb4caSwyllys 	 */
92530a5e8faSwyllys 	ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE);
92699ebb4caSwyllys 	if (ret != KMF_OK) {
92799ebb4caSwyllys 		(void) fprintf(stderr,
92899ebb4caSwyllys 		    gettext("Error adding policy to database: 0x%04x\n"), ret);
92999ebb4caSwyllys 		rv = KC_ERR_ADD_POLICY;
93099ebb4caSwyllys 		goto out;
93199ebb4caSwyllys 	}
93299ebb4caSwyllys 
93399ebb4caSwyllys out:
93499ebb4caSwyllys 	if (filename != NULL)
93599ebb4caSwyllys 		free(filename);
93699ebb4caSwyllys 
93730a5e8faSwyllys 	kmf_free_policy_record(&oplc);
93899ebb4caSwyllys 
93999ebb4caSwyllys 	return (rv);
94099ebb4caSwyllys }
941431deaa0Shylee 
942431deaa0Shylee static int
943431deaa0Shylee kc_modify_plugin(int argc, char *argv[])
944431deaa0Shylee {
945431deaa0Shylee 	int 		rv = KC_OK;
946431deaa0Shylee 	int		opt;
947431deaa0Shylee 	extern int	optind_av;
948431deaa0Shylee 	extern char	*optarg_av;
949431deaa0Shylee 	char 		*keystore_name = NULL;
950431deaa0Shylee 	char		*option = NULL;
951431deaa0Shylee 	boolean_t	modify_plugin = B_FALSE;
952431deaa0Shylee 	boolean_t 	has_option_arg = B_FALSE;
953431deaa0Shylee 	conf_entry_t	*entry = NULL;
954431deaa0Shylee 	FILE		*pfile = NULL;
955431deaa0Shylee 	FILE		*pfile_tmp = NULL;
956431deaa0Shylee 	char		tmpfile_name[MAXPATHLEN];
957431deaa0Shylee 	char 		buffer[MAXPATHLEN];
958431deaa0Shylee 	char 		buffer2[MAXPATHLEN];
959431deaa0Shylee 
960431deaa0Shylee 	while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)"))
961431deaa0Shylee 	    != EOF) {
962431deaa0Shylee 		switch (opt) {
963431deaa0Shylee 		case 'p':
964431deaa0Shylee 			if (modify_plugin) {
965431deaa0Shylee 				(void) fprintf(stderr,
966431deaa0Shylee 				    gettext("duplicate plugin input.\n"));
967431deaa0Shylee 				rv = KC_ERR_USAGE;
968431deaa0Shylee 			} else {
969431deaa0Shylee 				modify_plugin = B_TRUE;
970431deaa0Shylee 			}
971431deaa0Shylee 			break;
972431deaa0Shylee 		case 'k':
973431deaa0Shylee 			if (keystore_name != NULL)
974431deaa0Shylee 				rv = KC_ERR_USAGE;
975431deaa0Shylee 			else {
976431deaa0Shylee 				keystore_name = get_string(optarg_av, &rv);
977431deaa0Shylee 				if (keystore_name == NULL) {
978431deaa0Shylee 					(void) fprintf(stderr, gettext(
979431deaa0Shylee 					    "Error keystore input.\n"));
980431deaa0Shylee 					rv = KC_ERR_USAGE;
981431deaa0Shylee 				}
982431deaa0Shylee 			}
983431deaa0Shylee 			break;
984431deaa0Shylee 		case 'o':
985431deaa0Shylee 			if (has_option_arg) {
986431deaa0Shylee 				(void) fprintf(stderr,
987431deaa0Shylee 				    gettext("duplicate option input.\n"));
988431deaa0Shylee 				rv = KC_ERR_USAGE;
989431deaa0Shylee 			} else {
990431deaa0Shylee 				has_option_arg = B_TRUE;
991431deaa0Shylee 				option = get_string(optarg_av, NULL);
992431deaa0Shylee 			}
993431deaa0Shylee 			break;
994431deaa0Shylee 		default:
995431deaa0Shylee 			(void) fprintf(stderr,
996431deaa0Shylee 			    gettext("Error input option.\n"));
997431deaa0Shylee 			rv = KC_ERR_USAGE;
998431deaa0Shylee 			break;
999431deaa0Shylee 		}
1000431deaa0Shylee 
1001431deaa0Shylee 		if (rv != KC_OK)
1002431deaa0Shylee 			goto out;
1003431deaa0Shylee 	}
1004431deaa0Shylee 
1005431deaa0Shylee 	/* No additional args allowed. */
1006431deaa0Shylee 	argc -= optind_av;
1007431deaa0Shylee 	if (argc) {
1008431deaa0Shylee 		(void) fprintf(stderr,
1009431deaa0Shylee 		    gettext("Error input option\n"));
1010431deaa0Shylee 		rv = KC_ERR_USAGE;
1011431deaa0Shylee 		goto out;
1012431deaa0Shylee 	}
1013431deaa0Shylee 
1014431deaa0Shylee 	if (keystore_name == NULL || has_option_arg == B_FALSE) {
1015431deaa0Shylee 		(void) fprintf(stderr,
1016431deaa0Shylee 		    gettext("Error input option\n"));
1017431deaa0Shylee 		rv = KC_ERR_USAGE;
1018431deaa0Shylee 		goto out;
1019431deaa0Shylee 	}
1020431deaa0Shylee 
1021431deaa0Shylee 	if (strcasecmp(keystore_name, "nss") == 0 ||
1022431deaa0Shylee 	    strcasecmp(keystore_name, "pkcs11") == 0 ||
1023431deaa0Shylee 	    strcasecmp(keystore_name, "file") == 0) {
1024431deaa0Shylee 		(void) fprintf(stderr,
1025431deaa0Shylee 		    gettext("Can not modify the built-in keystore %s\n"),
1026431deaa0Shylee 		    keystore_name);
1027431deaa0Shylee 		rv = KC_ERR_USAGE;
1028431deaa0Shylee 		goto out;
1029431deaa0Shylee 	}
1030431deaa0Shylee 
1031431deaa0Shylee 	entry = get_keystore_entry(keystore_name);
1032431deaa0Shylee 	if (entry == NULL) {
1033431deaa0Shylee 		(void) fprintf(stderr, gettext("%s does not exist.\n"),
1034431deaa0Shylee 		    keystore_name);
1035431deaa0Shylee 		rv = KC_ERR_USAGE;
1036431deaa0Shylee 		goto out;
1037431deaa0Shylee 	}
1038431deaa0Shylee 
1039431deaa0Shylee 	if ((entry->option == NULL && option == NULL) ||
1040431deaa0Shylee 	    (entry->option != NULL && option != NULL &&
1041431deaa0Shylee 	    strcmp(entry->option, option) == 0)) {
1042431deaa0Shylee 		(void) fprintf(stderr, gettext("No change - "
1043431deaa0Shylee 		    "the new option is same as the old option.\n"));
1044431deaa0Shylee 		rv = KC_OK;
1045431deaa0Shylee 		goto out;
1046431deaa0Shylee 	}
1047431deaa0Shylee 
1048431deaa0Shylee 	if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
1049431deaa0Shylee 		err = errno;
1050431deaa0Shylee 		(void) fprintf(stderr,
1051431deaa0Shylee 		    gettext("failed to update the configuration - %s\n"),
1052431deaa0Shylee 		    strerror(err));
1053431deaa0Shylee 		rv = KC_ERR_ACCESS;
1054431deaa0Shylee 		goto out;
1055431deaa0Shylee 	}
1056431deaa0Shylee 
1057431deaa0Shylee 	if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
1058431deaa0Shylee 		err = errno;
1059431deaa0Shylee 		(void) fprintf(stderr,
1060431deaa0Shylee 		    gettext("failed to lock the configuration - %s\n"),
1061431deaa0Shylee 		    strerror(err));
1062431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1063431deaa0Shylee 		goto out;
1064431deaa0Shylee 	}
1065431deaa0Shylee 
1066431deaa0Shylee 	/*
1067431deaa0Shylee 	 * Create a temporary file in the /etc/crypto directory.
1068431deaa0Shylee 	 */
1069431deaa0Shylee 	(void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
1070431deaa0Shylee 	if (mkstemp(tmpfile_name) == -1) {
1071431deaa0Shylee 		err = errno;
1072431deaa0Shylee 		(void) fprintf(stderr,
1073431deaa0Shylee 		    gettext("failed to create a temporary file - %s\n"),
1074431deaa0Shylee 		    strerror(err));
1075431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1076431deaa0Shylee 		goto out;
1077431deaa0Shylee 	}
1078431deaa0Shylee 
1079431deaa0Shylee 	if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
1080431deaa0Shylee 		err = errno;
1081431deaa0Shylee 		(void) fprintf(stderr,
1082431deaa0Shylee 		    gettext("failed to open %s - %s\n"),
1083431deaa0Shylee 		    tmpfile_name, strerror(err));
1084431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1085431deaa0Shylee 		goto out;
1086431deaa0Shylee 	}
1087431deaa0Shylee 
1088431deaa0Shylee 	/*
1089431deaa0Shylee 	 * Loop thru the config file and update the entry.
1090431deaa0Shylee 	 */
1091431deaa0Shylee 	while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
1092431deaa0Shylee 		char *name;
1093431deaa0Shylee 		int len;
1094431deaa0Shylee 
1095431deaa0Shylee 		if (buffer[0] == '#') {
1096431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1097431deaa0Shylee 				rv = KC_ERR_MODIFY_PLUGIN;
1098431deaa0Shylee 				goto out;
1099431deaa0Shylee 			} else {
1100431deaa0Shylee 				continue;
1101431deaa0Shylee 			}
1102431deaa0Shylee 		}
1103431deaa0Shylee 
1104431deaa0Shylee 		/*
1105431deaa0Shylee 		 * make a copy of the original buffer to buffer2.  Also get
1106431deaa0Shylee 		 * rid of the trailing '\n' from buffer2.
1107431deaa0Shylee 		 */
1108431deaa0Shylee 		(void) strlcpy(buffer2, buffer, MAXPATHLEN);
1109431deaa0Shylee 		len = strlen(buffer2);
1110431deaa0Shylee 		if (buffer2[len-1] == '\n') {
1111431deaa0Shylee 			len--;
1112431deaa0Shylee 		}
1113431deaa0Shylee 		buffer2[len] = '\0';
1114431deaa0Shylee 
1115431deaa0Shylee 		if ((name = strtok(buffer2, SEP_COLON)) == NULL) {
1116431deaa0Shylee 			rv = KC_ERR_UNINSTALL;
1117431deaa0Shylee 			goto out;
1118431deaa0Shylee 		}
1119431deaa0Shylee 
1120431deaa0Shylee 		if (strcmp(name, keystore_name) == 0) {
1121431deaa0Shylee 			/* found the entry */
1122431deaa0Shylee 			if (option == NULL)
1123431deaa0Shylee 				(void) snprintf(buffer, MAXPATHLEN,
1124431deaa0Shylee 				    "%s:%s%s\n", keystore_name,
1125431deaa0Shylee 				    CONF_MODULEPATH, entry->modulepath);
1126431deaa0Shylee 			else
1127431deaa0Shylee 				(void) snprintf(buffer, MAXPATHLEN,
1128431deaa0Shylee 				    "%s:%s%s;%s%s\n", keystore_name,
1129431deaa0Shylee 				    CONF_MODULEPATH, entry->modulepath,
1130431deaa0Shylee 				    CONF_OPTION, option);
1131431deaa0Shylee 
1132431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1133431deaa0Shylee 				err = errno;
1134431deaa0Shylee 				(void) fprintf(stderr, gettext(
1135431deaa0Shylee 				    "failed to write to %s: %s\n"),
1136431deaa0Shylee 				    tmpfile_name, strerror(err));
1137431deaa0Shylee 				rv = KC_ERR_MODIFY_PLUGIN;
1138431deaa0Shylee 				goto out;
1139431deaa0Shylee 			}
1140431deaa0Shylee 		} else {
1141431deaa0Shylee 
1142431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1143431deaa0Shylee 				rv = KC_ERR_UNINSTALL;
1144431deaa0Shylee 				goto out;
1145431deaa0Shylee 			}
1146431deaa0Shylee 		}
1147431deaa0Shylee 	}
1148431deaa0Shylee 
1149431deaa0Shylee 	if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
1150431deaa0Shylee 		err = errno;
1151431deaa0Shylee 		(void) fprintf(stderr, gettext(
1152431deaa0Shylee 		    "failed to update the configuration - %s"), strerror(err));
1153431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1154431deaa0Shylee 		goto out;
1155431deaa0Shylee 	}
1156431deaa0Shylee 
1157431deaa0Shylee 	if (chmod(_PATH_KMF_CONF,
1158431deaa0Shylee 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
1159431deaa0Shylee 		err = errno;
1160431deaa0Shylee 		(void) fprintf(stderr, gettext(
1161431deaa0Shylee 		    "failed to update the configuration - %s\n"),
1162431deaa0Shylee 		    strerror(err));
1163431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1164431deaa0Shylee 		goto out;
1165431deaa0Shylee 	}
1166431deaa0Shylee 
1167431deaa0Shylee out:
1168431deaa0Shylee 	if (entry != NULL)
1169431deaa0Shylee 		free_entry(entry);
1170431deaa0Shylee 
1171431deaa0Shylee 	if (pfile != NULL)
1172431deaa0Shylee 		(void) fclose(pfile);
1173431deaa0Shylee 
1174431deaa0Shylee 	if (rv != KC_OK && pfile_tmp != NULL)
1175431deaa0Shylee 		(void) unlink(tmpfile_name);
1176431deaa0Shylee 
1177431deaa0Shylee 	if (pfile_tmp != NULL)
1178431deaa0Shylee 		(void) fclose(pfile_tmp);
1179431deaa0Shylee 
1180431deaa0Shylee 	return (rv);
1181431deaa0Shylee }
1182431deaa0Shylee 
1183431deaa0Shylee 
1184431deaa0Shylee int
1185431deaa0Shylee kc_modify(int argc, char *argv[])
1186431deaa0Shylee {
1187431deaa0Shylee 	if (argc > 2 &&
1188431deaa0Shylee 	    strcmp(argv[0], "modify") == 0 &&
1189431deaa0Shylee 	    strcmp(argv[1], "plugin") == 0) {
1190431deaa0Shylee 		return (kc_modify_plugin(argc, argv));
1191431deaa0Shylee 	} else {
1192431deaa0Shylee 		return (kc_modify_policy(argc, argv));
1193431deaa0Shylee 	}
1194431deaa0Shylee }
1195