diff options
author | Thorsten Kukuk <kukuk@thkukuk.de> | 2016-04-01 15:28:09 +0200 |
---|---|---|
committer | Thorsten Kukuk <kukuk@thkukuk.de> | 2016-04-01 15:28:09 +0200 |
commit | 549aef483c9f1852e1fbefabc4ebbbe72e00c243 (patch) | |
tree | 5d47083ddd386bd5e06e9e6e322e10e78d1ce20d /modules/pam_unix/pam_unix_passwd.c | |
parent | 6b12a20c527cb6ced5b8911ea0f1dcdfc6e6f30c (diff) | |
download | pam-549aef483c9f1852e1fbefabc4ebbbe72e00c243.tar.gz pam-549aef483c9f1852e1fbefabc4ebbbe72e00c243.tar.bz2 pam-549aef483c9f1852e1fbefabc4ebbbe72e00c243.zip |
Use TI-RPC functions if we compile and link against libtirpc.
The old SunRPC functions don't work with IPv6.
* configure.ac: Set and restore CPPFLAGS
* modules/pam_unix/pam_unix_passwd.c: Replace getrpcport with
rpcb_getaddr if available.
Diffstat (limited to 'modules/pam_unix/pam_unix_passwd.c')
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index e3d32096..fa293278 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -92,7 +92,7 @@ # include "yppasswd.h" -# if !HAVE_DECL_GETRPCPORT +# if !HAVE_DECL_GETRPCPORT &&!HAVE_RPCB_GETADDR extern int getrpcport(const char *host, unsigned long prognum, unsigned long versnum, unsigned int proto); # endif /* GNU libc 2.1 */ @@ -114,11 +114,48 @@ extern int getrpcport(const char *host, unsigned long prognum, #define MAX_PASSWD_TRIES 3 #ifdef HAVE_NIS +#ifdef HAVE_RPCB_GETADDR +static unsigned short +__taddr2port (const struct netconfig *nconf, const struct netbuf *nbuf) +{ + unsigned short port = 0; + struct __rpc_sockinfo si; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + if (!__rpc_nconf2sockinfo(nconf, &si)) + return 0; + + switch (si.si_af) + { + case AF_INET: + sin = nbuf->buf; + port = sin->sin_port; + break; + case AF_INET6: + sin6 = nbuf->buf; + port = sin6->sin6_port; + break; + default: + break; + } + + return htons (port); +} +#endif + static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) { char *master; char *domainname; int port, err; +#if defined(HAVE_RPCB_GETADDR) + struct netconfig *nconf; + struct netbuf svcaddr; + char addrbuf[INET6_ADDRSTRLEN]; + void *handle; + int found; +#endif + #ifdef HAVE_YP_GET_DEFAULT_DOMAIN if ((err = yp_get_default_domain(&domainname)) != 0) { @@ -146,7 +183,41 @@ static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) yperr_string(err)); return NULL; } +#ifdef HAVE_RPCB_GETADDR + svcaddr.len = 0; + svcaddr.maxlen = sizeof (addrbuf); + svcaddr.buf = addrbuf; + port = 0; + found = 0; + + handle = setnetconfig(); + while ((nconf = getnetconfig(handle)) != NULL) { + if (!strcmp(nconf->nc_proto, "udp")) { + if (rpcb_getaddr(YPPASSWDPROG, YPPASSWDPROC_UPDATE, + nconf, &svcaddr, master)) { + port = __taddr2port (nconf, &svcaddr); + endnetconfig (handle); + found=1; + break; + } + + if (rpc_createerr.cf_stat != RPC_UNKNOWNHOST) { + clnt_pcreateerror (master); + pam_syslog (pamh, LOG_ERR, + "rpcb_getaddr (%s) failed!", master); + return NULL; + } + } + } + + if (!found) { + pam_syslog (pamh, LOG_ERR, + "Cannot find suitable transport for protocol 'udp'"); + return NULL; + } +#else port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP); +#endif if (port == 0) { pam_syslog(pamh, LOG_WARNING, "yppasswdd not running on NIS master host"); |