[BACK]Return to yplib.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / yp

Annotation of src/lib/libc/yp/yplib.c, Revision 1.31

1.31    ! lukem       1: /*     $NetBSD: yplib.c,v 1.30 1997/07/21 14:09:32 jtc Exp $    */
1.14      cgd         2:
1.3       deraadt     3: /*
1.8       deraadt     4:  * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
1.3       deraadt     5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.8       deraadt    15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Theo de Raadt.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission.
1.3       deraadt    20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     22:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
                     25:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  */
                     33:
1.29      christos   34: #include <sys/cdefs.h>
1.17      jtc        35: #if defined(LIBC_SCCS) && !defined(lint)
1.31    ! lukem      36: __RCSID("$NetBSD: yplib.c,v 1.30 1997/07/21 14:09:32 jtc Exp $");
1.3       deraadt    37: #endif
                     38:
1.30      jtc        39: #include "namespace.h"
1.1       deraadt    40: #include <sys/param.h>
                     41: #include <sys/types.h>
                     42: #include <sys/socket.h>
                     43: #include <sys/file.h>
1.7       deraadt    44: #include <sys/uio.h>
1.28      lukem      45: #include <arpa/nameser.h>
1.1       deraadt    46: #include <errno.h>
                     47: #include <stdio.h>
1.9       jtc        48: #include <stdlib.h>
1.1       deraadt    49: #include <string.h>
1.9       jtc        50: #include <unistd.h>
1.1       deraadt    51: #include <rpc/rpc.h>
                     52: #include <rpc/xdr.h>
                     53: #include <rpcsvc/yp_prot.h>
                     54: #include <rpcsvc/ypclnt.h>
1.29      christos   55: #include "local.h"
1.1       deraadt    56:
1.13      deraadt    57: #define BINDINGDIR     "/var/yp/binding"
                     58: #define YPBINDLOCK     "/var/run/ypbind.lock"
1.1       deraadt    59:
                     60: struct dom_binding *_ypbindlist;
1.21      jtc        61: char _yp_domain[MAXHOSTNAMELEN];
1.1       deraadt    62:
1.26      thorpej    63: #define YPLIB_TIMEOUT          10
                     64: #define YPLIB_RPC_RETRIES      4
                     65:
                     66: struct timeval _yplib_timeout = { YPLIB_TIMEOUT, 0 };
                     67: struct timeval _yplib_rpc_timeout = { YPLIB_TIMEOUT / YPLIB_RPC_RETRIES,
                     68:        1000000 * (YPLIB_TIMEOUT % YPLIB_RPC_RETRIES) / YPLIB_RPC_RETRIES };
1.23      christos   69: int _yplib_nerrs = 5;
1.16      christos   70:
1.30      jtc        71: #ifdef __weak_alias
                     72: __weak_alias(yp_bind, _yp_bind);
                     73: __weak_alias(yp_unbind, _yp_unbind);
                     74: __weak_alias(yp_get_default_domain, _yp_get_default_domain);
                     75: #endif
                     76:
1.1       deraadt    77: int
                     78: _yp_dobind(dom, ypdb)
1.16      christos   79:        const char     *dom;
                     80:        struct dom_binding **ypdb;
1.1       deraadt    81: {
1.16      christos   82:        static int      pid = -1;
                     83:        char            path[MAXPATHLEN];
1.1       deraadt    84:        struct dom_binding *ysd, *ysd2;
                     85:        struct ypbind_resp ypbr;
                     86:        struct sockaddr_in clnt_sin;
1.16      christos   87:        int             clnt_sock, fd, gpid;
                     88:        CLIENT         *client;
                     89:        int             new = 0, r;
1.25      christos   90:        int             nerrs = 0;
1.1       deraadt    91:
1.28      lukem      92:        if (dom == NULL || *dom == '\0')
1.22      jtc        93:                return YPERR_BADARGS;
                     94:
1.13      deraadt    95:        /*
                     96:         * test if YP is running or not
                     97:         */
1.16      christos   98:        if ((fd = open(YPBINDLOCK, O_RDONLY)) == -1)
1.13      deraadt    99:                return YPERR_YPBIND;
1.16      christos  100:        if (!(flock(fd, LOCK_EX | LOCK_NB) == -1 && errno == EWOULDBLOCK)) {
                    101:                (void)close(fd);
1.13      deraadt   102:                return YPERR_YPBIND;
                    103:        }
1.16      christos  104:        (void)close(fd);
1.13      deraadt   105:
1.1       deraadt   106:        gpid = getpid();
1.16      christos  107:        if (!(pid == -1 || pid == gpid)) {
1.1       deraadt   108:                ysd = _ypbindlist;
1.16      christos  109:                while (ysd) {
                    110:                        if (ysd->dom_client)
1.1       deraadt   111:                                clnt_destroy(ysd->dom_client);
                    112:                        ysd2 = ysd->dom_pnext;
                    113:                        free(ysd);
                    114:                        ysd = ysd2;
                    115:                }
                    116:                _ypbindlist = NULL;
                    117:        }
                    118:        pid = gpid;
                    119:
1.16      christos  120:        if (ypdb != NULL)
1.1       deraadt   121:                *ypdb = NULL;
                    122:
1.16      christos  123:        for (ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext)
                    124:                if (strcmp(dom, ysd->dom_domain) == 0)
1.1       deraadt   125:                        break;
1.16      christos  126:        if (ysd == NULL) {
                    127:                if ((ysd = malloc(sizeof *ysd)) == NULL)
                    128:                        return YPERR_YPERR;
                    129:                (void)memset(ysd, 0, sizeof *ysd);
1.1       deraadt   130:                ysd->dom_socket = -1;
                    131:                ysd->dom_vers = 0;
                    132:                new = 1;
                    133:        }
                    134: again:
1.16      christos  135:        if (ysd->dom_vers == 0) {
                    136:                (void) snprintf(path, sizeof(path), "%s/%s.%d",
                    137:                                BINDINGDIR, dom, 2);
                    138:                if ((fd = open(path, O_RDONLY)) == -1) {
                    139:                        /*
                    140:                         * no binding file, YP is dead, or not yet fully
                    141:                         * alive.
                    142:                         */
1.11      deraadt   143:                        goto trynet;
1.1       deraadt   144:                }
1.16      christos  145:                if (flock(fd, LOCK_EX | LOCK_NB) == -1 &&
                    146:                    errno == EWOULDBLOCK) {
                    147:                        struct iovec    iov[2];
1.7       deraadt   148:                        struct ypbind_resp ybr;
1.16      christos  149:                        u_short         ypb_port;
                    150:                        struct ypbind_binding *bn;
1.7       deraadt   151:
1.16      christos  152:                        iov[0].iov_base = (caddr_t) & ypb_port;
1.7       deraadt   153:                        iov[0].iov_len = sizeof ypb_port;
1.16      christos  154:                        iov[1].iov_base = (caddr_t) & ybr;
1.7       deraadt   155:                        iov[1].iov_len = sizeof ybr;
                    156:
                    157:                        r = readv(fd, iov, 2);
1.16      christos  158:                        if (r != iov[0].iov_len + iov[1].iov_len) {
                    159:                                (void)close(fd);
1.1       deraadt   160:                                ysd->dom_vers = -1;
                    161:                                goto again;
                    162:                        }
1.16      christos  163:                        (void)memset(&ysd->dom_server_addr, 0,
                    164:                                     sizeof ysd->dom_server_addr);
                    165:                        ysd->dom_server_addr.sin_len =
                    166:                                sizeof(struct sockaddr_in);
1.7       deraadt   167:                        ysd->dom_server_addr.sin_family = AF_INET;
1.16      christos  168:                        bn = &ybr.ypbind_respbody.ypbind_bindinfo;
1.15      mycroft   169:                        ysd->dom_server_addr.sin_port =
1.16      christos  170:                                bn->ypbind_binding_port;
                    171:
1.7       deraadt   172:                        ysd->dom_server_addr.sin_addr =
1.16      christos  173:                                bn->ypbind_binding_addr;
1.7       deraadt   174:
1.1       deraadt   175:                        ysd->dom_server_port = ysd->dom_server_addr.sin_port;
1.16      christos  176:                        (void)close(fd);
1.1       deraadt   177:                        goto gotit;
                    178:                } else {
                    179:                        /* no lock on binding file, YP is dead. */
1.16      christos  180:                        (void)close(fd);
                    181:                        if (new)
1.1       deraadt   182:                                free(ysd);
                    183:                        return YPERR_YPBIND;
                    184:                }
                    185:        }
1.11      deraadt   186: trynet:
1.16      christos  187:        if (ysd->dom_vers == -1 || ysd->dom_vers == 0) {
                    188:                struct ypbind_binding *bn;
                    189:                (void)memset(&clnt_sin, 0, sizeof clnt_sin);
1.15      mycroft   190:                clnt_sin.sin_len = sizeof(struct sockaddr_in);
1.1       deraadt   191:                clnt_sin.sin_family = AF_INET;
                    192:                clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
                    193:
                    194:                clnt_sock = RPC_ANYSOCK;
1.16      christos  195:                client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS,
                    196:                                        &clnt_sock, 0, 0);
                    197:                if (client == NULL) {
1.1       deraadt   198:                        clnt_pcreateerror("clnttcp_create");
1.16      christos  199:                        if (new)
1.1       deraadt   200:                                free(ysd);
                    201:                        return YPERR_YPBIND;
                    202:                }
1.24      thorpej   203:                r = clnt_call(client, YPBINDPROC_DOMAIN,
                    204:                    xdr_ypdomain_wrap_string, &dom, xdr_ypbind_resp,
                    205:                    &ypbr, _yplib_timeout);
1.16      christos  206:                if (r != RPC_SUCCESS) {
1.25      christos  207:                        if (new == 0 && ++nerrs == _yplib_nerrs) {
                    208:                                nerrs = 0;
1.12      deraadt   209:                                fprintf(stderr,
1.16      christos  210:                    "YP server for domain %s not responding, still trying\n",
1.25      christos  211:                                    dom);
                    212:                        }
1.1       deraadt   213:                        clnt_destroy(client);
                    214:                        ysd->dom_vers = -1;
                    215:                        goto again;
                    216:                }
                    217:                clnt_destroy(client);
                    218:
1.16      christos  219:                (void)memset(&ysd->dom_server_addr, 0,
                    220:                             sizeof ysd->dom_server_addr);
1.15      mycroft   221:                ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in);
1.1       deraadt   222:                ysd->dom_server_addr.sin_family = AF_INET;
1.16      christos  223:                bn = &ypbr.ypbind_respbody.ypbind_bindinfo;
1.1       deraadt   224:                ysd->dom_server_addr.sin_port =
1.16      christos  225:                        bn->ypbind_binding_port;
1.1       deraadt   226:                ysd->dom_server_addr.sin_addr.s_addr =
1.16      christos  227:                        bn->ypbind_binding_addr.s_addr;
1.1       deraadt   228:                ysd->dom_server_port =
1.16      christos  229:                        bn->ypbind_binding_port;
1.1       deraadt   230: gotit:
                    231:                ysd->dom_vers = YPVERS;
1.27      mrg       232:                (void)strncpy(ysd->dom_domain, dom, sizeof(ysd->dom_domain)-1);
1.1       deraadt   233:        }
1.16      christos  234:        if (ysd->dom_client)
1.1       deraadt   235:                clnt_destroy(ysd->dom_client);
                    236:        ysd->dom_socket = RPC_ANYSOCK;
                    237:        ysd->dom_client = clntudp_create(&ysd->dom_server_addr,
1.26      thorpej   238:            YPPROG, YPVERS, _yplib_rpc_timeout, &ysd->dom_socket);
1.16      christos  239:        if (ysd->dom_client == NULL) {
1.1       deraadt   240:                clnt_pcreateerror("clntudp_create");
                    241:                ysd->dom_vers = -1;
                    242:                goto again;
                    243:        }
1.16      christos  244:        if (fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
1.1       deraadt   245:                perror("fcntl: F_SETFD");
                    246:
1.16      christos  247:        if (new) {
1.1       deraadt   248:                ysd->dom_pnext = _ypbindlist;
                    249:                _ypbindlist = ysd;
                    250:        }
1.16      christos  251:        if (ypdb != NULL)
1.1       deraadt   252:                *ypdb = ysd;
                    253:        return 0;
                    254: }
                    255:
1.20      jtc       256: void
1.30      jtc       257: __yp_unbind(ypb)
1.16      christos  258:        struct dom_binding *ypb;
1.1       deraadt   259: {
                    260:        clnt_destroy(ypb->dom_client);
                    261:        ypb->dom_client = NULL;
                    262:        ypb->dom_socket = -1;
                    263: }
                    264:
                    265: int
                    266: yp_bind(dom)
1.16      christos  267:        const char     *dom;
1.1       deraadt   268: {
1.28      lukem     269:        if (_yp_invalid_domain(dom))
                    270:                return YPERR_BADARGS;
                    271:
1.1       deraadt   272:        return _yp_dobind(dom, NULL);
                    273: }
                    274:
                    275: void
                    276: yp_unbind(dom)
1.16      christos  277:        const char     *dom;
1.1       deraadt   278: {
                    279:        struct dom_binding *ypb, *ypbp;
                    280:
1.28      lukem     281:        if (_yp_invalid_domain(dom))
                    282:                return;
                    283:
1.1       deraadt   284:        ypbp = NULL;
1.16      christos  285:        for (ypb = _ypbindlist; ypb; ypb = ypb->dom_pnext) {
                    286:                if (strcmp(dom, ypb->dom_domain) == 0) {
1.1       deraadt   287:                        clnt_destroy(ypb->dom_client);
1.16      christos  288:                        if (ypbp)
1.1       deraadt   289:                                ypbp->dom_pnext = ypb->dom_pnext;
                    290:                        else
                    291:                                _ypbindlist = ypb->dom_pnext;
                    292:                        free(ypb);
                    293:                        return;
                    294:                }
                    295:                ypbp = ypb;
                    296:        }
                    297:        return;
                    298: }
                    299:
                    300: int
                    301: yp_get_default_domain(domp)
1.16      christos  302:        char          **domp;
1.1       deraadt   303: {
                    304:        *domp = NULL;
1.16      christos  305:        if (_yp_domain[0] == '\0')
                    306:                if (getdomainname(_yp_domain, sizeof _yp_domain))
1.1       deraadt   307:                        return YPERR_NODOM;
                    308:        *domp = _yp_domain;
                    309:        return 0;
                    310: }
                    311:
                    312: int
                    313: _yp_check(dom)
1.16      christos  314:        char          **dom;
1.1       deraadt   315: {
1.16      christos  316:        char           *unused;
1.1       deraadt   317:
1.16      christos  318:        if (_yp_domain[0] == '\0')
                    319:                if (yp_get_default_domain(&unused))
1.1       deraadt   320:                        return 0;
                    321:
1.16      christos  322:        if (dom)
1.1       deraadt   323:                *dom = _yp_domain;
                    324:
1.16      christos  325:        if (yp_bind(_yp_domain) == 0)
1.28      lukem     326:                return 1;
                    327:        return 0;
                    328: }
                    329:
                    330: /*
1.31    ! lukem     331:  * _yp_invalid_domain: check if given domainname isn't legal.
1.28      lukem     332:  * returns non-zero if invalid
                    333:  */
                    334: int
                    335: _yp_invalid_domain(dom)
                    336:        const char *dom;
                    337: {
                    338:        if (dom == NULL || *dom == '\0')
                    339:                return 1;
                    340:
1.31    ! lukem     341:        if (strlen(dom) > YPMAXDOMAIN)
        !           342:                return 1;
1.28      lukem     343:
1.31    ! lukem     344:        if (strchr(dom, '/') != NULL)
1.1       deraadt   345:                return 1;
1.31    ! lukem     346:
1.1       deraadt   347:        return 0;
                    348: }

CVSweb <webmaster@jp.NetBSD.org>