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
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]
23 * Copyright 2017 Joyent Inc
24 * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * Portions of this source code were derived from Berkeley 4.3 BSD
33 * under license from the Regents of the University of California.
41 #include <sys/types.h>
43 #include <sys/signal.h>
46 #include <rpc/nettype.h>
47 #include <rpcsvc/ypupd.h>
48 #include <rpcsvc/ypclnt.h>
49 #include <sys/debug.h>
56 #define openlog(a, b, c)
61 #define debug(msg) fprintf(stderr, "%s\n", msg);
63 #define debug(msg) /* turn off debugging */
66 static char YPDIR
[] = "/var/yp";
67 static char UPDATEFILE
[] = "/var/yp/updaters";
68 #define _RPCSVC_CLOSEDOWN 120
70 static int addr2netname();
71 static void closedown();
72 static void ypupdate_prog();
76 static int _rpcpmstart
; /* Started by a port monitor ? */
77 static int _rpcsvcdirty
; /* Still serving ? */
79 extern unsigned int alarm();
84 extern struct netconfig
*getnetconfigent();
88 extern void *signal();
90 extern int t_getinfo();
91 extern int user2netname();
92 extern int _openchild();
100 char mname
[FMNAMESZ
+ 1];
102 if (geteuid() != 0) {
103 (void) fprintf(stderr
, "must be root to run %s\n", argv
[0]);
115 if (strcmp(argv
[1], "-i") == 0) {
120 fprintf(stderr
, "%s: warning -- options ignored\n", cmd
);
124 if (chdir(YPDIR
) < 0) {
125 fprintf(stderr
, "%s: can't chdir to ", cmd
);
130 if (!ioctl(0, I_LOOK
, mname
) &&
131 (strcmp(mname
, "sockmod") == 0 ||
132 strcmp(mname
, "timod") == 0)) {
134 * Started from port monitor: use 0 as fd
137 struct netconfig
*nconf
= NULL
;
140 extern char *getenv();
143 if ((netid
= getenv("NLSPROVIDER")) == NULL
) {
144 msgout("cannot get transport name");
146 if ((nconf
= getnetconfigent(netid
)) == NULL
) {
147 msgout("cannot get transport info");
149 if (strcmp(mname
, "sockmod") == 0) {
150 if (ioctl(0, I_POP
, 0) || ioctl(0, I_PUSH
, "timod")) {
151 msgout("could not get the right module");
155 pmclose
= (t_getstate(0) != T_DATAXFER
);
156 if ((transp
= svc_tli_create(0, nconf
, NULL
, 0, 0)) == NULL
) {
157 msgout("cannot create update server handle");
160 if (!svc_reg(transp
, YPU_PROG
, YPU_VERS
, ypupdate_prog
, 0)) {
161 msgout("unable to register (YPBINDPROG, YPBINDVERS).");
165 freenetconfigent(nconf
);
168 (void) signal(SIGALRM
, closedown
);
169 (void) alarm(_RPCSVC_CLOSEDOWN
);
176 * Started from shell; background thyself and run
181 perror("cannot fork");
188 openlog("ypupdated", LOG_PID
, LOG_DAEMON
);
190 if (!svc_create(ypupdate_prog
, YPU_PROG
, YPU_VERS
, "netpath")) {
191 msgout("unable to create (YPU_PROG, YPU_VERS) for netpath.");
196 msgout("svc_run returned");
202 ypupdate_prog(rqstp
, transp
)
203 struct svc_req
*rqstp
;
206 struct ypupdate_args args
;
210 char namebuf
[MAXNETNAMELEN
+1];
211 struct authunix_parms
*aup
;
213 switch (rqstp
->rq_proc
) {
215 svc_sendreply(transp
, xdr_void
, NULL
);
230 svcerr_noproc(transp
);
234 fprintf(stderr
, "ypupdated: request received\n");
236 switch (rqstp
->rq_cred
.oa_flavor
) {
238 CTASSERT(sizeof (struct authdes_cred
) <= RQCRED_SIZE
);
239 netname
= ((struct authdes_cred
*)
240 rqstp
->rq_clntcred
)->adc_fullname
.name
;
244 CTASSERT(sizeof (struct authunix_parms
) <= RQCRED_SIZE
);
245 aup
= (struct authunix_parms
*)rqstp
->rq_clntcred
;
246 if (aup
->aup_uid
== 0) {
247 if (addr2netname(namebuf
, transp
) != 0) {
249 "addr2netname failing for %d\n",
251 svcerr_systemerr(transp
);
255 if (user2netname(namebuf
, aup
->aup_uid
, NULL
)
258 "user2netname failing for %d\n",
260 svcerr_systemerr(transp
);
268 svcerr_weakauth(transp
);
271 memset(&args
, 0, sizeof (args
));
272 if (!svc_getargs(transp
, xdr_ypupdate_args
, (char *)&args
)) {
273 svcerr_decode(transp
);
277 fprintf(stderr
, "netname = %s\n, map=%s\n key=%s\n",
278 netname
, args
.mapname
, args
.key
.yp_buf_val
);
280 rslt
= update(netname
, args
.mapname
, op
,
281 args
.key
.yp_buf_len
, args
.key
.yp_buf_val
,
282 args
.datum
.yp_buf_len
, args
.datum
.yp_buf_val
);
283 if (!svc_sendreply(transp
, xdr_u_int
, (char *)&rslt
)) {
284 debug("svc_sendreply failed");
286 if (!svc_freeargs(transp
, xdr_ypupdate_args
, (char *)&args
)) {
287 debug("svc_freeargs failed");
292 * Determine if requester is allowed to update the given map,
293 * and update it if so. Returns the yp status, which is zero
294 * if there is no access violation.
297 update(requester
, mapname
, op
, keylen
, key
, datalen
, data
)
306 char updater
[MAXMAPNAMELEN
+ 40];
313 sprintf(updater
, "/usr/ccs/bin/make -s -f %s %s", UPDATEFILE
, mapname
);
315 fprintf(stderr
, "updater: %s\n", updater
);
316 fprintf(stderr
, "requestor = %s, op = %d, key = %s\n",
318 fprintf(stderr
, "data = %s\n", data
);
320 pid
= _openchild(updater
, &childargs
, &childrslt
);
322 debug("openpipes failed");
323 return (YPERR_YPERR
);
329 fprintf(childargs
, "%s\n", requester
);
330 fprintf(childargs
, "%u\n", op
);
331 fprintf(childargs
, "%u\n", keylen
);
332 fwrite(key
, keylen
, 1, childargs
);
333 fprintf(childargs
, "\n");
334 fprintf(childargs
, "%u\n", datalen
);
335 fwrite(data
, datalen
, 1, childargs
);
336 fprintf(childargs
, "\n");
342 fscanf(childrslt
, "%d", &yperrno
);
346 if (!WIFEXITED(status
)) {
347 return (YPERR_YPERR
);
357 syslog(LOG_ERR
, msg
);
359 (void) fprintf(stderr
, "%s\n", msg
);
365 if (_rpcsvcdirty
== 0) {
369 if (t_getinfo(0, tinfo
) || (tinfo
.servtype
== T_CLTS
))
372 for (i
= 0, openfd
= 0; i
< svc_max_pollfd
&& openfd
< 2; i
++)
373 if (svc_pollfd
[i
].fd
>= 0)
379 (void) alarm(_RPCSVC_CLOSEDOWN
);
383 addr2netname(namebuf
, transp
)
387 struct nd_hostservlist
*hostservs
= NULL
;
388 struct netconfig
*nconf
;
391 who
= svc_getrpccaller(transp
);
392 if ((who
== NULL
) || (who
->len
== 0))
394 if ((nconf
= getnetconfigent(transp
->xp_netid
))
395 == (struct netconfig
*)NULL
)
397 if (netdir_getbyaddr(nconf
, &hostservs
, who
) != 0) {
398 (void) freenetconfigent(nconf
);
401 if (hostservs
== NULL
) {
402 msgout("ypupdated: netdir_getbyaddr failed\n");
404 strcpy(namebuf
, hostservs
->h_hostservs
->h_host
);
406 (void) freenetconfigent(nconf
);
407 netdir_free((char *)hostservs
, ND_HOSTSERVLIST
);