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