147593e96SBill Paul /* 247593e96SBill Paul * Copyright (c) 1995, 1996 347593e96SBill Paul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 447593e96SBill Paul * 547593e96SBill Paul * Redistribution and use in source and binary forms, with or without 647593e96SBill Paul * modification, are permitted provided that the following conditions 747593e96SBill Paul * are met: 847593e96SBill Paul * 1. Redistributions of source code must retain the above copyright 947593e96SBill Paul * notice, this list of conditions and the following disclaimer. 1047593e96SBill Paul * 2. Redistributions in binary form must reproduce the above copyright 1147593e96SBill Paul * notice, this list of conditions and the following disclaimer in the 1247593e96SBill Paul * documentation and/or other materials provided with the distribution. 1347593e96SBill Paul * 3. All advertising materials mentioning features or use of this software 1447593e96SBill Paul * must display the following acknowledgement: 1547593e96SBill Paul * This product includes software developed by Bill Paul. 1647593e96SBill Paul * 4. Neither the name of the author nor the names of any co-contributors 1747593e96SBill Paul * may be used to endorse or promote products derived from this software 1847593e96SBill Paul * without specific prior written permission. 1947593e96SBill Paul * 2047593e96SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2147593e96SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2247593e96SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2347593e96SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 2447593e96SBill Paul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2547593e96SBill Paul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2647593e96SBill Paul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2747593e96SBill Paul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2847593e96SBill Paul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2947593e96SBill Paul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3047593e96SBill Paul * SUCH DAMAGE. 3147593e96SBill Paul * 3247593e96SBill Paul * ypupdate client-side library function. 3347593e96SBill Paul * 3447593e96SBill Paul * Written by Bill Paul <wpaul@ctr.columbia.edu> 3547593e96SBill Paul * Center for Telecommunications Research 3647593e96SBill Paul * Columbia University, New York City 3747593e96SBill Paul */ 3847593e96SBill Paul 39542d87feSMatthew Dillon #include <sys/cdefs.h> 40542d87feSMatthew Dillon __FBSDID("$FreeBSD$"); 41542d87feSMatthew Dillon 4247593e96SBill Paul #include <stdlib.h> 4347593e96SBill Paul #include <rpc/rpc.h> 4447593e96SBill Paul #include <rpcsvc/yp_prot.h> 4547593e96SBill Paul #include <rpcsvc/ypclnt.h> 4647593e96SBill Paul #include <rpcsvc/ypupdate_prot.h> 4747593e96SBill Paul #include <rpc/key_prot.h> 4847593e96SBill Paul 4947593e96SBill Paul #ifndef WINDOW 5047593e96SBill Paul #define WINDOW (60*60) 5147593e96SBill Paul #endif 5247593e96SBill Paul 5347593e96SBill Paul #ifndef TIMEOUT 5447593e96SBill Paul #define TIMEOUT 300 5547593e96SBill Paul #endif 5647593e96SBill Paul 5747593e96SBill Paul int 5847593e96SBill Paul yp_update(domain, map, ypop, key, keylen, data, datalen) 5947593e96SBill Paul char *domain; 6047593e96SBill Paul char *map; 6147593e96SBill Paul unsigned int ypop; 6247593e96SBill Paul char *key; 6347593e96SBill Paul int keylen; 6447593e96SBill Paul char *data; 6547593e96SBill Paul int datalen; 6647593e96SBill Paul { 6747593e96SBill Paul char *master; 6847593e96SBill Paul int rval; 6947593e96SBill Paul unsigned int res; 7047593e96SBill Paul struct ypupdate_args upargs; 7147593e96SBill Paul struct ypdelete_args delargs; 7247593e96SBill Paul CLIENT *clnt; 7347593e96SBill Paul char netname[MAXNETNAMELEN+1]; 7447593e96SBill Paul des_block des_key; 7547593e96SBill Paul struct timeval timeout; 7647593e96SBill Paul 7747593e96SBill Paul /* Get the master server name for 'domain.' */ 7847593e96SBill Paul if ((rval = yp_master(domain, map, &master))) 7947593e96SBill Paul return(rval); 8047593e96SBill Paul 8147593e96SBill Paul /* Check that ypupdated is running there. */ 8247593e96SBill Paul if (getrpcport(master, YPU_PROG, YPU_VERS, ypop)) 8347593e96SBill Paul return(YPERR_DOMAIN); 8447593e96SBill Paul 8547593e96SBill Paul /* Get a handle. */ 8647593e96SBill Paul if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL) 8747593e96SBill Paul return(YPERR_RPC); 8847593e96SBill Paul 8947593e96SBill Paul /* 9047593e96SBill Paul * Assemble netname of server. 9147593e96SBill Paul * NOTE: It's difficult to discern from the documentation, but 9247593e96SBill Paul * when you make a Secure RPC call, the netname you pass should 9347593e96SBill Paul * be the netname of the guy on the other side, not your own 9447593e96SBill Paul * netname. This is how the client side knows what public key 9547593e96SBill Paul * to use for the initial exchange. Passing your own netname 9647593e96SBill Paul * only works if the server on the other side is running under 9747593e96SBill Paul * your UID. 9847593e96SBill Paul */ 9947593e96SBill Paul if (!host2netname(netname, master, domain)) { 10047593e96SBill Paul clnt_destroy(clnt); 10147593e96SBill Paul return(YPERR_BADARGS); 10247593e96SBill Paul } 10347593e96SBill Paul 10447593e96SBill Paul /* Make up a DES session key. */ 10547593e96SBill Paul key_gendes(&des_key); 10647593e96SBill Paul 10747593e96SBill Paul /* Set up DES authentication. */ 10847593e96SBill Paul if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL, 10947593e96SBill Paul &des_key)) == NULL) { 11047593e96SBill Paul clnt_destroy(clnt); 11147593e96SBill Paul return(YPERR_RESRC); 11247593e96SBill Paul } 11347593e96SBill Paul 11447593e96SBill Paul /* Set a timeout for clnt_call(). */ 11547593e96SBill Paul timeout.tv_usec = 0; 11647593e96SBill Paul timeout.tv_sec = TIMEOUT; 11747593e96SBill Paul 11847593e96SBill Paul /* 11947593e96SBill Paul * Make the call. Note that we use clnt_call() here rather than 12047593e96SBill Paul * the rpcgen-erated client stubs. We could use those stubs, but 12147593e96SBill Paul * then we'd have to do some gymnastics to get at the error 12247593e96SBill Paul * information to figure out what error code to send back to the 12347593e96SBill Paul * caller. With clnt_call(), we get the error status returned to 12447593e96SBill Paul * us right away, and we only have to exert a small amount of 12547593e96SBill Paul * extra effort. 12647593e96SBill Paul */ 12747593e96SBill Paul switch(ypop) { 12847593e96SBill Paul case YPOP_CHANGE: 12947593e96SBill Paul upargs.mapname = map; 13047593e96SBill Paul upargs.key.yp_buf_len = keylen; 13147593e96SBill Paul upargs.key.yp_buf_val = key; 13247593e96SBill Paul upargs.datum.yp_buf_len = datalen; 13347593e96SBill Paul upargs.datum.yp_buf_val = data; 13447593e96SBill Paul 13547593e96SBill Paul if ((rval = clnt_call(clnt, YPU_CHANGE, xdr_ypupdate_args, 13647593e96SBill Paul &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) { 13747593e96SBill Paul if (rval == RPC_AUTHERROR) 13847593e96SBill Paul res = YPERR_ACCESS; 13947593e96SBill Paul else 14047593e96SBill Paul res = YPERR_RPC; 14147593e96SBill Paul } 14247593e96SBill Paul 14347593e96SBill Paul break; 14447593e96SBill Paul case YPOP_INSERT: 14547593e96SBill Paul upargs.mapname = map; 14647593e96SBill Paul upargs.key.yp_buf_len = keylen; 14747593e96SBill Paul upargs.key.yp_buf_val = key; 14847593e96SBill Paul upargs.datum.yp_buf_len = datalen; 14947593e96SBill Paul upargs.datum.yp_buf_val = data; 15047593e96SBill Paul 15147593e96SBill Paul if ((rval = clnt_call(clnt, YPU_INSERT, xdr_ypupdate_args, 15247593e96SBill Paul &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) { 15347593e96SBill Paul if (rval == RPC_AUTHERROR) 15447593e96SBill Paul res = YPERR_ACCESS; 15547593e96SBill Paul else 15647593e96SBill Paul res = YPERR_RPC; 15747593e96SBill Paul } 15847593e96SBill Paul 15947593e96SBill Paul break; 16047593e96SBill Paul case YPOP_DELETE: 16147593e96SBill Paul delargs.mapname = map; 16247593e96SBill Paul delargs.key.yp_buf_len = keylen; 16347593e96SBill Paul delargs.key.yp_buf_val = key; 16447593e96SBill Paul 16547593e96SBill Paul if ((rval = clnt_call(clnt, YPU_DELETE, xdr_ypdelete_args, 16647593e96SBill Paul &delargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) { 16747593e96SBill Paul if (rval == RPC_AUTHERROR) 16847593e96SBill Paul res = YPERR_ACCESS; 16947593e96SBill Paul else 17047593e96SBill Paul res = YPERR_RPC; 17147593e96SBill Paul } 17247593e96SBill Paul 17347593e96SBill Paul break; 17447593e96SBill Paul case YPOP_STORE: 17547593e96SBill Paul upargs.mapname = map; 17647593e96SBill Paul upargs.key.yp_buf_len = keylen; 17747593e96SBill Paul upargs.key.yp_buf_val = key; 17847593e96SBill Paul upargs.datum.yp_buf_len = datalen; 17947593e96SBill Paul upargs.datum.yp_buf_val = data; 18047593e96SBill Paul 18147593e96SBill Paul if ((rval = clnt_call(clnt, YPU_STORE, xdr_ypupdate_args, 18247593e96SBill Paul &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) { 18347593e96SBill Paul if (rval == RPC_AUTHERROR) 18447593e96SBill Paul res = YPERR_ACCESS; 18547593e96SBill Paul else 18647593e96SBill Paul res = YPERR_RPC; 18747593e96SBill Paul } 18847593e96SBill Paul 18947593e96SBill Paul break; 19047593e96SBill Paul default: 19147593e96SBill Paul res = YPERR_BADARGS; 19247593e96SBill Paul break; 19347593e96SBill Paul } 19447593e96SBill Paul 19547593e96SBill Paul /* All done: tear down the connection. */ 19647593e96SBill Paul auth_destroy(clnt->cl_auth); 19747593e96SBill Paul clnt_destroy(clnt); 19847593e96SBill Paul free(master); 19947593e96SBill Paul 20047593e96SBill Paul return(res); 20147593e96SBill Paul } 202