diff options
Diffstat (limited to 'nis/ypclnt.c')
-rw-r--r-- | nis/ypclnt.c | 311 |
1 files changed, 190 insertions, 121 deletions
diff --git a/nis/ypclnt.c b/nis/ypclnt.c index 85292b6..ae04ee9 100644 --- a/nis/ypclnt.c +++ b/nis/ypclnt.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. @@ -45,12 +46,12 @@ struct dom_binding }; typedef struct dom_binding dom_binding; -static struct timeval RPCTIMEOUT = {25, 0}; -static struct timeval UDPTIMEOUT = {5, 0}; +static const struct timeval RPCTIMEOUT = {25, 0}; +static const struct timeval UDPTIMEOUT = {5, 0}; static int const MAXTRIES = 2; -static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0"; +static char ypdomainname[NIS_MAXNAMELEN + 1]; __libc_lock_define_initialized (static, ypbindlist_lock) -static dom_binding *__ypbindlist = NULL; +static dom_binding *ypbindlist = NULL; static void @@ -110,8 +111,8 @@ yp_bind_ypbindprog (const char *domain, dom_binding *ysd) int clnt_sock; CLIENT *client; - memset (&clnt_saddr, '\0', sizeof clnt_saddr); clnt_saddr.sin_family = AF_INET; + clnt_saddr.sin_port = 0; clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); clnt_sock = RPC_ANYSOCK; client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS, @@ -141,7 +142,7 @@ yp_bind_ypbindprog (const char *domain, dom_binding *ysd) if (ypbr.ypbind_status != YPBIND_SUCC_VAL) { - fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"), + fprintf (stderr, "YPBINDPROC_DOMAIN: %s\n", ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error)); return YPERR_DOMAIN; } @@ -224,7 +225,7 @@ yp_bind (const char *indomain) __libc_lock_lock (ypbindlist_lock); - status = __yp_bind (indomain, &__ypbindlist); + status = __yp_bind (indomain, &ypbindlist); __libc_lock_unlock (ypbindlist_lock); @@ -238,7 +239,7 @@ yp_unbind_locked (const char *indomain) dom_binding *ydbptr, *ydbptr2; ydbptr2 = NULL; - ydbptr = __ypbindlist; + ydbptr = ypbindlist; while (ydbptr != NULL) { @@ -248,7 +249,7 @@ yp_unbind_locked (const char *indomain) work = ydbptr; if (ydbptr2 == NULL) - __ypbindlist = __ypbindlist->dom_pnext; + ypbindlist = ypbindlist->dom_pnext; else ydbptr2 = ydbptr->dom_pnext; __yp_unbind (work); @@ -305,7 +306,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs, status = YPERR_YPERR; __libc_lock_lock (ypbindlist_lock); - ydb = __ypbindlist; + ydb = ypbindlist; while (ydb != NULL) { if (strcmp (domain, ydb->dom_domain) == 0) @@ -348,7 +349,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs, if (status != YPERR_SUCCESS) { ydb = calloc (1, sizeof (dom_binding)); - if (yp_bind_ypbindprog (domain, ydb) == YPERR_SUCCESS) + if (ydb != NULL && yp_bind_ypbindprog (domain, ydb) == YPERR_SUCCESS) { status = __ypclnt_call (domain, prog, xargs, req, xres, resp, &ydb, 1); @@ -364,6 +365,21 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs, return status; } +/* Like do_ypcall, but translate the status value if necessary. */ +static int +do_ypcall_tr (const char *domain, u_long prog, xdrproc_t xargs, + caddr_t req, xdrproc_t xres, caddr_t resp) +{ + int status = do_ypcall (domain, prog, xargs, req, xres, resp); + if (status == YPERR_SUCCESS) + /* We cast to ypresp_val although the pointer could also be of + type ypresp_key_val or ypresp_master or ypresp_order or + ypresp_maplist. But the stat element is in a common prefix so + this does not matter. */ + status = ypprot_err (((struct ypresp_val *) resp)->stat); + return status; +} + __libc_lock_define_initialized (static, domainname_lock) @@ -375,21 +391,21 @@ yp_get_default_domain (char **outdomain) __libc_lock_lock (domainname_lock); - if (__ypdomainname[0] == '\0') + if (ypdomainname[0] == '\0') { - if (getdomainname (__ypdomainname, NIS_MAXNAMELEN)) + if (getdomainname (ypdomainname, NIS_MAXNAMELEN)) result = YPERR_NODOM; - else if (strcmp (__ypdomainname, "(none)") == 0) + else if (strcmp (ypdomainname, "(none)") == 0) { /* If domainname is not set, some systems will return "(none)" */ - __ypdomainname[0] = '\0'; + ypdomainname[0] = '\0'; result = YPERR_NODOM; } else - *outdomain = __ypdomainname; + *outdomain = ypdomainname; } else - *outdomain = __ypdomainname; + *outdomain = ypdomainname; __libc_lock_unlock (domainname_lock); @@ -402,14 +418,14 @@ __yp_check (char **domain) { char *unused; - if (__ypdomainname[0] == '\0') + if (ypdomainname[0] == '\0') if (yp_get_default_domain (&unused)) return 0; if (domain) - *domain = __ypdomainname; + *domain = ypdomainname; - if (yp_bind (__ypdomainname) == 0) + if (yp_bind (ypdomainname) == 0) return 1; return 0; } @@ -436,25 +452,26 @@ yp_match (const char *indomain, const char *inmap, const char *inkey, *outvallen = 0; memset (&resp, '\0', sizeof (resp)); - result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key, - (caddr_t) & req, (xdrproc_t) xdr_ypresp_val, - (caddr_t) & resp); + result = do_ypcall_tr (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key, + (caddr_t) &req, (xdrproc_t) xdr_ypresp_val, + (caddr_t) &resp); if (result != YPERR_SUCCESS) return result; - if (resp.stat != YP_TRUE) - return ypprot_err (resp.stat); *outvallen = resp.val.valdat_len; *outval = malloc (*outvallen + 1); - if (__builtin_expect (*outval == NULL, 0)) - return YPERR_RESRC; - memcpy (*outval, resp.val.valdat_val, *outvallen); - (*outval)[*outvallen] = '\0'; + int status = YPERR_RESRC; + if (__builtin_expect (*outval != NULL, 1)) + { + memcpy (*outval, resp.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + status = YPERR_SUCCESS; + } xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp); - return YPERR_SUCCESS; + return status; } int @@ -477,30 +494,38 @@ yp_first (const char *indomain, const char *inmap, char **outkey, memset (&resp, '\0', sizeof (resp)); result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey, - (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val, - (caddr_t) & resp); + (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val, + (caddr_t) &resp); if (result != RPC_SUCCESS) return YPERR_RPC; if (resp.stat != YP_TRUE) return ypprot_err (resp.stat); - *outkeylen = resp.key.keydat_len; - *outkey = malloc (*outkeylen + 1); - if (__builtin_expect (*outkey == NULL, 0)) - return YPERR_RESRC; - memcpy (*outkey, resp.key.keydat_val, *outkeylen); - (*outkey)[*outkeylen] = '\0'; - *outvallen = resp.val.valdat_len; - *outval = malloc (*outvallen + 1); - if (__builtin_expect (*outval == NULL, 0)) - return YPERR_RESRC; - memcpy (*outval, resp.val.valdat_val, *outvallen); - (*outval)[*outvallen] = '\0'; + int status; + if (__builtin_expect ((*outkey = malloc (resp.key.keydat_len + 1)) != NULL + && (*outval = malloc (resp.val.valdat_len + + 1)) != NULL, 1)) + { + *outkeylen = resp.key.keydat_len; + memcpy (*outkey, resp.key.keydat_val, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + + *outvallen = resp.val.valdat_len; + memcpy (*outval, resp.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + + status = YPERR_SUCCESS; + } + else + { + free (*outkey); + status = YPERR_RESRC; + } xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp); - return YPERR_SUCCESS; + return status; } int @@ -526,31 +551,37 @@ yp_next (const char *indomain, const char *inmap, const char *inkey, *outkeylen = *outvallen = 0; memset (&resp, '\0', sizeof (resp)); - result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key, - (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val, - (caddr_t) & resp); + result = do_ypcall_tr (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key, + (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val, + (caddr_t) &resp); if (result != YPERR_SUCCESS) return result; - if (resp.stat != YP_TRUE) - return ypprot_err (resp.stat); - *outkeylen = resp.key.keydat_len; - *outkey = malloc (*outkeylen + 1); - if (__builtin_expect (*outkey == NULL, 0)) - return YPERR_RESRC; - memcpy (*outkey, resp.key.keydat_val, *outkeylen); - (*outkey)[*outkeylen] = '\0'; - *outvallen = resp.val.valdat_len; - *outval = malloc (*outvallen + 1); - if (__builtin_expect (*outval == NULL, 0)) - return YPERR_RESRC; - memcpy (*outval, resp.val.valdat_val, *outvallen); - (*outval)[*outvallen] = '\0'; + int status; + if (__builtin_expect ((*outkey = malloc (resp.key.keydat_len + 1)) != NULL + && (*outval = malloc (resp.val.valdat_len + + 1)) != NULL, 1)) + { + *outkeylen = resp.key.keydat_len; + memcpy (*outkey, resp.key.keydat_val, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + + *outvallen = resp.val.valdat_len; + memcpy (*outval, resp.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + + status = YPERR_SUCCESS; + } + else + { + free (*outkey); + status = YPERR_RESRC; + } xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp); - return YPERR_SUCCESS; + return status; } int @@ -569,13 +600,12 @@ yp_master (const char *indomain, const char *inmap, char **outname) memset (&resp, '\0', sizeof (ypresp_master)); - result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey, - (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp); + result = do_ypcall_tr (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey, + (caddr_t) &req, (xdrproc_t) xdr_ypresp_master, + (caddr_t) &resp); if (result != YPERR_SUCCESS) return result; - if (resp.stat != YP_TRUE) - return ypprot_err (resp.stat); *outname = strdup (resp.peer); xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp); @@ -592,7 +622,7 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder) enum clnt_stat result; if (indomain == NULL || indomain[0] == '\0' || - inmap == NULL || inmap == '\0') + inmap == NULL || inmap[0] == '\0') return YPERR_BADARGS; req.domain = (char *) indomain; @@ -600,18 +630,17 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder) memset (&resp, '\0', sizeof (resp)); - result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey, - (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp); + result = do_ypcall_tr (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey, + (caddr_t) &req, (xdrproc_t) xdr_ypresp_order, + (caddr_t) &resp); - if (result != YPERR_SUCCESS) + if (result == YPERR_SUCCESS) return result; - if (resp.stat != YP_TRUE) - return ypprot_err (resp.stat); *outorder = resp.ordernum; xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp); - return YPERR_SUCCESS; + return result; } struct ypresp_all_data @@ -657,10 +686,10 @@ __xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp) if we don't modify the length. So add an extra NUL character to avoid trouble with broken code. */ objp->status = YP_TRUE; - memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen); - key[keylen] = '\0'; - memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen); - val[vallen] = '\0'; + *((char *) __mempcpy (key, resp.ypresp_all_u.val.key.keydat_val, + keylen)) = '\0'; + *((char *) __mempcpy (val, resp.ypresp_all_u.val.val.valdat_val, + vallen)) = '\0'; xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); if ((*objp->foreach) (objp->status, key, keylen, val, vallen, objp->data)) @@ -671,7 +700,7 @@ __xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp) objp->status = resp.ypresp_all_u.val.stat; xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); /* Sun says we don't need to make this call, but must return - immediatly. Since Solaris makes this call, we will call + immediately. Since Solaris makes this call, we will call the callback function, too. */ (*objp->foreach) (objp->status, NULL, 0, NULL, 0, objp->data); return TRUE; @@ -693,8 +722,8 @@ yp_all (const char *indomain, const char *inmap, int clnt_sock; int saved_errno = errno; - if (indomain == NULL || indomain[0] == '\0' || - inmap == NULL || inmap == '\0') + if (indomain == NULL || indomain[0] == '\0' + || inmap == NULL || inmap[0] == '\0') return YPERR_BADARGS; try = 0; @@ -732,9 +761,9 @@ yp_all (const char *indomain, const char *inmap, (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all, (caddr_t) &data, RPCTIMEOUT); - if (result != RPC_SUCCESS) + if (__builtin_expect (result != RPC_SUCCESS, 0)) { - /* Print the error message only on the last try */ + /* Print the error message only on the last try. */ if (try == MAXTRIES - 1) clnt_perror (clnt, "yp_all: clnt_call"); res = YPERR_RPC; @@ -758,6 +787,7 @@ yp_all (const char *indomain, const char *inmap, } int + yp_maplist (const char *indomain, struct ypmaplist **outmaplist) { struct ypresp_maplist resp; @@ -768,67 +798,92 @@ yp_maplist (const char *indomain, struct ypmaplist **outmaplist) memset (&resp, '\0', sizeof (resp)); - result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname, - (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp); - - if (result != YPERR_SUCCESS) - return result; - if (resp.stat != YP_TRUE) - return ypprot_err (resp.stat); + result = do_ypcall_tr (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname, + (caddr_t) &indomain, (xdrproc_t) xdr_ypresp_maplist, + (caddr_t) &resp); - *outmaplist = resp.maps; - /* We give the list not free, this will be done by ypserv - xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */ + if (__builtin_expect (result == YPERR_SUCCESS, 1)) + { + *outmaplist = resp.maps; + /* We don't free the list, this will be done by ypserv + xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */ + } - return YPERR_SUCCESS; + return result; } const char * yperr_string (const int error) { + const char *str; switch (error) { case YPERR_SUCCESS: - return _("Success"); + str = N_("Success"); + break; case YPERR_BADARGS: - return _("Request arguments bad"); + str = N_("Request arguments bad"); + break; case YPERR_RPC: - return _("RPC failure on NIS operation"); + str = N_("RPC failure on NIS operation"); + break; case YPERR_DOMAIN: - return _("Can't bind to server which serves this domain"); + str = N_("Can't bind to server which serves this domain"); + break; case YPERR_MAP: - return _("No such map in server's domain"); + str = N_("No such map in server's domain"); + break; case YPERR_KEY: - return _("No such key in map"); + str = N_("No such key in map"); + break; case YPERR_YPERR: - return _("Internal NIS error"); + str = N_("Internal NIS error"); + break; case YPERR_RESRC: - return _("Local resource allocation failure"); + str = N_("Local resource allocation failure"); + break; case YPERR_NOMORE: - return _("No more records in map database"); + str = N_("No more records in map database"); + break; case YPERR_PMAP: - return _("Can't communicate with portmapper"); + str = N_("Can't communicate with portmapper"); + break; case YPERR_YPBIND: - return _("Can't communicate with ypbind"); + str = N_("Can't communicate with ypbind"); + break; case YPERR_YPSERV: - return _("Can't communicate with ypserv"); + str = N_("Can't communicate with ypserv"); + break; case YPERR_NODOM: - return _("Local domain name not set"); + str = N_("Local domain name not set"); + break; case YPERR_BADDB: - return _("NIS map database is bad"); + str = N_("NIS map database is bad"); + break; case YPERR_VERS: - return _("NIS client/server version mismatch - can't supply service"); + str = N_("NIS client/server version mismatch - can't supply service"); + break; case YPERR_ACCESS: - return _("Permission denied"); + str = N_("Permission denied"); + break; case YPERR_BUSY: - return _("Database is busy"); + str = N_("Database is busy"); + break; + default: + str = N_("Unknown NIS error code"); + break; } - return _("Unknown NIS error code"); + return _(str); } static const int8_t yp_2_yperr[] = { #define YP2YPERR(yp, yperr) [YP_##yp - YP_VERS] = YPERR_##yperr + YP2YPERR (TRUE, SUCCESS), + YP2YPERR (NOMORE, NOMORE), + YP2YPERR (FALSE, YPERR), + YP2YPERR (NOMAP, MAP), + YP2YPERR (NODOM, DOMAIN), YP2YPERR (NOKEY, KEY), YP2YPERR (BADOP, YPERR), YP2YPERR (BADDB, BADDB), @@ -839,7 +894,7 @@ static const int8_t yp_2_yperr[] = int ypprot_err (const int code) { - if (code < YP_VERS || code > YP_NOKEY) + if (code < YP_VERS || code > YP_NOMORE) return YPERR_YPERR; return yp_2_yperr[code - YP_VERS]; } @@ -848,19 +903,26 @@ libnsl_hidden_def (ypprot_err) const char * ypbinderr_string (const int error) { + const char *str; switch (error) { case 0: - return _("Success"); + str = N_("Success"); + break; case YPBIND_ERR_ERR: - return _("Internal ypbind error"); + str = N_("Internal ypbind error"); + break; case YPBIND_ERR_NOSERV: - return _("Domain not bound"); + str = N_("Domain not bound"); + break; case YPBIND_ERR_RESC: - return _("System resource allocation failure"); + str = N_("System resource allocation failure"); + break; default: - return _("Unknown ypbind error"); + str = N_("Unknown ypbind error"); + break; } + return _(str); } libnsl_hidden_def (ypbinderr_string) @@ -893,16 +955,22 @@ yp_update (char *domain, char *map, unsigned ypop, args.update_args.datum.yp_buf_len = datalen; args.update_args.datum.yp_buf_val = data; - if ((r = yp_master (domain, map, &master)) != 0) + if ((r = yp_master (domain, map, &master)) != YPERR_SUCCESS) return r; if (!host2netname (servername, master, domain)) { fputs (_("yp_update: cannot convert host to netname\n"), stderr); + free (master); return YPERR_YPERR; } - if ((clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp")) == NULL) + clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp"); + + /* We do not need the string anymore. */ + free (master); + + if (clnt == NULL) { clnt_pcreateerror ("yp_update: clnt_create"); return YPERR_RPC; @@ -942,6 +1010,7 @@ again: { if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES) { + auth_destroy (clnt->cl_auth); clnt->cl_auth = authunix_create_default (); goto again; } |