summaryrefslogtreecommitdiff
path: root/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/nsswitch/files/common/tsol_getrhent.c')
-rw-r--r--usr/src/lib/nsswitch/files/common/tsol_getrhent.c87
1 files changed, 80 insertions, 7 deletions
diff --git a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
index f41f606034..180a660189 100644
--- a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
+++ b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
@@ -28,30 +28,102 @@
#include "files_common.h"
#include <string.h>
#include <libtsnet.h>
+#include <netinet/in.h>
/*
* files/tsol_getrhent.c --
* "files" backend for nsswitch "tnrhdb" database
*/
static int
-check_addr(nss_XbyY_args_t *args)
+check_addr(nss_XbyY_args_t *args, const char *line, int linelen)
{
- tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)args->returnval;
+ const char *limit, *linep, *keyp;
+ char prev;
+ int ipv6;
- if ((args->key.hostaddr.type == rhstrp->family) &&
- (strcmp(args->key.hostaddr.addr, rhstrp->address) == 0))
+ linep = line;
+ limit = line + linelen;
+ keyp = args->key.hostaddr.addr;
+ prev = '\0';
+
+ if (strstr(linep, "\\:") != NULL)
+ ipv6 = 1;
+ else
+ ipv6 = 0;
+
+ /*
+ * compare addr in
+ *
+ * 192.168.120.6:public
+ * fec0\:\:a00\:20ff\:fea0\:21f7:cipso
+ *
+ * ':' is the seperator.
+ */
+
+ while (*keyp && linep < limit && *keyp == *linep) {
+ if ((ipv6 == 0 && *linep == ':') ||
+ (ipv6 == 1 && prev != '\\' && *linep == ':'))
+ break;
+
+ prev = *linep;
+ keyp++;
+ linep++;
+ }
+ if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') ||
+ (ipv6 == 1 && prev != '\\' && *linep == ':')))
return (1);
return (0);
}
+static void
+escape_colon(const char *in, char *out) {
+ int i, j;
+ for (i = 0, j = 0; in[i] != '\0'; i++) {
+ if (in[i] == ':') {
+ out[j++] = '\\';
+ out[j++] = in[i];
+ } else
+ out[j++] = in[i];
+ }
+ out[j] = '\0';
+}
+
static nss_status_t
getbyaddr(files_backend_ptr_t be, void *a)
{
nss_XbyY_args_t *argp = a;
+ char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */
+ const char *addr = NULL;
+ nss_status_t rc;
+
+ if (argp->key.hostaddr.addr == NULL ||
+ (argp->key.hostaddr.type != AF_INET &&
+ argp->key.hostaddr.type != AF_INET6))
+ return (NSS_NOTFOUND);
+ if (strchr(argp->key.hostaddr.addr, ':') != NULL) {
+ /* IPV6 */
+ if (argp->key.hostaddr.type == AF_INET)
+ return (NSS_NOTFOUND);
+ escape_colon(argp->key.hostaddr.addr, addr6);
+ /* save the key in original format */
+ addr = argp->key.hostaddr.addr;
+ /* Replace the key with escaped format */
+ argp->key.hostaddr.addr = addr6;
+ } else {
+ /* IPV4 */
+ if (argp->key.hostaddr.type == AF_INET6)
+ return (NSS_NOTFOUND);
+ }
+
+ rc = _nss_files_XY_all(be, argp, 1,
+ argp->key.hostaddr.addr, check_addr);
+
+ /* restore argp->key.hostaddr.addr */
+ if (addr)
+ argp->key.hostaddr.addr = addr;
- return (_nss_files_XY_all(be, argp, 1,
- argp->key.hostaddr.addr, check_addr));
+ return (rc);
}
static files_backend_op_t tsol_rh_ops[] = {
@@ -62,9 +134,10 @@ static files_backend_op_t tsol_rh_ops[] = {
getbyaddr
};
-/* ARGSUSED */
nss_backend_t *
+/* LINTED E_FUNC_ARG_UNUSED */
_nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
+/* LINTED E_FUNC_ARG_UNUSED */
const char *dummy3)
{
return (_nss_files_constr(tsol_rh_ops,