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  *
21269e59f9SJan 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
61269e59f9SJan Pechanec #define	KC_MAPPER_OPTIONS		0x2000000
6299ebb4caSwyllys 
63431deaa0Shylee static int err; /* To store errno which may be overwritten by gettext() */
64431deaa0Shylee 
65269e59f9SJan Pechanec #define	UPDATE_IF_DIFFERENT(old, new) \
66269e59f9SJan Pechanec 	if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \
67269e59f9SJan Pechanec 	    (old == NULL && new != NULL)) { \
68269e59f9SJan Pechanec 		if (old != NULL) \
69269e59f9SJan Pechanec 			free(old); \
70269e59f9SJan Pechanec 		old = new; \
71269e59f9SJan Pechanec 	}
72431deaa0Shylee 
7399ebb4caSwyllys int
kc_modify_policy(int argc,char * argv[])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;
82269e59f9SJan Pechanec 	char		*mapper_name = NULL;
83269e59f9SJan Pechanec 	char		*mapper_dir = NULL;
84269e59f9SJan 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,
9830a5e8faSwyllys 	    "i:(dbfile)"
9930a5e8faSwyllys 	    "p:(policy)"
10030a5e8faSwyllys 	    "d:(ignore-date)"
10130a5e8faSwyllys 	    "e:(ignore-unknown-eku)"
10230a5e8faSwyllys 	    "a:(ignore-trust-anchor)"
10330a5e8faSwyllys 	    "v:(validity-adjusttime)"
10430a5e8faSwyllys 	    "t:(ta-name)"
10530a5e8faSwyllys 	    "s:(ta-serial)"
10630a5e8faSwyllys 	    "o:(ocsp-responder)"
10730a5e8faSwyllys 	    "P:(ocsp-proxy)"
10830a5e8faSwyllys 	    "r:(ocsp-use-cert-responder)"
10930a5e8faSwyllys 	    "T:(ocsp-response-lifetime)"
11030a5e8faSwyllys 	    "R:(ocsp-ignore-response-sign)"
11130a5e8faSwyllys 	    "n:(ocsp-responder-cert-name)"
11230a5e8faSwyllys 	    "A:(ocsp-responder-cert-serial)"
11330a5e8faSwyllys 	    "y:(ocsp-none)"
11430a5e8faSwyllys 	    "c:(crl-basefilename)"
11530a5e8faSwyllys 	    "I:(crl-directory)"
11630a5e8faSwyllys 	    "g:(crl-get-crl-uri)"
11730a5e8faSwyllys 	    "X:(crl-proxy)"
11830a5e8faSwyllys 	    "S:(crl-ignore-crl-sign)"
11930a5e8faSwyllys 	    "D:(crl-ignore-crl-date)"
12030a5e8faSwyllys 	    "z:(crl-none)"
12130a5e8faSwyllys 	    "u:(keyusage)"
12230a5e8faSwyllys 	    "Y:(keyusage-none)"
12330a5e8faSwyllys 	    "E:(ekunames)"
12430a5e8faSwyllys 	    "O:(ekuoids)"
125269e59f9SJan Pechanec 	    "m:(mapper-name)"
126269e59f9SJan Pechanec 	    "M:(mapper-directory)"
127269e59f9SJan Pechanec 	    "Q:(mapper-pathname)"
128269e59f9SJan Pechanec 	    "q:(mapper-options)"
12930a5e8faSwyllys 	    "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"));
203*fc2613b0SWyllys Ingersoll 				} else if (strcasecmp(plc.ta_name, "search")) {
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 					}
216*fc2613b0SWyllys Ingersoll 				} else {
217*fc2613b0SWyllys Ingersoll 					flags |= KC_TA_NAME;
21899ebb4caSwyllys 				}
21999ebb4caSwyllys 				break;
22099ebb4caSwyllys 			case 's':
22199ebb4caSwyllys 				plc.ta_serial = get_string(optarg_av, &rv);
22299ebb4caSwyllys 				if (plc.ta_serial == NULL) {
22399ebb4caSwyllys 					(void) fprintf(stderr,
22499ebb4caSwyllys 					    gettext("Error serial input.\n"));
22599ebb4caSwyllys 				} else {
22699ebb4caSwyllys 					uchar_t *bytes = NULL;
22799ebb4caSwyllys 					size_t bytelen;
22899ebb4caSwyllys 
22930a5e8faSwyllys 					ret = kmf_hexstr_to_bytes(
23099ebb4caSwyllys 					    (uchar_t *)plc.ta_serial,
23199ebb4caSwyllys 					    &bytes, &bytelen);
23299ebb4caSwyllys 					if (ret != KMF_OK || bytes == NULL) {
23399ebb4caSwyllys 						(void) fprintf(stderr,
23499ebb4caSwyllys 						    gettext("serial number "
23599ebb4caSwyllys 						    "must be specified as a "
23699ebb4caSwyllys 						    "hex number "
23799ebb4caSwyllys 						    "(ex: 0x0102030405"
23899ebb4caSwyllys 						    "ffeeddee)\n"));
23999ebb4caSwyllys 						rv = KC_ERR_USAGE;
24099ebb4caSwyllys 						break;
24199ebb4caSwyllys 					}
24299ebb4caSwyllys 					if (bytes != NULL)
24399ebb4caSwyllys 						free(bytes);
24499ebb4caSwyllys 					flags |= KC_TA_SERIAL;
24599ebb4caSwyllys 				}
24699ebb4caSwyllys 				break;
24799ebb4caSwyllys 			case 'o':
24899ebb4caSwyllys 				plc.VAL_OCSP_RESPONDER_URI =
24930a5e8faSwyllys 				    get_string(optarg_av, &rv);
25099ebb4caSwyllys 				if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
25199ebb4caSwyllys 					(void) fprintf(stderr,
25299ebb4caSwyllys 					    gettext("Error responder "
25399ebb4caSwyllys 					    "input.\n"));
25499ebb4caSwyllys 				} else {
25599ebb4caSwyllys 					flags |= KC_OCSP_RESPONDER_URI;
25699ebb4caSwyllys 					ocsp_set_attr++;
25799ebb4caSwyllys 				}
25899ebb4caSwyllys 				break;
25999ebb4caSwyllys 			case 'P':
26099ebb4caSwyllys 				plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv);
26199ebb4caSwyllys 				if (plc.VAL_OCSP_PROXY == NULL) {
26299ebb4caSwyllys 					(void) fprintf(stderr,
26399ebb4caSwyllys 					    gettext("Error proxy input.\n"));
26499ebb4caSwyllys 				} else {
26599ebb4caSwyllys 					flags |= KC_OCSP_PROXY;
26699ebb4caSwyllys 					ocsp_set_attr++;
26799ebb4caSwyllys 				}
26899ebb4caSwyllys 				break;
26999ebb4caSwyllys 			case 'r':
27099ebb4caSwyllys 				plc.VAL_OCSP_URI_FROM_CERT =
27199ebb4caSwyllys 				    get_boolean(optarg_av);
27299ebb4caSwyllys 				if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
27399ebb4caSwyllys 					(void) fprintf(stderr,
27499ebb4caSwyllys 					    gettext("Error boolean input.\n"));
27599ebb4caSwyllys 					rv = KC_ERR_USAGE;
27699ebb4caSwyllys 				} else {
27799ebb4caSwyllys 					flags |= KC_OCSP_URI_FROM_CERT;
27899ebb4caSwyllys 					ocsp_set_attr++;
27999ebb4caSwyllys 				}
28099ebb4caSwyllys 				break;
28199ebb4caSwyllys 			case 'T':
28299ebb4caSwyllys 				plc.VAL_OCSP_RESP_LIFETIME =
28399ebb4caSwyllys 				    get_string(optarg_av, &rv);
28499ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
28599ebb4caSwyllys 					(void) fprintf(stderr,
28699ebb4caSwyllys 					    gettext("Error time input.\n"));
28799ebb4caSwyllys 				} else {
28899ebb4caSwyllys 					uint32_t adj;
28999ebb4caSwyllys 					/* for syntax checking */
29099ebb4caSwyllys 					if (str2lifetime(
29199ebb4caSwyllys 					    plc.VAL_OCSP_RESP_LIFETIME,
29299ebb4caSwyllys 					    &adj) < 0) {
29399ebb4caSwyllys 						(void) fprintf(stderr,
29499ebb4caSwyllys 						    gettext("Error time "
29599ebb4caSwyllys 						    "input.\n"));
29699ebb4caSwyllys 						rv = KC_ERR_USAGE;
29799ebb4caSwyllys 					} else {
29899ebb4caSwyllys 						flags |= KC_OCSP_RESP_LIFETIME;
29999ebb4caSwyllys 						ocsp_set_attr++;
30099ebb4caSwyllys 					}
30199ebb4caSwyllys 				}
30299ebb4caSwyllys 				break;
30399ebb4caSwyllys 			case 'R':
30499ebb4caSwyllys 				plc.VAL_OCSP_IGNORE_RESP_SIGN =
30599ebb4caSwyllys 				    get_boolean(optarg_av);
30699ebb4caSwyllys 				if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
30799ebb4caSwyllys 					(void) fprintf(stderr,
30899ebb4caSwyllys 					    gettext("Error boolean input.\n"));
30999ebb4caSwyllys 					rv = KC_ERR_USAGE;
31099ebb4caSwyllys 				} else {
31199ebb4caSwyllys 					flags |= KC_OCSP_IGNORE_RESP_SIGN;
31299ebb4caSwyllys 					ocsp_set_attr++;
31399ebb4caSwyllys 				}
31499ebb4caSwyllys 				break;
31599ebb4caSwyllys 			case 'n':
31699ebb4caSwyllys 				plc.VAL_OCSP_RESP_CERT_NAME =
31799ebb4caSwyllys 				    get_string(optarg_av, &rv);
31899ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
31999ebb4caSwyllys 					(void) fprintf(stderr,
32099ebb4caSwyllys 					    gettext("Error name input.\n"));
32199ebb4caSwyllys 				} else {
32299ebb4caSwyllys 					KMF_X509_NAME respDN;
32399ebb4caSwyllys 					/* for syntax checking */
32430a5e8faSwyllys 					if (kmf_dn_parser(
32599ebb4caSwyllys 					    plc.VAL_OCSP_RESP_CERT_NAME,
32699ebb4caSwyllys 					    &respDN) != KMF_OK) {
32799ebb4caSwyllys 						(void) fprintf(stderr,
32899ebb4caSwyllys 						    gettext("Error name "
32999ebb4caSwyllys 						    "input.\n"));
33099ebb4caSwyllys 						rv = KC_ERR_USAGE;
33199ebb4caSwyllys 					} else {
33230a5e8faSwyllys 						kmf_free_dn(&respDN);
33399ebb4caSwyllys 						flags |= KC_OCSP_RESP_CERT_NAME;
33499ebb4caSwyllys 						ocsp_set_attr++;
33599ebb4caSwyllys 					}
33699ebb4caSwyllys 				}
33799ebb4caSwyllys 				break;
33899ebb4caSwyllys 			case 'A':
33999ebb4caSwyllys 				plc.VAL_OCSP_RESP_CERT_SERIAL =
34099ebb4caSwyllys 				    get_string(optarg_av, &rv);
34199ebb4caSwyllys 				if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
34299ebb4caSwyllys 					(void) fprintf(stderr,
34399ebb4caSwyllys 					    gettext("Error serial input.\n"));
34499ebb4caSwyllys 				} else {
34599ebb4caSwyllys 					uchar_t *bytes = NULL;
34699ebb4caSwyllys 					size_t bytelen;
34799ebb4caSwyllys 
34830a5e8faSwyllys 					ret = kmf_hexstr_to_bytes((uchar_t *)
34999ebb4caSwyllys 					    plc.VAL_OCSP_RESP_CERT_SERIAL,
35099ebb4caSwyllys 					    &bytes, &bytelen);
35199ebb4caSwyllys 					if (ret != KMF_OK || bytes == NULL) {
35299ebb4caSwyllys 						(void) fprintf(stderr,
35399ebb4caSwyllys 						    gettext("serial number "
35499ebb4caSwyllys 						    "must be specified as a "
35599ebb4caSwyllys 						    "hex number "
35699ebb4caSwyllys 						    "(ex: 0x0102030405"
35799ebb4caSwyllys 						    "ffeeddee)\n"));
35899ebb4caSwyllys 						rv = KC_ERR_USAGE;
35999ebb4caSwyllys 						break;
36099ebb4caSwyllys 					}
36199ebb4caSwyllys 					if (bytes != NULL)
36299ebb4caSwyllys 						free(bytes);
36399ebb4caSwyllys 					flags |= KC_OCSP_RESP_CERT_SERIAL;
36499ebb4caSwyllys 					ocsp_set_attr++;
36599ebb4caSwyllys 				}
36699ebb4caSwyllys 				break;
36799ebb4caSwyllys 			case 'y':
36899ebb4caSwyllys 				ocsp_none_opt = get_boolean(optarg_av);
36999ebb4caSwyllys 				if (ocsp_none_opt == -1) {
37099ebb4caSwyllys 					(void) fprintf(stderr,
37199ebb4caSwyllys 					    gettext("Error boolean input.\n"));
37299ebb4caSwyllys 					rv = KC_ERR_USAGE;
37399ebb4caSwyllys 				} else {
37499ebb4caSwyllys 					flags |= KC_OCSP_NONE;
37599ebb4caSwyllys 				}
37699ebb4caSwyllys 				break;
37799ebb4caSwyllys 			case 'c':
37899ebb4caSwyllys 				plc.VAL_CRL_BASEFILENAME =
37999ebb4caSwyllys 				    get_string(optarg_av, &rv);
38099ebb4caSwyllys 				if (plc.VAL_CRL_BASEFILENAME == NULL) {
38199ebb4caSwyllys 					(void) fprintf(stderr, gettext(
38299ebb4caSwyllys 					    "Error basefilename input.\n"));
38399ebb4caSwyllys 				} else {
38499ebb4caSwyllys 					flags |= KC_CRL_BASEFILENAME;
38599ebb4caSwyllys 					crl_set_attr++;
38699ebb4caSwyllys 				}
38799ebb4caSwyllys 				break;
38899ebb4caSwyllys 			case 'I':
38999ebb4caSwyllys 				plc.VAL_CRL_DIRECTORY =
39099ebb4caSwyllys 				    get_string(optarg_av, &rv);
39199ebb4caSwyllys 				if (plc.VAL_CRL_DIRECTORY == NULL) {
39299ebb4caSwyllys 					(void) fprintf(stderr,
39399ebb4caSwyllys 					    gettext("Error boolean input.\n"));
39499ebb4caSwyllys 				} else {
39599ebb4caSwyllys 					flags |= KC_CRL_DIRECTORY;
39699ebb4caSwyllys 					crl_set_attr++;
39799ebb4caSwyllys 				}
39899ebb4caSwyllys 				break;
39999ebb4caSwyllys 			case 'g':
40099ebb4caSwyllys 				plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
40199ebb4caSwyllys 				if (plc.VAL_CRL_GET_URI == -1) {
40299ebb4caSwyllys 					(void) fprintf(stderr,
40399ebb4caSwyllys 					    gettext("Error boolean input.\n"));
40499ebb4caSwyllys 					rv = KC_ERR_USAGE;
40599ebb4caSwyllys 				} else {
40699ebb4caSwyllys 					flags |= KC_CRL_GET_URI;
40799ebb4caSwyllys 					crl_set_attr++;
40899ebb4caSwyllys 				}
40999ebb4caSwyllys 				break;
41099ebb4caSwyllys 			case 'X':
41199ebb4caSwyllys 				plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
41299ebb4caSwyllys 				if (plc.VAL_CRL_PROXY == NULL) {
41399ebb4caSwyllys 					(void) fprintf(stderr,
41499ebb4caSwyllys 					    gettext("Error proxy input.\n"));
41599ebb4caSwyllys 				} else {
41699ebb4caSwyllys 					flags |= KC_CRL_PROXY;
41799ebb4caSwyllys 					crl_set_attr++;
41899ebb4caSwyllys 				}
41999ebb4caSwyllys 				break;
42099ebb4caSwyllys 			case 'S':
42199ebb4caSwyllys 				plc.VAL_CRL_IGNORE_SIGN =
42299ebb4caSwyllys 				    get_boolean(optarg_av);
42399ebb4caSwyllys 				if (plc.VAL_CRL_IGNORE_SIGN == -1) {
42499ebb4caSwyllys 					(void) fprintf(stderr,
42599ebb4caSwyllys 					    gettext("Error boolean input.\n"));
42699ebb4caSwyllys 					rv = KC_ERR_USAGE;
42799ebb4caSwyllys 				} else {
42899ebb4caSwyllys 					flags |= KC_CRL_IGNORE_SIGN;
42999ebb4caSwyllys 					crl_set_attr++;
43099ebb4caSwyllys 				}
43199ebb4caSwyllys 				break;
43299ebb4caSwyllys 			case 'D':
43399ebb4caSwyllys 				plc.VAL_CRL_IGNORE_DATE =
43430a5e8faSwyllys 				    get_boolean(optarg_av);
43599ebb4caSwyllys 				if (plc.VAL_CRL_IGNORE_DATE == -1) {
43699ebb4caSwyllys 					(void) fprintf(stderr,
43799ebb4caSwyllys 					    gettext("Error boolean input.\n"));
43899ebb4caSwyllys 					rv = KC_ERR_USAGE;
43999ebb4caSwyllys 				} else {
44099ebb4caSwyllys 					flags |= KC_CRL_IGNORE_DATE;
44199ebb4caSwyllys 					crl_set_attr++;
44299ebb4caSwyllys 				}
44399ebb4caSwyllys 				break;
44499ebb4caSwyllys 			case 'z':
44599ebb4caSwyllys 				crl_none_opt = get_boolean(optarg_av);
44699ebb4caSwyllys 				if (crl_none_opt == -1) {
44799ebb4caSwyllys 					(void) fprintf(stderr,
44899ebb4caSwyllys 					    gettext("Error boolean input.\n"));
44999ebb4caSwyllys 					rv = KC_ERR_USAGE;
45099ebb4caSwyllys 				} else {
45199ebb4caSwyllys 					flags |= KC_CRL_NONE;
45299ebb4caSwyllys 				}
45399ebb4caSwyllys 				break;
45499ebb4caSwyllys 			case 'u':
45599ebb4caSwyllys 				plc.ku_bits = parseKUlist(optarg_av);
45699ebb4caSwyllys 				if (plc.ku_bits == 0) {
45799ebb4caSwyllys 					(void) fprintf(stderr, gettext(
45899ebb4caSwyllys 					    "Error keyusage input.\n"));
45999ebb4caSwyllys 					rv = KC_ERR_USAGE;
46099ebb4caSwyllys 				} else {
46199ebb4caSwyllys 					flags |= KC_KEYUSAGE;
46299ebb4caSwyllys 				}
46399ebb4caSwyllys 				break;
46499ebb4caSwyllys 			case 'Y':
46599ebb4caSwyllys 				ku_none_opt = get_boolean(optarg_av);
46699ebb4caSwyllys 				if (ku_none_opt == -1) {
46799ebb4caSwyllys 					(void) fprintf(stderr,
46899ebb4caSwyllys 					    gettext("Error boolean input.\n"));
46999ebb4caSwyllys 					rv = KC_ERR_USAGE;
47099ebb4caSwyllys 				} else {
47199ebb4caSwyllys 					flags |= KC_KEYUSAGE_NONE;
47299ebb4caSwyllys 				}
47399ebb4caSwyllys 				break;
47499ebb4caSwyllys 			case 'E':
47599ebb4caSwyllys 				if (parseEKUNames(optarg_av, &plc) != 0) {
47699ebb4caSwyllys 					(void) fprintf(stderr,
47799ebb4caSwyllys 					    gettext("Error EKU input.\n"));
47899ebb4caSwyllys 					rv = KC_ERR_USAGE;
47999ebb4caSwyllys 				} else {
48099ebb4caSwyllys 					flags |= KC_EKUS;
48199ebb4caSwyllys 				}
48299ebb4caSwyllys 				break;
48399ebb4caSwyllys 			case 'O':
48499ebb4caSwyllys 				if (parseEKUOIDs(optarg_av, &plc) != 0) {
48599ebb4caSwyllys 					(void) fprintf(stderr,
48699ebb4caSwyllys 					    gettext("Error EKU OID input.\n"));
48799ebb4caSwyllys 					rv = KC_ERR_USAGE;
48899ebb4caSwyllys 				} else {
48999ebb4caSwyllys 					flags |= KC_EKUS;
49099ebb4caSwyllys 				}
49199ebb4caSwyllys 				break;
49299ebb4caSwyllys 			case 'Z':
49399ebb4caSwyllys 				eku_none_opt = get_boolean(optarg_av);
49499ebb4caSwyllys 				if (eku_none_opt == -1) {
49599ebb4caSwyllys 					(void) fprintf(stderr,
49699ebb4caSwyllys 					    gettext("Error boolean input.\n"));
49799ebb4caSwyllys 					rv = KC_ERR_USAGE;
49899ebb4caSwyllys 				} else {
49999ebb4caSwyllys 					flags |= KC_EKUS_NONE;
50099ebb4caSwyllys 				}
50199ebb4caSwyllys 				break;
502269e59f9SJan Pechanec 			case 'm':
503269e59f9SJan Pechanec 				mapper_name = get_string(optarg_av, &rv);
504269e59f9SJan Pechanec 				if (mapper_name == NULL) {
505269e59f9SJan Pechanec 					(void) fprintf(stderr,
506269e59f9SJan Pechanec 					    gettext("Error mapper-name "
507269e59f9SJan Pechanec 					    "input.\n"));
508269e59f9SJan Pechanec 				}
509269e59f9SJan Pechanec 				break;
510269e59f9SJan Pechanec 			case 'M':
511269e59f9SJan Pechanec 				mapper_dir = get_string(optarg_av, &rv);
512269e59f9SJan Pechanec 				if (mapper_dir == NULL) {
513269e59f9SJan Pechanec 					(void) fprintf(stderr,
514269e59f9SJan Pechanec 					    gettext("Error mapper-directory "
515269e59f9SJan Pechanec 					    "input.\n"));
516269e59f9SJan Pechanec 				}
517269e59f9SJan Pechanec 				break;
518269e59f9SJan Pechanec 			case 'Q':
519269e59f9SJan Pechanec 				mapper_pathname = get_string(optarg_av, &rv);
520269e59f9SJan Pechanec 				if (mapper_pathname == NULL) {
521269e59f9SJan Pechanec 					(void) fprintf(stderr,
522269e59f9SJan Pechanec 					    gettext("Error mapper-pathname "
523269e59f9SJan Pechanec 					    "input.\n"));
524269e59f9SJan Pechanec 				}
525269e59f9SJan Pechanec 				break;
526269e59f9SJan Pechanec 			case 'q':
527269e59f9SJan Pechanec 				plc.mapper.options = get_string(optarg_av, &rv);
528269e59f9SJan Pechanec 				rv = 0; /* its ok for this to be NULL */
529269e59f9SJan Pechanec 				flags |= KC_MAPPER_OPTIONS;
530269e59f9SJan Pechanec 				break;
53199ebb4caSwyllys 			default:
53299ebb4caSwyllys 				(void) fprintf(stderr,
53399ebb4caSwyllys 				    gettext("Error input option.\n"));
53499ebb4caSwyllys 				rv = KC_ERR_USAGE;
53599ebb4caSwyllys 				break;
53699ebb4caSwyllys 		}
53799ebb4caSwyllys 		if (rv != KC_OK)
53899ebb4caSwyllys 			goto out;
53999ebb4caSwyllys 	}
54099ebb4caSwyllys 
54199ebb4caSwyllys 	/* No additional args allowed. */
54299ebb4caSwyllys 	argc -= optind_av;
54399ebb4caSwyllys 	if (argc) {
54499ebb4caSwyllys 		(void) fprintf(stderr,
54599ebb4caSwyllys 		    gettext("Error input option\n"));
54699ebb4caSwyllys 		rv = KC_ERR_USAGE;
54799ebb4caSwyllys 		goto out;
54899ebb4caSwyllys 	}
54999ebb4caSwyllys 
55099ebb4caSwyllys 	if (filename == NULL) {
55199ebb4caSwyllys 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
55299ebb4caSwyllys 		if (filename == NULL) {
55399ebb4caSwyllys 			rv = KC_ERR_MEMORY;
55499ebb4caSwyllys 			goto out;
55599ebb4caSwyllys 		}
55699ebb4caSwyllys 	}
55799ebb4caSwyllys 
55899ebb4caSwyllys 	/*
55999ebb4caSwyllys 	 * Must have a policy name. The policy name can not be default
56099ebb4caSwyllys 	 * if using the default policy file.
56199ebb4caSwyllys 	 */
56299ebb4caSwyllys 	if (plc.name == NULL) {
56399ebb4caSwyllys 		(void) fprintf(stderr,
56499ebb4caSwyllys 		    gettext("You must specify a policy name.\n"));
56599ebb4caSwyllys 		rv = KC_ERR_USAGE;
56699ebb4caSwyllys 		goto out;
56799ebb4caSwyllys 	} else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
56899ebb4caSwyllys 	    strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
56999ebb4caSwyllys 		(void) fprintf(stderr,
57099ebb4caSwyllys 		    gettext("Can not modify the default policy in the default "
57199ebb4caSwyllys 		    "policy file.\n"));
57299ebb4caSwyllys 		rv = KC_ERR_USAGE;
57399ebb4caSwyllys 		goto out;
57499ebb4caSwyllys 	}
57599ebb4caSwyllys 
57699ebb4caSwyllys 	/* Check the access permission of the policy DB */
57799ebb4caSwyllys 	if (access(filename, W_OK) < 0) {
57899ebb4caSwyllys 		int err = errno;
57999ebb4caSwyllys 		(void) fprintf(stderr,
58099ebb4caSwyllys 		    gettext("Cannot access \"%s\" for modify - %s\n"),
58199ebb4caSwyllys 		    filename, strerror(err));
58299ebb4caSwyllys 		rv = KC_ERR_ACCESS;
58399ebb4caSwyllys 		goto out;
58499ebb4caSwyllys 	}
58599ebb4caSwyllys 
58699ebb4caSwyllys 	/* Try to load the named policy from the DB */
58730a5e8faSwyllys 	ret = kmf_get_policy(filename, plc.name, &oplc);
58899ebb4caSwyllys 	if (ret != KMF_OK) {
58999ebb4caSwyllys 		(void) fprintf(stderr,
59099ebb4caSwyllys 		    gettext("Error loading policy \"%s\" from %s\n"), filename,
59199ebb4caSwyllys 		    plc.name);
59299ebb4caSwyllys 		return (KC_ERR_FIND_POLICY);
59399ebb4caSwyllys 	}
59499ebb4caSwyllys 
59599ebb4caSwyllys 	/* Update the general policy attributes. */
59699ebb4caSwyllys 	if (flags & KC_IGNORE_DATE)
59799ebb4caSwyllys 		oplc.ignore_date = plc.ignore_date;
59899ebb4caSwyllys 
59999ebb4caSwyllys 	if (flags & KC_IGNORE_UNKNOWN_EKUS)
60099ebb4caSwyllys 		oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus;
60199ebb4caSwyllys 
60299ebb4caSwyllys 	if (flags & KC_IGNORE_TRUST_ANCHOR)
60399ebb4caSwyllys 		oplc.ignore_trust_anchor = plc.ignore_trust_anchor;
60499ebb4caSwyllys 
60599ebb4caSwyllys 	if (flags & KC_VALIDITY_ADJUSTTIME) {
60699ebb4caSwyllys 		if (oplc.validity_adjusttime)
60799ebb4caSwyllys 			free(oplc.validity_adjusttime);
60899ebb4caSwyllys 		oplc.validity_adjusttime =
60930a5e8faSwyllys 		    plc.validity_adjusttime;
61099ebb4caSwyllys 	}
61199ebb4caSwyllys 
61299ebb4caSwyllys 	if (flags & KC_TA_NAME) {
61399ebb4caSwyllys 		if (oplc.ta_name)
61499ebb4caSwyllys 			free(oplc.ta_name);
61599ebb4caSwyllys 		oplc.ta_name = plc.ta_name;
61699ebb4caSwyllys 	}
61799ebb4caSwyllys 	if (flags & KC_TA_SERIAL) {
61899ebb4caSwyllys 		if (oplc.ta_serial)
61999ebb4caSwyllys 			free(oplc.ta_serial);
62099ebb4caSwyllys 		oplc.ta_serial = plc.ta_serial;
62199ebb4caSwyllys 	}
62299ebb4caSwyllys 
623269e59f9SJan Pechanec 	/*
624269e59f9SJan Pechanec 	 * There are some combinations of attributes that are not valid.
625269e59f9SJan Pechanec 	 *
626269e59f9SJan Pechanec 	 * First, setting mapper-name (with optional mapper-directory) and
627269e59f9SJan Pechanec 	 * mapper-pathname is mutually exclusive.
628269e59f9SJan Pechanec 	 */
629269e59f9SJan Pechanec 	if ((mapper_name != NULL && mapper_pathname != NULL) ||
630269e59f9SJan Pechanec 	    (mapper_name != NULL && oplc.mapper.pathname != NULL) ||
631269e59f9SJan Pechanec 	    (mapper_pathname != NULL && oplc.mapper.mapname != NULL) ||
632269e59f9SJan Pechanec 	    /* Mapper directory can be set only if mapper name is set. */
633269e59f9SJan Pechanec 	    (mapper_dir != NULL && mapper_pathname != NULL) ||
634269e59f9SJan Pechanec 	    (mapper_dir != NULL && mapper_name == NULL &&
635269e59f9SJan Pechanec 	    oplc.mapper.mapname == NULL) ||
636269e59f9SJan Pechanec 	    (mapper_dir != NULL && oplc.mapper.pathname != NULL) ||
637269e59f9SJan Pechanec 	    /* Options can be set only if mapper name or pathname is set. */
638269e59f9SJan Pechanec 	    ((plc.mapper.options != NULL || oplc.mapper.options != NULL) &&
639269e59f9SJan Pechanec 	    (mapper_name == NULL && oplc.mapper.mapname == NULL &&
640269e59f9SJan Pechanec 	    mapper_pathname == NULL && oplc.mapper.pathname == NULL))) {
641269e59f9SJan Pechanec 		(void) fprintf(stderr,
642269e59f9SJan Pechanec 		    gettext("Error in mapper input options\n"));
643269e59f9SJan Pechanec 		if (mapper_name != NULL)
644269e59f9SJan Pechanec 			free(mapper_name);
645269e59f9SJan Pechanec 		if (mapper_pathname != NULL)
646269e59f9SJan Pechanec 			free(mapper_pathname);
647269e59f9SJan Pechanec 		if (mapper_dir != NULL)
648269e59f9SJan Pechanec 			free(mapper_dir);
649269e59f9SJan Pechanec 		if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL)
650269e59f9SJan Pechanec 			free(plc.mapper.options);
651269e59f9SJan Pechanec 		rv = KC_ERR_USAGE;
652269e59f9SJan Pechanec 		goto out;
653269e59f9SJan Pechanec 	} else {
654269e59f9SJan Pechanec 		if (mapper_name != NULL)
655269e59f9SJan Pechanec 			plc.mapper.mapname = mapper_name;
656269e59f9SJan Pechanec 		if (mapper_pathname != NULL)
657269e59f9SJan Pechanec 			plc.mapper.pathname = mapper_pathname;
658269e59f9SJan Pechanec 		if (mapper_dir != NULL)
659269e59f9SJan Pechanec 			plc.mapper.dir = mapper_dir;
660269e59f9SJan Pechanec 	}
661269e59f9SJan Pechanec 
662269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname);
663269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname);
664269e59f9SJan Pechanec 	UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir);
665269e59f9SJan Pechanec 
666269e59f9SJan Pechanec 	if (flags & KC_MAPPER_OPTIONS) {
667269e59f9SJan Pechanec 		if (oplc.mapper.options != NULL)
668269e59f9SJan Pechanec 			free(oplc.mapper.options);
669269e59f9SJan Pechanec 		oplc.mapper.options = plc.mapper.options;
670269e59f9SJan Pechanec 	}
671269e59f9SJan Pechanec 
67299ebb4caSwyllys 	/* Update the OCSP policy */
67399ebb4caSwyllys 	if (ocsp_none_opt == B_TRUE) {
67499ebb4caSwyllys 		if (ocsp_set_attr > 0) {
67599ebb4caSwyllys 			(void) fprintf(stderr,
67699ebb4caSwyllys 			    gettext("Can not set ocsp-none=true and other "
67799ebb4caSwyllys 			    "OCSP attributes at the same time.\n"));
67899ebb4caSwyllys 			rv = KC_ERR_USAGE;
67999ebb4caSwyllys 			goto out;
68099ebb4caSwyllys 		}
68199ebb4caSwyllys 
68299ebb4caSwyllys 		/*
68399ebb4caSwyllys 		 * If the original policy does not have OCSP checking,
68499ebb4caSwyllys 		 * then we do not need to do anything.  If the original
68599ebb4caSwyllys 		 * policy has the OCSP checking, then we need to release the
68699ebb4caSwyllys 		 * space of OCSP attributes and turn the OCSP checking off.
68799ebb4caSwyllys 		 */
68899ebb4caSwyllys 		if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) {
68999ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.responderURI) {
69099ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.responderURI);
69199ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.responderURI = NULL;
69299ebb4caSwyllys 			}
69399ebb4caSwyllys 
69499ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.proxy) {
69599ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.proxy);
69699ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.proxy = NULL;
69799ebb4caSwyllys 			}
69899ebb4caSwyllys 
69999ebb4caSwyllys 			if (oplc.VAL_OCSP_BASIC.response_lifetime) {
70099ebb4caSwyllys 				free(oplc.VAL_OCSP_BASIC.response_lifetime);
70199ebb4caSwyllys 				oplc.VAL_OCSP_BASIC.response_lifetime = NULL;
70299ebb4caSwyllys 			}
70399ebb4caSwyllys 
70499ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_NAME) {
70599ebb4caSwyllys 				free(oplc.VAL_OCSP_RESP_CERT.name);
70699ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT.name = NULL;
70799ebb4caSwyllys 			}
70899ebb4caSwyllys 
70999ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_SERIAL) {
71099ebb4caSwyllys 				free(oplc.VAL_OCSP_RESP_CERT.serial);
71199ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT.serial = NULL;
71299ebb4caSwyllys 			}
71399ebb4caSwyllys 
71499ebb4caSwyllys 			/* Turn off the OCSP checking */
71599ebb4caSwyllys 			oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP;
71699ebb4caSwyllys 		}
71799ebb4caSwyllys 
71899ebb4caSwyllys 	} else {
71999ebb4caSwyllys 		/*
72099ebb4caSwyllys 		 * If the "ocsp-none" option is not set or is set to false,
72199ebb4caSwyllys 		 * then we only need to do the modification if there is at
72299ebb4caSwyllys 		 * least one OCSP attribute is specified.
72399ebb4caSwyllys 		 */
72499ebb4caSwyllys 		if (ocsp_set_attr > 0) {
72599ebb4caSwyllys 			if (flags & KC_OCSP_RESPONDER_URI) {
72699ebb4caSwyllys 				if (oplc.VAL_OCSP_RESPONDER_URI)
72799ebb4caSwyllys 					free(oplc.VAL_OCSP_RESPONDER_URI);
72899ebb4caSwyllys 				oplc.VAL_OCSP_RESPONDER_URI =
72930a5e8faSwyllys 				    plc.VAL_OCSP_RESPONDER_URI;
73099ebb4caSwyllys 			}
73199ebb4caSwyllys 
73299ebb4caSwyllys 			if (flags & KC_OCSP_PROXY) {
73399ebb4caSwyllys 				if (oplc.VAL_OCSP_PROXY)
73499ebb4caSwyllys 					free(oplc.VAL_OCSP_PROXY);
73599ebb4caSwyllys 				oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY;
73699ebb4caSwyllys 			}
73799ebb4caSwyllys 
73899ebb4caSwyllys 			if (flags & KC_OCSP_URI_FROM_CERT)
73999ebb4caSwyllys 				oplc.VAL_OCSP_URI_FROM_CERT =
74030a5e8faSwyllys 				    plc.VAL_OCSP_URI_FROM_CERT;
74199ebb4caSwyllys 
74299ebb4caSwyllys 			if (flags & KC_OCSP_RESP_LIFETIME) {
74399ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_LIFETIME)
74499ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_LIFETIME);
74599ebb4caSwyllys 				oplc.VAL_OCSP_RESP_LIFETIME =
74630a5e8faSwyllys 				    plc.VAL_OCSP_RESP_LIFETIME;
74799ebb4caSwyllys 			}
74899ebb4caSwyllys 
74999ebb4caSwyllys 			if (flags & KC_OCSP_IGNORE_RESP_SIGN)
75099ebb4caSwyllys 				oplc.VAL_OCSP_IGNORE_RESP_SIGN =
75130a5e8faSwyllys 				    plc.VAL_OCSP_IGNORE_RESP_SIGN;
75299ebb4caSwyllys 
75399ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_NAME) {
75499ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_CERT_NAME)
75599ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_CERT_NAME);
75699ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT_NAME =
75730a5e8faSwyllys 				    plc.VAL_OCSP_RESP_CERT_NAME;
75899ebb4caSwyllys 			}
75999ebb4caSwyllys 
76099ebb4caSwyllys 			if (flags & KC_OCSP_RESP_CERT_SERIAL) {
76199ebb4caSwyllys 				if (oplc.VAL_OCSP_RESP_CERT_SERIAL)
76299ebb4caSwyllys 					free(oplc.VAL_OCSP_RESP_CERT_SERIAL);
76399ebb4caSwyllys 				oplc.VAL_OCSP_RESP_CERT_SERIAL =
76430a5e8faSwyllys 				    plc.VAL_OCSP_RESP_CERT_SERIAL;
76599ebb4caSwyllys 			}
76699ebb4caSwyllys 
76799ebb4caSwyllys 			if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL &&
76899ebb4caSwyllys 			    oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL)
76999ebb4caSwyllys 				oplc.VAL_OCSP.has_resp_cert = B_TRUE;
77099ebb4caSwyllys 			else
77199ebb4caSwyllys 				oplc.VAL_OCSP.has_resp_cert = B_FALSE;
77299ebb4caSwyllys 
77399ebb4caSwyllys 			/* Turn on the OCSP checking */
77499ebb4caSwyllys 			oplc.revocation |= KMF_REVOCATION_METHOD_OCSP;
77599ebb4caSwyllys 		}
77699ebb4caSwyllys 	}
77799ebb4caSwyllys 
77899ebb4caSwyllys 	/* Update the CRL policy */
77999ebb4caSwyllys 	if (crl_none_opt == B_TRUE) {
78099ebb4caSwyllys 		if (crl_set_attr > 0) {
78199ebb4caSwyllys 			(void) fprintf(stderr,
78299ebb4caSwyllys 			    gettext("Can not set crl-none=true and other CRL "
78399ebb4caSwyllys 			    "attributes at the same time.\n"));
78499ebb4caSwyllys 			rv = KC_ERR_USAGE;
78599ebb4caSwyllys 			goto out;
78699ebb4caSwyllys 		}
78799ebb4caSwyllys 
78899ebb4caSwyllys 		/*
78999ebb4caSwyllys 		 * If the original policy does not have CRL checking,
79099ebb4caSwyllys 		 * then we do not need to do anything.  If the original
79199ebb4caSwyllys 		 * policy has the CRL checking, then we need to release the
79299ebb4caSwyllys 		 * space of CRL attributes and turn the CRL checking off.
79399ebb4caSwyllys 		 */
79499ebb4caSwyllys 		if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) {
79599ebb4caSwyllys 			if (oplc.VAL_CRL_BASEFILENAME) {
79699ebb4caSwyllys 				free(oplc.VAL_CRL_BASEFILENAME);
79799ebb4caSwyllys 				oplc.VAL_CRL_BASEFILENAME = NULL;
79899ebb4caSwyllys 			}
79999ebb4caSwyllys 
80099ebb4caSwyllys 			if (oplc.VAL_CRL_DIRECTORY) {
80199ebb4caSwyllys 				free(oplc.VAL_CRL_DIRECTORY);
80299ebb4caSwyllys 				oplc.VAL_CRL_DIRECTORY = NULL;
80399ebb4caSwyllys 			}
80499ebb4caSwyllys 
80599ebb4caSwyllys 			if (oplc.VAL_CRL_PROXY) {
80699ebb4caSwyllys 				free(oplc.VAL_CRL_PROXY);
80799ebb4caSwyllys 				oplc.VAL_CRL_PROXY = NULL;
80899ebb4caSwyllys 			}
80999ebb4caSwyllys 
81099ebb4caSwyllys 			/* Turn off the CRL checking */
81199ebb4caSwyllys 			oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL;
81299ebb4caSwyllys 		}
81399ebb4caSwyllys 	} else {
81499ebb4caSwyllys 		/*
81599ebb4caSwyllys 		 * If the "ocsp-none" option is not set or is set to false,
81699ebb4caSwyllys 		 * then we only need to do the modification if there is at
81799ebb4caSwyllys 		 * least one CRL attribute is specified.
81899ebb4caSwyllys 		 */
81999ebb4caSwyllys 		if (crl_set_attr > 0) {
82099ebb4caSwyllys 			if (flags & KC_CRL_BASEFILENAME) {
82199ebb4caSwyllys 				if (oplc.VAL_CRL_BASEFILENAME)
82299ebb4caSwyllys 					free(oplc.VAL_CRL_BASEFILENAME);
82399ebb4caSwyllys 				oplc.VAL_CRL_BASEFILENAME =
82499ebb4caSwyllys 				    plc.VAL_CRL_BASEFILENAME;
82599ebb4caSwyllys 			}
82699ebb4caSwyllys 
82799ebb4caSwyllys 			if (flags & KC_CRL_DIRECTORY) {
82899ebb4caSwyllys 				if (oplc.VAL_CRL_DIRECTORY)
82999ebb4caSwyllys 					free(oplc.VAL_CRL_DIRECTORY);
83099ebb4caSwyllys 				oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY;
83199ebb4caSwyllys 			}
83299ebb4caSwyllys 
83399ebb4caSwyllys 			if (flags & KC_CRL_GET_URI) {
83499ebb4caSwyllys 				oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI;
83599ebb4caSwyllys 			}
83699ebb4caSwyllys 
83799ebb4caSwyllys 			if (flags & KC_CRL_PROXY) {
83899ebb4caSwyllys 				if (oplc.VAL_CRL_PROXY)
83999ebb4caSwyllys 					free(oplc.VAL_CRL_PROXY);
84099ebb4caSwyllys 				oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY;
84199ebb4caSwyllys 			}
84299ebb4caSwyllys 
84399ebb4caSwyllys 			if (flags & KC_CRL_IGNORE_SIGN) {
84499ebb4caSwyllys 				oplc.VAL_CRL_IGNORE_SIGN =
84599ebb4caSwyllys 				    plc.VAL_CRL_IGNORE_SIGN;
84699ebb4caSwyllys 			}
84799ebb4caSwyllys 
84899ebb4caSwyllys 			if (flags & KC_CRL_IGNORE_DATE) {
84999ebb4caSwyllys 				oplc.VAL_CRL_IGNORE_DATE =
85099ebb4caSwyllys 				    plc.VAL_CRL_IGNORE_DATE;
85199ebb4caSwyllys 			}
85299ebb4caSwyllys 
85399ebb4caSwyllys 			/* Turn on the CRL checking */
85499ebb4caSwyllys 			oplc.revocation |= KMF_REVOCATION_METHOD_CRL;
85599ebb4caSwyllys 		}
85699ebb4caSwyllys 	}
85799ebb4caSwyllys 
85899ebb4caSwyllys 	/* Update the Key Usage */
85999ebb4caSwyllys 	if (ku_none_opt == B_TRUE) {
86099ebb4caSwyllys 		if (flags & KC_KEYUSAGE) {
86199ebb4caSwyllys 			(void) fprintf(stderr,
86299ebb4caSwyllys 			    gettext("Can not set keyusage-none=true and "
86399ebb4caSwyllys 			    "modify the keyusage value at the same time.\n"));
86499ebb4caSwyllys 			rv = KC_ERR_USAGE;
86599ebb4caSwyllys 			goto out;
86699ebb4caSwyllys 		}
86799ebb4caSwyllys 
86899ebb4caSwyllys 		oplc.ku_bits = 0;
86999ebb4caSwyllys 	} else {
87099ebb4caSwyllys 		/*
87199ebb4caSwyllys 		 * If the "keyusage-none" option is not set or is set to
87299ebb4caSwyllys 		 * false, then we only need to do the modification if
87399ebb4caSwyllys 		 * the keyusage value is specified.
87499ebb4caSwyllys 		 */
87599ebb4caSwyllys 		if (flags & KC_KEYUSAGE)
87699ebb4caSwyllys 			oplc.ku_bits = plc.ku_bits;
87799ebb4caSwyllys 	}
87899ebb4caSwyllys 
87999ebb4caSwyllys 
88099ebb4caSwyllys 	/* Update the Extended Key Usage */
88199ebb4caSwyllys 	if (eku_none_opt == B_TRUE) {
88299ebb4caSwyllys 		if (flags & KC_EKUS) {
88399ebb4caSwyllys 			(void) fprintf(stderr,
88499ebb4caSwyllys 			    gettext("Can not set eku-none=true and modify "
88599ebb4caSwyllys 			    "EKU values at the same time.\n"));
88699ebb4caSwyllys 			rv = KC_ERR_USAGE;
88799ebb4caSwyllys 			goto out;
88899ebb4caSwyllys 		}
88999ebb4caSwyllys 
89099ebb4caSwyllys 		/* Release current EKU list (if any) */
89199ebb4caSwyllys 		if (oplc.eku_set.eku_count > 0) {
89230a5e8faSwyllys 			kmf_free_eku_policy(&oplc.eku_set);
89399ebb4caSwyllys 			oplc.eku_set.eku_count = 0;
89499ebb4caSwyllys 			oplc.eku_set.ekulist = NULL;
89599ebb4caSwyllys 		}
89699ebb4caSwyllys 	} else {
89799ebb4caSwyllys 		/*
89899ebb4caSwyllys 		 * If the "eku-none" option is not set or is set to false,
89999ebb4caSwyllys 		 * then we only need to do the modification if either
90099ebb4caSwyllys 		 * "ekuname" or "ekuoids" is specified.
90199ebb4caSwyllys 		 */
90299ebb4caSwyllys 		if (flags & KC_EKUS) {
90399ebb4caSwyllys 			/* Release current EKU list (if any) */
90430a5e8faSwyllys 			kmf_free_eku_policy(&oplc.eku_set);
90599ebb4caSwyllys 			oplc.eku_set = plc.eku_set;
90699ebb4caSwyllys 		}
90799ebb4caSwyllys 	}
90899ebb4caSwyllys 
90999ebb4caSwyllys 	/* Do a sanity check on the modified policy */
91030a5e8faSwyllys 	ret = kmf_verify_policy(&oplc);
91199ebb4caSwyllys 	if (ret != KMF_OK) {
91299ebb4caSwyllys 		print_sanity_error(ret);
91399ebb4caSwyllys 		rv = KC_ERR_VERIFY_POLICY;
91499ebb4caSwyllys 		goto out;
91599ebb4caSwyllys 	}
91699ebb4caSwyllys 
91799ebb4caSwyllys 	/* The modify operation is a delete followed by an add */
91830a5e8faSwyllys 	ret = kmf_delete_policy_from_db(oplc.name, filename);
91999ebb4caSwyllys 	if (ret != KMF_OK) {
92099ebb4caSwyllys 		rv = KC_ERR_DELETE_POLICY;
92199ebb4caSwyllys 		goto out;
92299ebb4caSwyllys 	}
92399ebb4caSwyllys 
92499ebb4caSwyllys 	/*
92599ebb4caSwyllys 	 * Now add the modified policy back to the DB.
92699ebb4caSwyllys 	 */
92730a5e8faSwyllys 	ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE);
92899ebb4caSwyllys 	if (ret != KMF_OK) {
92999ebb4caSwyllys 		(void) fprintf(stderr,
93099ebb4caSwyllys 		    gettext("Error adding policy to database: 0x%04x\n"), ret);
93199ebb4caSwyllys 		rv = KC_ERR_ADD_POLICY;
93299ebb4caSwyllys 		goto out;
93399ebb4caSwyllys 	}
93499ebb4caSwyllys 
93599ebb4caSwyllys out:
93699ebb4caSwyllys 	if (filename != NULL)
93799ebb4caSwyllys 		free(filename);
93899ebb4caSwyllys 
93930a5e8faSwyllys 	kmf_free_policy_record(&oplc);
94099ebb4caSwyllys 
94199ebb4caSwyllys 	return (rv);
94299ebb4caSwyllys }
943431deaa0Shylee 
944431deaa0Shylee static int
kc_modify_plugin(int argc,char * argv[])945431deaa0Shylee kc_modify_plugin(int argc, char *argv[])
946431deaa0Shylee {
947431deaa0Shylee 	int 		rv = KC_OK;
948431deaa0Shylee 	int		opt;
949431deaa0Shylee 	extern int	optind_av;
950431deaa0Shylee 	extern char	*optarg_av;
951431deaa0Shylee 	char 		*keystore_name = NULL;
952431deaa0Shylee 	char		*option = NULL;
953431deaa0Shylee 	boolean_t	modify_plugin = B_FALSE;
954431deaa0Shylee 	boolean_t 	has_option_arg = B_FALSE;
955431deaa0Shylee 	conf_entry_t	*entry = NULL;
956431deaa0Shylee 	FILE		*pfile = NULL;
957431deaa0Shylee 	FILE		*pfile_tmp = NULL;
958431deaa0Shylee 	char		tmpfile_name[MAXPATHLEN];
959431deaa0Shylee 	char 		buffer[MAXPATHLEN];
960431deaa0Shylee 	char 		buffer2[MAXPATHLEN];
961431deaa0Shylee 
962431deaa0Shylee 	while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)"))
963431deaa0Shylee 	    != EOF) {
964431deaa0Shylee 		switch (opt) {
965431deaa0Shylee 		case 'p':
966431deaa0Shylee 			if (modify_plugin) {
967431deaa0Shylee 				(void) fprintf(stderr,
968431deaa0Shylee 				    gettext("duplicate plugin input.\n"));
969431deaa0Shylee 				rv = KC_ERR_USAGE;
970431deaa0Shylee 			} else {
971431deaa0Shylee 				modify_plugin = B_TRUE;
972431deaa0Shylee 			}
973431deaa0Shylee 			break;
974431deaa0Shylee 		case 'k':
975431deaa0Shylee 			if (keystore_name != NULL)
976431deaa0Shylee 				rv = KC_ERR_USAGE;
977431deaa0Shylee 			else {
978431deaa0Shylee 				keystore_name = get_string(optarg_av, &rv);
979431deaa0Shylee 				if (keystore_name == NULL) {
980431deaa0Shylee 					(void) fprintf(stderr, gettext(
981431deaa0Shylee 					    "Error keystore input.\n"));
982431deaa0Shylee 					rv = KC_ERR_USAGE;
983431deaa0Shylee 				}
984431deaa0Shylee 			}
985431deaa0Shylee 			break;
986431deaa0Shylee 		case 'o':
987431deaa0Shylee 			if (has_option_arg) {
988431deaa0Shylee 				(void) fprintf(stderr,
989431deaa0Shylee 				    gettext("duplicate option input.\n"));
990431deaa0Shylee 				rv = KC_ERR_USAGE;
991431deaa0Shylee 			} else {
992431deaa0Shylee 				has_option_arg = B_TRUE;
993431deaa0Shylee 				option = get_string(optarg_av, NULL);
994431deaa0Shylee 			}
995431deaa0Shylee 			break;
996431deaa0Shylee 		default:
997431deaa0Shylee 			(void) fprintf(stderr,
998431deaa0Shylee 			    gettext("Error input option.\n"));
999431deaa0Shylee 			rv = KC_ERR_USAGE;
1000431deaa0Shylee 			break;
1001431deaa0Shylee 		}
1002431deaa0Shylee 
1003431deaa0Shylee 		if (rv != KC_OK)
1004431deaa0Shylee 			goto out;
1005431deaa0Shylee 	}
1006431deaa0Shylee 
1007431deaa0Shylee 	/* No additional args allowed. */
1008431deaa0Shylee 	argc -= optind_av;
1009431deaa0Shylee 	if (argc) {
1010431deaa0Shylee 		(void) fprintf(stderr,
1011431deaa0Shylee 		    gettext("Error input option\n"));
1012431deaa0Shylee 		rv = KC_ERR_USAGE;
1013431deaa0Shylee 		goto out;
1014431deaa0Shylee 	}
1015431deaa0Shylee 
1016431deaa0Shylee 	if (keystore_name == NULL || has_option_arg == B_FALSE) {
1017431deaa0Shylee 		(void) fprintf(stderr,
1018431deaa0Shylee 		    gettext("Error input option\n"));
1019431deaa0Shylee 		rv = KC_ERR_USAGE;
1020431deaa0Shylee 		goto out;
1021431deaa0Shylee 	}
1022431deaa0Shylee 
1023431deaa0Shylee 	if (strcasecmp(keystore_name, "nss") == 0 ||
1024431deaa0Shylee 	    strcasecmp(keystore_name, "pkcs11") == 0 ||
1025431deaa0Shylee 	    strcasecmp(keystore_name, "file") == 0) {
1026431deaa0Shylee 		(void) fprintf(stderr,
1027431deaa0Shylee 		    gettext("Can not modify the built-in keystore %s\n"),
1028431deaa0Shylee 		    keystore_name);
1029431deaa0Shylee 		rv = KC_ERR_USAGE;
1030431deaa0Shylee 		goto out;
1031431deaa0Shylee 	}
1032431deaa0Shylee 
1033431deaa0Shylee 	entry = get_keystore_entry(keystore_name);
1034431deaa0Shylee 	if (entry == NULL) {
1035431deaa0Shylee 		(void) fprintf(stderr, gettext("%s does not exist.\n"),
1036431deaa0Shylee 		    keystore_name);
1037431deaa0Shylee 		rv = KC_ERR_USAGE;
1038431deaa0Shylee 		goto out;
1039431deaa0Shylee 	}
1040431deaa0Shylee 
1041431deaa0Shylee 	if ((entry->option == NULL && option == NULL) ||
1042431deaa0Shylee 	    (entry->option != NULL && option != NULL &&
1043431deaa0Shylee 	    strcmp(entry->option, option) == 0)) {
1044431deaa0Shylee 		(void) fprintf(stderr, gettext("No change - "
1045431deaa0Shylee 		    "the new option is same as the old option.\n"));
1046431deaa0Shylee 		rv = KC_OK;
1047431deaa0Shylee 		goto out;
1048431deaa0Shylee 	}
1049431deaa0Shylee 
1050431deaa0Shylee 	if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
1051431deaa0Shylee 		err = errno;
1052431deaa0Shylee 		(void) fprintf(stderr,
1053431deaa0Shylee 		    gettext("failed to update the configuration - %s\n"),
1054431deaa0Shylee 		    strerror(err));
1055431deaa0Shylee 		rv = KC_ERR_ACCESS;
1056431deaa0Shylee 		goto out;
1057431deaa0Shylee 	}
1058431deaa0Shylee 
1059431deaa0Shylee 	if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
1060431deaa0Shylee 		err = errno;
1061431deaa0Shylee 		(void) fprintf(stderr,
1062431deaa0Shylee 		    gettext("failed to lock the configuration - %s\n"),
1063431deaa0Shylee 		    strerror(err));
1064431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1065431deaa0Shylee 		goto out;
1066431deaa0Shylee 	}
1067431deaa0Shylee 
1068431deaa0Shylee 	/*
1069431deaa0Shylee 	 * Create a temporary file in the /etc/crypto directory.
1070431deaa0Shylee 	 */
1071431deaa0Shylee 	(void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
1072431deaa0Shylee 	if (mkstemp(tmpfile_name) == -1) {
1073431deaa0Shylee 		err = errno;
1074431deaa0Shylee 		(void) fprintf(stderr,
1075431deaa0Shylee 		    gettext("failed to create a temporary file - %s\n"),
1076431deaa0Shylee 		    strerror(err));
1077431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1078431deaa0Shylee 		goto out;
1079431deaa0Shylee 	}
1080431deaa0Shylee 
1081431deaa0Shylee 	if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
1082431deaa0Shylee 		err = errno;
1083431deaa0Shylee 		(void) fprintf(stderr,
1084431deaa0Shylee 		    gettext("failed to open %s - %s\n"),
1085431deaa0Shylee 		    tmpfile_name, strerror(err));
1086431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1087431deaa0Shylee 		goto out;
1088431deaa0Shylee 	}
1089431deaa0Shylee 
1090431deaa0Shylee 	/*
1091431deaa0Shylee 	 * Loop thru the config file and update the entry.
1092431deaa0Shylee 	 */
1093431deaa0Shylee 	while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
1094431deaa0Shylee 		char *name;
1095431deaa0Shylee 		int len;
1096431deaa0Shylee 
1097431deaa0Shylee 		if (buffer[0] == '#') {
1098431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1099431deaa0Shylee 				rv = KC_ERR_MODIFY_PLUGIN;
1100431deaa0Shylee 				goto out;
1101431deaa0Shylee 			} else {
1102431deaa0Shylee 				continue;
1103431deaa0Shylee 			}
1104431deaa0Shylee 		}
1105431deaa0Shylee 
1106431deaa0Shylee 		/*
1107431deaa0Shylee 		 * make a copy of the original buffer to buffer2.  Also get
1108431deaa0Shylee 		 * rid of the trailing '\n' from buffer2.
1109431deaa0Shylee 		 */
1110431deaa0Shylee 		(void) strlcpy(buffer2, buffer, MAXPATHLEN);
1111431deaa0Shylee 		len = strlen(buffer2);
1112431deaa0Shylee 		if (buffer2[len-1] == '\n') {
1113431deaa0Shylee 			len--;
1114431deaa0Shylee 		}
1115431deaa0Shylee 		buffer2[len] = '\0';
1116431deaa0Shylee 
1117431deaa0Shylee 		if ((name = strtok(buffer2, SEP_COLON)) == NULL) {
1118431deaa0Shylee 			rv = KC_ERR_UNINSTALL;
1119431deaa0Shylee 			goto out;
1120431deaa0Shylee 		}
1121431deaa0Shylee 
1122431deaa0Shylee 		if (strcmp(name, keystore_name) == 0) {
1123431deaa0Shylee 			/* found the entry */
1124431deaa0Shylee 			if (option == NULL)
1125431deaa0Shylee 				(void) snprintf(buffer, MAXPATHLEN,
1126431deaa0Shylee 				    "%s:%s%s\n", keystore_name,
1127431deaa0Shylee 				    CONF_MODULEPATH, entry->modulepath);
1128431deaa0Shylee 			else
1129431deaa0Shylee 				(void) snprintf(buffer, MAXPATHLEN,
1130431deaa0Shylee 				    "%s:%s%s;%s%s\n", keystore_name,
1131431deaa0Shylee 				    CONF_MODULEPATH, entry->modulepath,
1132431deaa0Shylee 				    CONF_OPTION, option);
1133431deaa0Shylee 
1134431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1135431deaa0Shylee 				err = errno;
1136431deaa0Shylee 				(void) fprintf(stderr, gettext(
1137431deaa0Shylee 				    "failed to write to %s: %s\n"),
1138431deaa0Shylee 				    tmpfile_name, strerror(err));
1139431deaa0Shylee 				rv = KC_ERR_MODIFY_PLUGIN;
1140431deaa0Shylee 				goto out;
1141431deaa0Shylee 			}
1142431deaa0Shylee 		} else {
1143431deaa0Shylee 
1144431deaa0Shylee 			if (fputs(buffer, pfile_tmp) == EOF) {
1145431deaa0Shylee 				rv = KC_ERR_UNINSTALL;
1146431deaa0Shylee 				goto out;
1147431deaa0Shylee 			}
1148431deaa0Shylee 		}
1149431deaa0Shylee 	}
1150431deaa0Shylee 
1151431deaa0Shylee 	if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
1152431deaa0Shylee 		err = errno;
1153431deaa0Shylee 		(void) fprintf(stderr, gettext(
1154431deaa0Shylee 		    "failed to update the configuration - %s"), strerror(err));
1155431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1156431deaa0Shylee 		goto out;
1157431deaa0Shylee 	}
1158431deaa0Shylee 
1159431deaa0Shylee 	if (chmod(_PATH_KMF_CONF,
1160431deaa0Shylee 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
1161431deaa0Shylee 		err = errno;
1162431deaa0Shylee 		(void) fprintf(stderr, gettext(
1163431deaa0Shylee 		    "failed to update the configuration - %s\n"),
1164431deaa0Shylee 		    strerror(err));
1165431deaa0Shylee 		rv = KC_ERR_MODIFY_PLUGIN;
1166431deaa0Shylee 		goto out;
1167431deaa0Shylee 	}
1168431deaa0Shylee 
1169431deaa0Shylee out:
1170431deaa0Shylee 	if (entry != NULL)
1171431deaa0Shylee 		free_entry(entry);
1172431deaa0Shylee 
1173431deaa0Shylee 	if (pfile != NULL)
1174431deaa0Shylee 		(void) fclose(pfile);
1175431deaa0Shylee 
1176431deaa0Shylee 	if (rv != KC_OK && pfile_tmp != NULL)
1177431deaa0Shylee 		(void) unlink(tmpfile_name);
1178431deaa0Shylee 
1179431deaa0Shylee 	if (pfile_tmp != NULL)
1180431deaa0Shylee 		(void) fclose(pfile_tmp);
1181431deaa0Shylee 
1182431deaa0Shylee 	return (rv);
1183431deaa0Shylee }
1184431deaa0Shylee 
1185431deaa0Shylee 
1186431deaa0Shylee int
kc_modify(int argc,char * argv[])1187431deaa0Shylee kc_modify(int argc, char *argv[])
1188431deaa0Shylee {
1189431deaa0Shylee 	if (argc > 2 &&
1190431deaa0Shylee 	    strcmp(argv[0], "modify") == 0 &&
1191431deaa0Shylee 	    strcmp(argv[1], "plugin") == 0) {
1192431deaa0Shylee 		return (kc_modify_plugin(argc, argv));
1193431deaa0Shylee 	} else {
1194431deaa0Shylee 		return (kc_modify_policy(argc, argv));
1195431deaa0Shylee 	}
1196431deaa0Shylee }
1197