7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / rpc.metad / metad_init.c
blob480946e30701e2b172ebfbe44a175efe2df62a73
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include "metad_local.h"
27 #include <metad.h>
29 #include <grp.h>
30 #include <pwd.h>
31 #include <synch.h>
32 #include <netdir.h>
33 #include <netdb.h>
34 #include <sdssc.h>
36 extern void nc_perror(const char *msg);
38 /*ARGSUSED*/
39 void
40 sigalarmhandler(int sig)
42 md_exit(NULL, 0);
47 * check for trusted host and user
49 static int
50 check_host(
51 struct svc_req *rqstp /* RPC stuff */
54 struct authsys_parms *sys_credp;
55 SVCXPRT *transp = rqstp->rq_xprt;
56 struct netconfig *nconfp = NULL;
57 struct nd_hostservlist *hservlistp = NULL;
58 int i;
59 int rval = -1;
60 char *inplace = NULL;
62 /* check for root */
63 /*LINTED*/
64 sys_credp = (struct authsys_parms *)rqstp->rq_clntcred;
65 assert(sys_credp != NULL);
66 if (sys_credp->aup_uid != 0)
67 goto out;
69 /* get hostnames */
70 if (transp->xp_netid == NULL) {
71 md_eprintf("transp->xp_netid == NULL\n");
72 goto out;
74 if ((nconfp = getnetconfigent(transp->xp_netid)) == NULL) {
75 #ifdef DEBUG
76 nc_perror("getnetconfigent(transp->xp_netid)");
77 #endif
78 goto out;
80 if ((__netdir_getbyaddr_nosrv(nconfp, &hservlistp, &transp->xp_rtaddr)
81 != 0) || (hservlistp == NULL)) {
82 #ifdef DEBUG
83 netdir_perror("netdir_getbyaddr(transp->xp_rtaddr)");
84 #endif
85 goto out;
88 /* check hostnames */
89 for (i = 0; (i < hservlistp->h_cnt); ++i) {
90 struct nd_hostserv *hservp = &hservlistp->h_hostservs[i];
91 char *hostname = hservp->h_host;
93 inplace = strdup(hostname);
95 /* localhost is OK */
96 if (strcmp(hostname, mynode()) == 0) {
97 rval = 0;
98 goto out;
101 /* check for remote root access */
102 if (ruserok(hostname, 1, "root", "root") == 0) {
103 rval = 0;
104 goto out;
107 sdssc_cm_nm2nid(inplace);
108 if (strcmp(inplace, hostname)) {
111 * If the names are now different it indicates
112 * that hostname was converted to a nodeid. This
113 * will only occur if hostname is part of the same
114 * cluster that the current node is in.
115 * If the machine is not running in a cluster than
116 * sdssc_cm_nm2nid is a noop which leaves inplace
117 * alone.
119 rval = 0;
120 goto out;
124 /* cleanup, return success */
125 out:
126 if (inplace)
127 free(inplace);
128 if (hservlistp != NULL)
129 netdir_free(hservlistp, ND_HOSTSERVLIST);
130 if (nconfp != NULL)
131 Free(nconfp);
132 return (rval);
136 * check for user in local group 14
138 static int
139 check_gid14(
140 uid_t uid
143 struct passwd *pwp;
144 struct group *grp;
145 char **namep;
147 /* get user info, check default GID */
148 if ((pwp = getpwuid(uid)) == NULL)
149 return (-1);
150 if (pwp->pw_gid == METAD_GID)
151 return (0);
153 /* check in group */
154 if ((grp = getgrgid(METAD_GID)) == NULL)
155 return (-1);
156 for (namep = grp->gr_mem; ((*namep != NULL) && (**namep != '\0'));
157 ++namep) {
158 if (strcmp(*namep, pwp->pw_name) == 0)
159 return (0);
161 return (-1);
165 * check AUTH_SYS
167 static int
168 check_sys(
169 struct svc_req *rqstp, /* RPC stuff */
170 int amode, /* R_OK | W_OK */
171 md_error_t *ep /* returned status */
174 static mutex_t mx = DEFAULTMUTEX;
175 struct authsys_parms *sys_credp;
177 /* for read, anything is OK */
178 if (! (amode & W_OK))
179 return (0);
181 /* single thread (not really needed if daemon stays single threaded) */
182 (void) mutex_lock(&mx);
184 /* check for remote root or METAD_GID */
185 /*LINTED*/
186 sys_credp = (struct authsys_parms *)rqstp->rq_clntcred;
187 if ((check_gid14(sys_credp->aup_uid) == 0) ||
188 (check_host(rqstp) == 0)) {
189 (void) mutex_unlock(&mx);
190 return (0);
193 /* return failure */
194 (void) mutex_unlock(&mx);
195 return (mdsyserror(ep, EACCES, "rpc.metad"));
199 * setup RPC service
201 * if can't authenticate return < 0
202 * any other error return > 0
205 svc_init(
206 struct svc_req *rqstp, /* RPC stuff */
207 int amode, /* R_OK | W_OK */
208 md_error_t *ep /* returned status */
211 SVCXPRT *transp;
213 if (sdssc_bind_library() == SDSSC_ERROR) {
214 (void) mdsyserror(ep, EACCES, "can't bind to cluster library");
215 return (1);
219 * if we have no rpc service info, we must have been
220 * called recursively from within the daemon
222 if (rqstp == NULL) {
223 mdclrerror(ep);
224 return (0); /* OK */
228 * initialize
230 transp = rqstp->rq_xprt;
231 assert(transp != NULL);
232 *ep = mdnullerror;
235 * check credentials
237 switch (rqstp->rq_cred.oa_flavor) {
239 /* UNIX flavor */
240 case AUTH_SYS:
242 if (check_sys(rqstp, amode, ep) != 0)
243 return (1); /* error */
244 break;
247 /* can't authenticate anything else */
248 default:
249 svcerr_weakauth(transp);
250 return (-1); /* weak authentication */
254 * (re)initialize
256 if (md_init_daemon("rpc.metad", ep) != 0)
257 return (1); /* error */
259 if (set_snarf(ep))
260 return (1);
262 sr_validate();
264 /* success */
265 return (0);
268 /*ARGSUSED*/
270 svc_fini(md_error_t *ep)
272 return (0);
276 check_set_lock(
277 int amode, /* R_OK | W_OK */
278 md_setkey_t *cl_sk, /* clients idea of set locked */
279 md_error_t *ep /* returned status */
282 md_setkey_t *svc_sk;
284 if (cl_sk == NULL)
285 return (0);
287 svc_sk = svc_get_setkey(cl_sk->sk_setno);
289 /* The set is not locked */
290 if (svc_sk == NULL) {
291 if ((amode & W_OK) == W_OK) {
292 (void) mddserror(ep, MDE_DS_WRITEWITHSULK,
293 cl_sk->sk_setno, mynode(), NULL, cl_sk->sk_setname);
294 return (1);
296 return (0);
299 /* The set is locked, do we have the key? */
300 if (cl_sk->sk_key.tv_sec == svc_sk->sk_key.tv_sec &&
301 cl_sk->sk_key.tv_usec == svc_sk->sk_key.tv_usec)
302 return (0);
304 (void) mddserror(ep, MDE_DS_SETLOCKED, MD_SET_BAD, mynode(),
305 svc_sk->sk_host, svc_sk->sk_setname);
307 return (1);