7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / rpc.metamedd / med_init.c
blobbc76420d8679c5bb8280be452584cf9ca338af64
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "med_local.h"
30 #include <sdssc.h>
32 #include <grp.h>
33 #include <pwd.h>
34 #include <signal.h>
35 #include <syslog.h>
36 #include <netdir.h>
37 #include <netdb.h>
38 #include <sys/resource.h>
39 #include <sys/priocntl.h>
40 #include <sys/rtpriocntl.h>
41 #include <sys/utsname.h>
43 extern void nc_perror(const char *msg);
45 /* daemon name */
46 static char *medname = MED_SERVNAME;
49 * reset and exit daemon
51 void
52 med_exit(
53 int eval
56 med_err_t status = med_null_err;
58 if (med_db_finit(&status))
59 medde_perror(&status, "med_db_finit");
61 /* log exit */
62 med_eprintf("exiting with %d\n", eval);
64 /* exit with value */
65 exit(eval);
69 * signal catchers
71 static void
72 med_catcher(
73 int sig
76 char buf[128];
77 char *msg;
79 /* log signal */
80 if ((msg = strsignal(sig)) == NULL) {
81 (void) sprintf(buf, "unknown signal %d", sig);
82 msg = buf;
84 med_eprintf("%s\n", msg);
86 /* let default handler do it's thing */
87 (void) sigset(sig, SIG_DFL);
88 if (kill(getpid(), sig) != 0) {
89 med_perror("kill(getpid())");
90 med_exit(-sig);
95 * initialize daemon
97 static int
98 med_setup(
99 med_err_t *medep
102 /* catch common signals */
103 if ((sigset(SIGHUP, med_catcher) == SIG_ERR) ||
104 (sigset(SIGINT, med_catcher) == SIG_ERR) ||
105 (sigset(SIGABRT, med_catcher) == SIG_ERR) ||
106 (sigset(SIGBUS, med_catcher) == SIG_ERR) ||
107 (sigset(SIGSEGV, med_catcher) == SIG_ERR) ||
108 (sigset(SIGPIPE, med_catcher) == SIG_ERR) ||
109 (sigset(SIGTERM, med_catcher) == SIG_ERR)) {
110 return (med_error(medep, errno, "sigset"));
113 /* ignore SIGALRM (used in med_cv_timedwait) */
114 if (sigset(SIGALRM, SIG_IGN) == SIG_ERR) {
115 return (med_error(medep, errno, "sigset"));
118 /* return success */
119 return (0);
123 * (re)initalize daemon
125 static int
126 med_init_daemon(
127 med_err_t *medep
130 static int already = 0;
132 /* setup */
133 if (! already) {
134 if (med_setup(medep) != 0)
135 return (-1);
136 openlog(medname, LOG_CONS, LOG_DAEMON);
137 already = 1;
140 /* return success */
141 return (0);
145 * get my nodename
147 char *
148 mynode(void)
150 static struct utsname myuname;
151 static int done = 0;
153 if (! done) {
154 if (uname(&myuname) == -1) {
155 med_perror("uname");
156 assert(0);
158 done = 1;
160 return (myuname.nodename);
164 * check for trusted host and user
166 static int
167 check_host(
168 struct svc_req *rqstp /* RPC stuff */
171 struct authsys_parms *sys_credp;
172 SVCXPRT *transp = rqstp->rq_xprt;
173 struct netconfig *nconfp = NULL;
174 struct nd_hostservlist *hservlistp = NULL;
175 int i;
176 int rval = -1;
177 char *inplace = NULL;
179 /* check for root */
180 /*LINTED*/
181 sys_credp = (struct authsys_parms *)rqstp->rq_clntcred;
182 assert(sys_credp != NULL);
183 if (sys_credp->aup_uid != 0)
184 goto out;
186 /* get hostnames */
187 if (transp->xp_netid == NULL) {
188 med_eprintf("transp->xp_netid == NULL\n");
189 goto out;
191 if ((nconfp = getnetconfigent(transp->xp_netid)) == NULL) {
192 #ifdef DEBUG
193 nc_perror("getnetconfigent(transp->xp_netid)");
194 #endif
195 goto out;
197 if ((__netdir_getbyaddr_nosrv(nconfp, &hservlistp, &transp->xp_rtaddr)
198 != 0) || (hservlistp == NULL)) {
199 #ifdef DEBUG
200 netdir_perror("netdir_getbyaddr(transp->xp_rtaddr)");
201 #endif
202 goto out;
205 /* check hostnames */
206 for (i = 0; (i < hservlistp->h_cnt); ++i) {
207 struct nd_hostserv *hservp = &hservlistp->h_hostservs[i];
208 char *hostname = hservp->h_host;
210 inplace = strdup(hostname);
211 sdssc_cm_nm2nid(inplace);
212 if (strcmp(inplace, hostname)) {
215 * If the names are now different it indicates
216 * that hostname was converted to a nodeid. This
217 * will only occur if hostname is part of the same
218 * cluster that the current node is in.
219 * If the machine is not running in a cluster than
220 * sdssc_cm_nm2nid is a noop which leaves inplace
221 * alone.
223 rval = 0;
224 goto out;
227 /* localhost is OK */
228 if (strcmp(hostname, mynode()) == 0) {
229 rval = 0;
230 goto out;
233 if (strcmp(hostname, "localhost") == 0) {
234 rval = 0;
235 goto out;
238 /* check for remote root access */
239 if (ruserok(hostname, 1, "root", "root") == 0) {
240 rval = 0;
241 goto out;
245 /* cleanup, return success */
246 out:
247 if (inplace)
248 free(inplace);
249 if (hservlistp != NULL)
250 netdir_free(hservlistp, ND_HOSTSERVLIST);
251 if (nconfp != NULL)
252 Free(nconfp);
253 return (rval);
257 * check for user in local group 14
259 static int
260 check_gid14(
261 uid_t uid
264 struct passwd *pwp;
265 struct group *grp;
266 char **namep;
268 /* get user info, check default GID */
269 if ((pwp = getpwuid(uid)) == NULL)
270 return (-1);
271 if (pwp->pw_gid == MED_GID)
272 return (0);
274 /* check in group */
275 if ((grp = getgrgid(MED_GID)) == NULL)
276 return (-1);
277 for (namep = grp->gr_mem; ((*namep != NULL) && (**namep != '\0'));
278 ++namep) {
279 if (strcmp(*namep, pwp->pw_name) == 0)
280 return (0);
282 return (-1);
286 * check AUTH_SYS
288 static int
289 check_sys(
290 struct svc_req *rqstp, /* RPC stuff */
291 int amode, /* R_OK | W_OK */
292 med_err_t *medep /* returned status */
295 #ifdef _REENTRANT
296 static mutex_t mx = DEFAULTMUTEX;
297 #endif /* _REENTRANT */
298 struct authsys_parms *sys_credp;
300 /* for read, anything is OK */
301 if (! (amode & W_OK))
302 return (0);
304 #ifdef _REENTRANT
305 /* single thread (not really needed if daemon stays single threaded) */
306 mutex_lock(&mx);
307 #endif /* _REENTRANT */
309 /* check for remote root or METAMED_GID */
310 /*LINTED*/
311 sys_credp = (struct authsys_parms *)rqstp->rq_clntcred;
312 if ((check_gid14(sys_credp->aup_uid) == 0) ||
313 (check_host(rqstp) == 0)) {
314 #ifdef _REENTRANT
315 mutex_unlock(&mx);
316 #endif /* _REENTRANT */
317 return (0);
320 /* return failure */
321 #ifdef _REENTRANT
322 mutex_unlock(&mx);
323 #endif /* _REENTRANT */
324 return (med_error(medep, EACCES, medname));
328 * setup RPC service
330 * if can't authenticate return < 0
331 * if any other error return > 0
334 med_init(
335 struct svc_req *rqstp, /* RPC stuff */
336 int amode, /* R_OK | W_OK */
337 med_err_t *medep /* returned status */
340 SVCXPRT *transp = rqstp->rq_xprt;
343 * initialize
345 (void) memset(medep, 0, sizeof (*medep));
347 if (sdssc_bind_library() == SDSSC_ERROR) {
348 (void) med_error(medep, EACCES,
349 "can't bind to cluster library");
350 return (1);
354 * check credentials
356 switch (rqstp->rq_cred.oa_flavor) {
358 /* UNIX flavor */
359 case AUTH_SYS:
361 if (check_sys(rqstp, amode, medep) != 0)
362 return (1); /* error */
363 break;
366 /* can't authenticate anything else */
367 default:
368 svcerr_weakauth(transp);
369 return (-1); /* weak authentication */
374 * (re)initialize
376 if (med_init_daemon(medep) != 0)
377 return (1); /* error */
379 /* return success */
380 return (0);