setadmin.c revision 9781:ccf49524d5dc
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
22/*
23 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28/* All Rights Reserved */
29
30
31#include <stdio.h>
32#include <limits.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include <string.h>
36#include <errno.h>
37#include <pkglocs.h>
38#include <locale.h>
39#include <libintl.h>
40#include <pkglib.h>
41#include <pkgerr.h>
42#include <pkgweb.h>
43#include <install.h>
44#include <libinst.h>
45#include <libadm.h>
46#include <messages.h>
47
48#define	DEFMAIL	"root"
49
50extern struct admin	adm;		/* holds info about install admin */
51extern int		warnflag;	/* != 0 non-fatal error occurred 2 */
52
53static struct {
54	char	**memloc;
55	char	*tag;
56} admlist[] = {
57	&adm.action,		"action",
58	&adm.authentication,	"authentication",
59	&adm.basedir,		"basedir",
60	&adm.conflict,		"conflict",
61	&adm.idepend,		"idepend",
62	&adm.instance,		"instance",
63	&adm.keystore,		"keystore",
64	&adm.mail,		"mail",
65	&adm.networkretries,	"networkretries",
66	&adm.networktimeout,	"networktimeout",
67	&adm.partial,		"partial",
68	&adm.proxy,		"proxy",
69	&adm.rdepend,		"rdepend",
70	&adm.RSCRIPTALT,	RSCRIPTALT_KEYWORD,
71	&adm.runlevel,		"runlevel",
72	&adm.setuid,		"setuid",
73	&adm.space,		"space",
74	/* MUST BE LAST ENTRY IN LIST */
75	(char **)NULL,		(char *)NULL
76};
77
78/*
79 * Name:	setadminSetting
80 * Description:	set one administration parameter setting
81 * Arguments:	a_paramName - pointer to string representing the name of
82 *			the administration parameter to set
83 *		a_paramValue - pointer to string representing the value
84 *			to set the specified administration parameter to
85 * Returns:	char *
86 *			- old value the parameter had before being set
87 *			== NULL - the old paramter was not set
88 */
89
90char *
91setadminSetting(char *a_paramName, char *a_paramValue)
92{
93	char	*oldValue = (char *)NULL;
94	int	i;
95
96	/* locate and update the specified admin setting */
97
98	for (i = 0; admlist[i].memloc; i++) {
99		if (strcmp(a_paramName, admlist[i].tag) == 0) {
100			oldValue = *admlist[i].memloc;
101			*admlist[i].memloc = a_paramValue;
102			break;
103		}
104	}
105
106	if (admlist[i].memloc == (char **)NULL) {
107		logerr(WRN_UNKNOWN_ADM_PARAM, a_paramName);
108	}
109
110	return (oldValue);
111}
112
113/*
114 * Name:	setadminFile
115 * Description:	read and remember settings from administration file
116 * Arguments:	file - pointer to string representing the path to the
117 *			administration file to read - if this is NULL
118 *			then the name "default" is used - if this is
119 *			the string "none" then the admin "basedir"
120 *			setting is set to "ask" so that the location
121 *			of the administration file will be interactively
122 *			asked at the appropriate time
123 * Returns:	void
124 */
125
126void
127setadminFile(char *file)
128{
129	FILE	*fp;
130	int	i;
131	char	param[MAX_PKG_PARAM_LENGTH];
132	char	*value;
133	char	path[PATH_MAX];
134	int	mail = 0;
135
136	if (file == NULL)
137		file = "default";
138	else if (strcmp(file, "none") == 0) {
139		adm.basedir = "ask";
140		return;
141	}
142
143	if (file[0] == '/')
144		(void) strcpy(path, file);
145	else {
146		(void) snprintf(path, sizeof (path), "%s/admin/%s",
147				get_PKGADM(), file);
148		if (access(path, R_OK)) {
149			(void) snprintf(path, sizeof (path), "%s/admin/%s",
150				PKGADM, file);
151		}
152	}
153
154	if ((fp = fopen(path, "r")) == NULL) {
155		progerr(ERR_OPEN_ADMIN_FILE, file, strerror(errno));
156		quit(99);
157	}
158
159	param[0] = '\0';
160	while (value = fpkgparam(fp, param)) {
161		if (strcmp(param, "mail") == 0) {
162			mail = 1;
163		}
164		if (value[0] == '\0') {
165			param[0] = '\0';
166			continue; /* same as not being set at all */
167		}
168		for (i = 0; admlist[i].memloc; i++) {
169			if (strcmp(param, admlist[i].tag) == 0) {
170				*admlist[i].memloc = value;
171				break;
172			}
173		}
174		if (admlist[i].memloc == NULL) {
175			logerr(WRN_UNKNOWN_ADM_PARAM, param);
176			free(value);
177		}
178		param[0] = '\0';
179	}
180
181	(void) fclose(fp);
182
183	if (!mail) {
184		adm.mail = DEFMAIL; 	/* if we don't assign anything to it */
185	}
186}
187
188
189/*
190 * Function:	web_ck_retries
191 * Description:	Reads admin file setting for networkretries, or uses default
192 * Parameters:	None
193 * Returns:	admin file setting for networkretries, or the default if no
194 *		admin file setting exists or if it is outside the
195 *		allowable range.
196 */
197int
198web_ck_retries(void)
199{
200	int retries = NET_RETRIES_DEFAULT;
201
202	if (ADMSET(networkretries)) {
203		/* Make sure value is within valid range */
204		if ((retries = atoi(adm.networkretries)) == 0) {
205			return (NET_RETRIES_DEFAULT);
206		} else if (retries <= NET_RETRIES_MIN ||
207			retries > NET_RETRIES_MAX) {
208			return (NET_RETRIES_DEFAULT);
209		}
210	}
211	return (retries);
212}
213
214/*
215 * Function:	web_ck_authentication
216 * Description:	Retrieves admin file setting for authentication
217 * Parameters:	None
218 * Returns:	admin file policy for authentication - AUTH_QUIT
219 *		or AUTH_NOCHECK.
220 *		non-zero failure
221 */
222int
223web_ck_authentication(void)
224{
225	if (ADM(authentication, "nocheck"))
226		return (AUTH_NOCHECK);
227
228	return (AUTH_QUIT);
229}
230
231/*
232 * Function:	web_ck_timeout
233 * Description:	Retrieves admin file policy for networktimeout's
234 * Parameters:	NONE
235 * Returns:	Admin file setting for networktimeout, or default
236 *		timeout value if admin file does not specify one,
237 *		or specifies one that is out of the allowable range.
238 */
239int
240web_ck_timeout(void)
241{
242	int timeout = NET_TIMEOUT_DEFAULT;
243
244	if (ADMSET(networktimeout)) {
245		/* Make sure value is within valid range */
246		if ((timeout = atoi(adm.networktimeout)) == 0) {
247			return (NET_TIMEOUT_DEFAULT);
248		} else if (timeout <= NET_TIMEOUT_MIN ||
249			timeout > NET_TIMEOUT_MAX) {
250			return (NET_TIMEOUT_DEFAULT);
251		}
252	}
253	return (timeout);
254}
255
256/*
257 * Function:	check_keystore_admin
258 * Description:	Retrieves security keystore setting from admin file,
259 *		or validates user-supplied keystore policy.
260 * Parameters:	keystore - Where to store resulting keystore policy
261 * Returns:	B_TRUE - admin file contained valid keystore, or
262 *		user-supplied keystore passed in "keystore" was
263 *		valid.  Resulting keystore stored in "keystore"
264 *
265 *		B_FALSE - No location supplied to store result,
266 *		or user-supplied keystore was not valid.
267 */
268boolean_t
269check_keystore_admin(char **keystore)
270{
271
272	if (!keystore) {
273		/* no location to store keystore */
274		return (B_FALSE);
275	}
276
277	if (*keystore != NULL) {
278	    if (!path_valid(*keystore)) {
279		    /* the given keystore is invalid */
280		    return (B_FALSE);
281	    }
282
283	    /* the user-supplied keystore was valid */
284	    return (B_TRUE);
285	}
286
287	/* no user-supplied, so use default */
288	if ((*keystore = set_keystore_admin()) == NULL) {
289		*keystore = PKGSEC;
290	}
291	return (B_TRUE);
292}
293
294/*
295 * Function:	get_proxy_port_admin
296 * Description:	Retrieves proxy setting from admin file
297 * Parameters:	proxy - where to store resulting proxy (host:port or URL)
298 *		port - Where to store resulting proxy port
299 * Returns:	B_TRUE - admin file had a valid proxy setting,
300 *		and it is stored in "proxy".
301 *		B_FALSE - no proxy setting in admin file, or
302 *		invalid setting in admin file.
303 */
304boolean_t
305get_proxy_port_admin(char **proxy, ushort_t *port)
306{
307	if (ADMSET(proxy) && !path_valid(adm.proxy)) {
308		/* admin file has bad keystore */
309		return (B_FALSE);
310	} else if (ADMSET(proxy)) {
311		*proxy = strdup(adm.proxy);
312		*port = strip_port(adm.proxy);
313	}
314	return (B_TRUE);
315}
316
317/*
318 * Function:	set_keystore_admin
319 * Description:	Retrieves security keystore setting from admin file,
320 * Parameters:	NONE
321 * Returns:	Keystore file policy from admin file, if set
322 *		and valid.  NULL otherwise.
323 */
324char *
325set_keystore_admin(void)
326{
327	if (ADMSET(keystore) && !path_valid(adm.keystore)) {
328		return (NULL);
329	}
330
331	if (!ADMSET(keystore)) {
332		return (NULL);
333	}
334
335	return (adm.keystore);
336}
337