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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Portions Copyright 2005 Juergen Keil */
28 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/types.h>
38 #include <netinet/in.h>
39 #include <sys/socket.h>
45 * Because this code hacks into DBM underneath its API it can't use the N2L
46 * shim in it's normal way. It thus includes shim.h instead of shim_hooks.h
47 * and has knowledge of shim internals. While copying the DBM files it does
48 * not lock them. This reflects the behavior of the pre N2L code.
53 #if (defined(vax) || defined(i386))
59 /* per connection stuff */
67 bool_t
xdr_myfyl(XDR
*xdrs
, struct mycon
*objp
);
68 bool_t
xdr_pages(XDR
*xdrs
, struct mycon
*m
);
69 bool_t
xdr_dirs(XDR
*xdrs
, struct mycon
*m
);
71 int mygetdir(char *block
, int *no
, struct mycon
*m
);
72 int mygetpage(char *block
, int *pageno
, struct mycon
*m
);
74 datum
mydbm_topkey(DBM
*db
, datum okey
);
75 datum
dbm_do_nextkey();
76 datum
shim_dbm_do_nextkey();
78 extern void get_secure_nets(char *);
79 extern int check_secure_net_ti(struct netbuf
*, char *);
80 extern int _main(int, char **);
83 main(int argc
, char **argv
)
85 int connmaxrec
= RPC_MAXDATASIZE
;
87 /* load up the securenet file */
88 get_secure_nets(argv
[0]);
91 * Set non-blocking mode and maximum record size for
92 * connection oriented RPC transports.
94 if (!rpc_control(RPC_SVC_CONNMAXREC_SET
, &connmaxrec
)) {
95 syslog(LOG_INFO
|LOG_DAEMON
,
96 "unable to set maximum RPC record size");
99 /* Initialize file locking etc. */
100 if (!init_lock_system(TRUE
))
101 /* An detailed error will already have been logged */
104 return (_main(argc
, argv
));
108 * In yptol mode we may start a cache update thread within a child process.
109 * It is thus important that child processes do not exit, killing any such
110 * threads, before the thread has completed. They must thus call this version
111 * of the exit() function.
114 yptol_exit(int status
)
117 thr_join(0, NULL
, NULL
);
123 getdbm_1_svc(hosereq
*argp
, struct svc_req
*rqstp
)
125 static dbmfyl result
;
126 char path
[MAXNAMLEN
+ 1];
131 char *ypname
= "ypxfrd";
136 xprt
= rqstp
->rq_xprt
;
138 signal(SIGPIPE
, SIG_IGN
);
139 signal(SIGCHLD
, SIG_IGN
);
142 * Build up path name. If we are working in N2L mode also conv
143 * to the new N2L style mapname.
145 * Do not allow any path as a domain name or map name.
147 if ((strchr(argp
->domain
, '/') != NULL
) ||
148 (strchr(argp
->map
, '/') != NULL
) ||
149 (!ypmkfilename(argp
->domain
, argp
->map
, (char *)&path
))) {
151 if (!svc_sendreply(rqstp
->rq_xprt
, xdr_answer
,
153 svcerr_systemerr(rqstp
->rq_xprt
);
163 if (!svc_sendreply(rqstp
->rq_xprt
, xdr_answer
,
165 svcerr_systemerr(rqstp
->rq_xprt
);
172 m
.map
= (map_ctrl
*)shim_dbm_open(path
, 0, 0);
176 if (!svc_sendreply(rqstp
->rq_xprt
, xdr_answer
,
178 svcerr_systemerr(rqstp
->rq_xprt
);
184 /* Do the security thing */
185 if ((nbuf
= svc_getrpccaller(xprt
)) == 0) {
187 if (!svc_sendreply(xprt
, xdr_answer
, (caddr_t
)&res
)) {
188 svcerr_systemerr(xprt
);
190 shim_dbm_close((DBM
*)m
.map
);
194 if (!check_secure_net_ti(nbuf
, ypname
)) {
196 if (!svc_sendreply(xprt
, xdr_answer
, (caddr_t
)&res
)) {
197 svcerr_systemerr(xprt
);
199 shim_dbm_close((DBM
*)m
.map
);
204 af
= ((struct sockaddr_storage
*)nbuf
->buf
)->ss_family
;
205 port
= (af
== AF_INET6
) ?
206 ((struct sockaddr_in6
*)nbuf
->buf
)->sin6_port
:
207 ((struct sockaddr_in
*)nbuf
->buf
)->sin_port
;
209 if ((af
== AF_INET
|| af
== AF_INET6
) &&
210 (ntohs(port
) > IPPORT_RESERVED
)) {
213 key
.dptr
= yp_secure
;
214 key
.dsize
= yp_secure_sz
;
215 val
= shim_dbm_fetch((DBM
*)m
.map
, key
);
216 if (val
.dptr
!= NULL
) {
218 if (!svc_sendreply(xprt
, xdr_answer
, (caddr_t
)&res
)) {
219 svcerr_systemerr(xprt
);
221 shim_dbm_close((DBM
*)m
.map
);
227 /* OK, we're through */
228 m
.key
= shim_dbm_firstkey((DBM
*)m
.map
);
233 if (!svc_sendreply(rqstp
->rq_xprt
, xdr_myfyl
, (caddr_t
)&m
)) {
234 svcerr_systemerr(rqstp
->rq_xprt
);
236 shim_dbm_close((DBM
*)m
.map
);
243 xdr_myfyl(XDR
*xdrs
, struct mycon
*objp
)
247 if (!xdr_answer(xdrs
, (answer
*) &ans
))
249 if (!xdr_pages(xdrs
, objp
))
251 if (!xdr_dirs(xdrs
, objp
))
258 xdr_pages(XDR
*xdrs
, struct mycon
*m
)
260 static struct pag res
;
261 bool_t
false = FALSE
;
268 res
.status
= mygetpage(res
.pag_u
.ok
.blkdat
, &(res
.pag_u
.ok
.blkno
), m
);
271 if (res
.status
== OK
) {
272 s
= (short *)res
.pag_u
.ok
.blkdat
;
274 for (i
= 0; i
<= cnt
; i
++)
279 if (!xdr_pag(xdrs
, &res
))
282 while (res
.status
== OK
) {
283 if (!xdr_bool(xdrs
, &true))
285 res
.status
= mygetpage(res
.pag_u
.ok
.blkdat
,
286 &(res
.pag_u
.ok
.blkno
), m
);
289 if (res
.status
== OK
) {
290 s
= (short *)res
.pag_u
.ok
.blkdat
;
292 for (i
= 0; i
<= cnt
; i
++)
297 if (!xdr_pag(xdrs
, &res
))
301 return (xdr_bool(xdrs
, &false));
305 mygetdir(char *block
, int *no
, struct mycon
*m
)
310 if (m
->firstd
== 0) {
311 lseek(m
->map
->entries
->dbm_dirf
, 0, 0);
316 len
= read(m
->map
->entries
->dbm_dirf
, block
, DBLKSIZ
);
317 *no
= (m
->firstd
) - 1;
321 * printf("dir block %d\n", (m->firstd) - 1);
325 perror("read directory");
326 status
= GETDBM_ERROR
;
327 } else if (len
== 0) {
330 * printf("dir EOF\n");
337 xdr_dirs(XDR
*xdrs
, struct mycon
*m
)
339 static struct dir res
;
340 bool_t
false = FALSE
;
343 res
.status
= mygetdir(res
.dir_u
.ok
.blkdat
, &(res
.dir_u
.ok
.blkno
), m
);
345 if (!xdr_dir(xdrs
, &res
))
348 while (res
.status
== OK
) {
349 if (!xdr_bool(xdrs
, &true))
351 res
.status
= mygetdir(res
.dir_u
.ok
.blkdat
,
352 &(res
.dir_u
.ok
.blkno
), m
);
353 if (!xdr_dir(xdrs
, &res
))
357 return (xdr_bool(xdrs
, &false));
361 mygetpage(char *block
, int *pageno
, struct mycon
*m
)
365 m
->key
= shim_dbm_do_nextkey((DBM
*)m
->map
, m
->key
)) {
367 if (m
->map
->entries
->dbm_pagbno
!= m
->lblk
) {
369 * printf("block=%d lblk=%d\n",
370 * m->map->entries->dbm_pagbno,
373 m
->lblk
= m
->map
->entries
->dbm_pagbno
;
375 memmove(block
, m
->map
->entries
->dbm_pagbuf
, PBLKSIZ
);
376 /* advance key on first try */
377 m
->key
= mydbm_topkey(m
->map
->entries
, m
->key
);
378 m
->key
= shim_dbm_do_nextkey((DBM
*)m
->map
, m
->key
);
389 mydbm_topkey(DBM
*db
, datum okey
)
403 register char *p1
, *p2
;
405 buf
= db
->dbm_pagbuf
;
407 /* find the maximum key in cmpdatum order */
409 if ((unsigned)0 >= sp
[0]) {
412 ans
.dptr
= buf
+ sp
[1];
413 ans
.dsize
= PBLKSIZ
- sp
[1];
415 for (n
= 2; ; n
+= 2) {
416 if ((unsigned)n
>= sp
[0]) {
417 if (ans
.dptr
== NULL
) {
426 tmp
.dptr
= buf
+ sp
[n
+ 1];
427 tmp
.dsize
= t
- sp
[n
+ 1];
431 if (m
!= ans
.dsize
) {
432 if ((m
- ans
.dsize
) < 0)
439 if (*p1
++ != *p2
++) {
440 if ((*--p1
- *--p2
) < 0)