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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include "mhd_local.h"
31 #include <stdio_ext.h>
35 #include <sys/resource.h>
36 #include <sys/priocntl.h>
37 #include <sys/rtpriocntl.h>
38 #include <sys/utsname.h>
40 extern void nc_perror(const char *msg
);
43 static char *myname
= "rpc.metamhd";
46 * reset and exit daemon
54 mhd_eprintf("exiting with %d\n", eval
);
72 if ((msg
= strsignal(sig
)) == NULL
) {
73 (void) sprintf(buf
, "unknown signal %d", sig
);
76 mhd_eprintf("%s\n", msg
);
78 /* let default handler do it's thing */
79 (void) sigset(sig
, SIG_DFL
);
80 if (kill(getpid(), sig
) != 0) {
81 mhd_perror("kill(getpid())");
97 rtparms_t
*rtparmsp
= (rtparms_t
*)pcparms
.pc_clparms
;
99 /* catch common signals */
100 if ((sigset(SIGHUP
, mhd_catcher
) == SIG_ERR
) ||
101 (sigset(SIGINT
, mhd_catcher
) == SIG_ERR
) ||
102 (sigset(SIGABRT
, mhd_catcher
) == SIG_ERR
) ||
103 (sigset(SIGBUS
, mhd_catcher
) == SIG_ERR
) ||
104 (sigset(SIGSEGV
, mhd_catcher
) == SIG_ERR
) ||
105 (sigset(SIGPIPE
, mhd_catcher
) == SIG_ERR
) ||
106 (sigset(SIGTERM
, mhd_catcher
) == SIG_ERR
)) {
107 return (mhd_error(mhep
, errno
, "sigset"));
110 /* ignore SIGHUP (used in mhd_cv_timedwait) */
111 if (sigset(SIGALRM
, SIG_IGN
) == SIG_ERR
) {
112 return (mhd_error(mhep
, errno
, "sigset"));
115 /* increase number of file descriptors */
116 (void) memset(&rlimit
, 0, sizeof (rlimit
));
117 if (getrlimit(RLIMIT_NOFILE
, &rlimit
) != 0)
118 return (mhd_error(mhep
, errno
, "getrlimit(RLIMIT_NOFILE)"));
119 rlimit
.rlim_cur
= rlimit
.rlim_max
= 1024;
120 if (setrlimit(RLIMIT_NOFILE
, &rlimit
) != 0)
121 return (mhd_error(mhep
, errno
, "setrlimit(RLIMIT_NOFILE)"));
122 (void) enable_extended_FILE_stdio(-1, -1);
124 /* set default RT priority */
125 (void) memset(&pcinfo
, 0, sizeof (pcinfo
));
126 (void) strncpy(pcinfo
.pc_clname
, "RT", sizeof (pcinfo
.pc_clname
));
127 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) < 0)
128 return (mhd_error(mhep
, errno
, "priocntl(PC_GETCID): \"RT\""));
129 (void) memset(&pcparms
, 0, sizeof (pcparms
));
130 pcparms
.pc_cid
= pcinfo
.pc_cid
;
131 rtparmsp
->rt_pri
= RT_NOCHANGE
;
132 rtparmsp
->rt_tqsecs
= (ulong_t
)RT_NOCHANGE
;
133 rtparmsp
->rt_tqnsecs
= RT_NOCHANGE
;
134 if (priocntl(P_PID
, getpid(), PC_SETPARMS
, (caddr_t
)&pcparms
) != 0)
135 return (mhd_error(mhep
, errno
, "priocntl(PC_SETPARMS)"));
142 * (re)initalize daemon
149 static int already
= 0;
153 if (mhd_setup(mhep
) != 0)
155 openlog(myname
, LOG_CONS
, LOG_DAEMON
);
169 static struct utsname myuname
;
173 if (uname(&myuname
) == -1) {
179 return (myuname
.nodename
);
183 * check for trusted host and user
187 struct svc_req
*rqstp
/* RPC stuff */
190 struct authsys_parms
*sys_credp
;
191 SVCXPRT
*transp
= rqstp
->rq_xprt
;
192 struct netconfig
*nconfp
= NULL
;
193 struct nd_hostservlist
*hservlistp
= NULL
;
199 sys_credp
= (struct authsys_parms
*)rqstp
->rq_clntcred
;
200 assert(sys_credp
!= NULL
);
201 if (sys_credp
->aup_uid
!= 0)
205 if (transp
->xp_netid
== NULL
) {
206 mhd_eprintf("transp->xp_netid == NULL\n");
209 if ((nconfp
= getnetconfigent(transp
->xp_netid
)) == NULL
) {
211 nc_perror("getnetconfigent(transp->xp_netid)");
215 if ((__netdir_getbyaddr_nosrv(nconfp
, &hservlistp
, &transp
->xp_rtaddr
)
216 != 0) || (hservlistp
== NULL
)) {
218 netdir_perror("netdir_getbyaddr(transp->xp_rtaddr)");
223 /* check hostnames */
224 for (i
= 0; (i
< hservlistp
->h_cnt
); ++i
) {
225 struct nd_hostserv
*hservp
= &hservlistp
->h_hostservs
[i
];
226 char *hostname
= hservp
->h_host
;
228 /* localhost is OK */
229 if (strcmp(hostname
, mynodename()) == 0) {
234 /* check for remote root access */
235 if (ruserok(hostname
, 1, "root", "root") == 0) {
241 /* cleanup, return success */
243 if (hservlistp
!= NULL
)
244 netdir_free(hservlistp
, ND_HOSTSERVLIST
);
251 * check for user in local group 14
262 /* get user info, check default GID */
263 if ((pwp
= getpwuid(uid
)) == NULL
)
265 if (pwp
->pw_gid
== METAMHD_GID
)
269 if ((grp
= getgrgid(METAMHD_GID
)) == NULL
)
271 for (namep
= grp
->gr_mem
; ((*namep
!= NULL
) && (**namep
!= '\0'));
273 if (strcmp(*namep
, pwp
->pw_name
) == 0)
284 struct svc_req
*rqstp
, /* RPC stuff */
285 int amode
, /* R_OK | W_OK */
286 mhd_error_t
*mhep
/* returned status */
289 static mutex_t mx
= DEFAULTMUTEX
;
290 struct authsys_parms
*sys_credp
;
292 /* for read, anything is OK */
293 if (! (amode
& W_OK
))
296 /* single thread (not really needed if daemon stays single threaded) */
297 (void) mutex_lock(&mx
);
299 /* check for remote root or METAMHD_GID */
301 sys_credp
= (struct authsys_parms
*)rqstp
->rq_clntcred
;
302 if ((check_gid14(sys_credp
->aup_uid
) == 0) ||
303 (check_host(rqstp
) == 0)) {
304 (void) mutex_unlock(&mx
);
309 (void) mutex_unlock(&mx
);
310 return (mhd_error(mhep
, EACCES
, myname
));
316 * if can't authenticate return < 0
317 * if any other error return > 0
321 struct svc_req
*rqstp
, /* RPC stuff */
322 int amode
, /* R_OK | W_OK */
323 mhd_error_t
*mhep
/* returned status */
326 SVCXPRT
*transp
= rqstp
->rq_xprt
;
331 (void) memset(mhep
, 0, sizeof (*mhep
));
336 switch (rqstp
->rq_cred
.oa_flavor
) {
341 if (check_sys(rqstp
, amode
, mhep
) != 0)
342 return (1); /* error */
346 /* can't authenticate anything else */
348 svcerr_weakauth(transp
);
349 return (-1); /* weak authentication */
356 if (mhd_init_daemon(mhep
) != 0)
357 return (1); /* error */