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 2017 Joyent Inc
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
36 #include <rpc/auth_des.h>
37 #include <sys/socket.h>
38 #include <sys/signal.h>
40 #include <sys/termio.h>
41 #include <sys/debug.h>
43 #include <rpcsvc/ypclnt.h>
44 #include <rpcsvc/yp_prot.h>
46 #include <rpcsvc/ypupd.h>
51 #define RPC_INETDSOCK 0 /* socket descriptor if using inetd */
52 #define debug(msg) /* turn off debugging */
54 char YPDIR
[] = "/var/yp";
55 char UPDATEFILE
[] = "updaters";
60 static int addr2netname(char *, SVCXPRT
*);
64 extern SVCXPRT
*svctcp_create(int, uint_t
, uint_t
);
65 extern SVCXPRT
*svcudp_create();
73 int connmaxrec
= RPC_MAXDATASIZE
;
77 * Check if we are running in N2L mode. If so updated is unsuported.
78 * This could be done by calling is_yptol_mode(), from libnisdb, but it
79 * seems over complex to pull in an entire library for one check so
80 * do it in line. Just pull in the name of file to check.
82 if (stat(NTOL_MAP_FILE
, &filestat
) != -1) {
83 fprintf(stderr
, "rpc.updated not supported in NIS to LDAP "
97 if (strcmp(argv
[1], "-i") == 0) {
100 } else if (strcmp(argv
[1], "-s") == 0) {
105 fprintf(stderr
, "%s: warning -- options ignored\n", cmd
);
109 if (chdir(YPDIR
) < 0) {
110 fprintf(stderr
, "%s: can't chdir to ", cmd
);
116 * Set non-blocking mode and maximum record size for
117 * connection oriented RPC transports.
119 if (!rpc_control(RPC_SVC_CONNMAXREC_SET
, &connmaxrec
)) {
120 fprintf(stderr
, "unable to set maximum RPC record size");
123 if (issock(RPC_INETDSOCK
)) {
126 transp
= svctcp_create(RPC_INETDSOCK
, 0, 0);
127 if (transp
== NULL
) {
128 fprintf(stderr
, "%s: cannot create tcp service\n", cmd
);
131 if (!svc_register(transp
, YPU_PROG
, YPU_VERS
, ypupdate_prog
,
133 fprintf(stderr
, "%s: couldn't register service\n", cmd
);
138 (void) rpcb_unset(YPU_PROG
, YPU_VERS
, 0);
139 if (!svc_create(ypupdate_prog
, YPU_PROG
, YPU_VERS
, "tcp")) {
140 fprintf(stderr
, "%s: cannot create tcp service\n", cmd
);
145 if (!svc_create(ypupdate_prog
, YPU_PROG
, YPU_VERS
, "udp")) {
146 fprintf(stderr
, "%s: cannot create udp service\n", cmd
);
157 * Determine if a descriptor belongs to a socket or not
165 if (fstat(fd
, &st
) == -1)
168 return (S_ISSOCK(fd
));
189 tt
= open("/dev/tty", O_RDWR
, 0);
191 ioctl(tt
, TIOCNOTTY
, 0);
194 open("/dev/null", O_RDWR
, 0);
200 ypupdate_prog(rqstp
, transp
)
201 struct svc_req
*rqstp
;
204 struct ypupdate_args args
;
208 char namebuf
[MAXNETNAMELEN
+1];
209 struct authunix_parms
*aup
;
211 switch (rqstp
->rq_proc
) {
213 svc_sendreply(transp
, xdr_void
, NULL
);
228 svcerr_noproc(transp
);
232 CTASSERT(sizeof (struct authdes_cred
) <= RQCRED_SIZE
);
233 CTASSERT(sizeof (struct authunix_parms
) <= RQCRED_SIZE
);
235 switch (rqstp
->rq_cred
.oa_flavor
) {
237 netname
= ((struct authdes_cred
*)
238 rqstp
->rq_clntcred
)->adc_fullname
.name
;
242 aup
= (struct authunix_parms
*)rqstp
->rq_clntcred
;
243 if (aup
->aup_uid
== 0) {
245 * addr2netname(namebuf, svc_getcaller(transp));
247 addr2netname(namebuf
, transp
);
249 user2netname(namebuf
, aup
->aup_uid
, NULL
);
255 svcerr_weakauth(transp
);
258 bzero(&args
, sizeof (args
));
259 if (!svc_getargs(transp
, xdr_ypupdate_args
, (caddr_t
)&args
)) {
260 svcerr_decode(transp
);
263 rslt
= update(netname
,
264 args
.mapname
, op
, args
.key
.yp_buf_len
, args
.key
.yp_buf_val
,
265 args
.datum
.yp_buf_len
, args
.datum
.yp_buf_val
);
266 if (!svc_sendreply(transp
, xdr_u_int
, (const caddr_t
)&rslt
)) {
267 debug("svc_sendreply failed");
269 if (!svc_freeargs(transp
, xdr_ypupdate_args
, (caddr_t
)&args
)) {
270 debug("svc_freeargs failed");
275 * Determine if requester is allowed to update the given map,
276 * and update it if so. Returns the NIS status, which is zero
277 * if there is no access violation.
280 update(requester
, mapname
, op
, keylen
, key
, datalen
, data
)
289 char updater
[MAXMAPNAMELEN
+ 40];
295 char default_domain
[YPMAXDOMAIN
];
301 if (getdomainname(default_domain
, YPMAXDOMAIN
)) {
302 debug("Couldn't get default domain name");
303 return (YPERR_YPERR
);
306 /* check to see if we have a valid mapname */
307 strncpy(fake_key
, "junk", 4);
308 err
= yp_match(default_domain
, mapname
,
309 fake_key
, strlen(fake_key
), &outval
, &outval_len
);
313 /* do nothing, only worry about above return code */
316 /* defensive programming */
317 return (YPERR_YPERR
);
321 /* valid map - continue */
322 sprintf(updater
, "make -s -f %s %s", UPDATEFILE
, mapname
);
323 pid
= _openchild(updater
, &childargs
, &childrslt
);
325 debug("openpipes failed");
326 return (YPERR_YPERR
);
332 fprintf(childargs
, "%s\n", requester
);
333 fprintf(childargs
, "%u\n", op
);
334 fprintf(childargs
, "%u\n", keylen
);
335 fwrite(key
, keylen
, 1, childargs
);
336 fprintf(childargs
, "\n");
337 fprintf(childargs
, "%u\n", datalen
);
338 fwrite(data
, datalen
, 1, childargs
);
339 fprintf(childargs
, "\n");
345 fscanf(childrslt
, "%d", &yperrno
);
349 if (!WIFEXITED(status
)) {
350 return (YPERR_YPERR
);
356 addr2netname(namebuf
, addr
)
358 struct sockaddr_in
*addr
;
362 h
= gethostbyaddr((const char *) &addr
->sin_addr
,
363 sizeof (addr
->sin_addr
), AF_INET
);
365 host2netname(namebuf
, (const char *) inet_ntoa(addr
->sin_addr
),
368 host2netname(namebuf
, h
->h_name
, NULL
);
375 addr2netname(namebuf
, transp
)
379 struct nd_hostservlist
*hostservs
= NULL
;
380 struct netconfig
*nconf
;
383 who
= svc_getrpccaller(transp
);
384 if ((who
== NULL
) || (who
->len
== 0))
386 if ((nconf
= getnetconfigent(transp
->xp_netid
))
389 if (netdir_getbyaddr(nconf
, &hostservs
, who
) != 0) {
390 (void) freenetconfigent(nconf
);
393 if (hostservs
!= NULL
)
394 strcpy(namebuf
, hostservs
->h_hostservs
->h_host
);
396 (void) freenetconfigent(nconf
);
397 netdir_free((char *)hostservs
, ND_HOSTSERVLIST
);