1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * nis/getnetent.c -- "nis" backend for nsswitch "networks" database 28 */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include "nis_common.h" 33 #include <synch.h> 34 #include <netdb.h> 35 #include <sys/socket.h> 36 #include <netinet/in.h> 37 #include <arpa/inet.h> 38 #include <string.h> 39 40 static int nettoa(int anet, char *buf, int buflen, char **pnull); 41 42 static nss_status_t 43 getbyname(be, a) 44 nis_backend_ptr_t be; 45 void *a; 46 { 47 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 48 49 return (_nss_nis_lookup(be, argp, 1, "networks.byname", 50 argp->key.name, 0)); 51 } 52 53 static nss_status_t 54 getbyaddr(be, a) 55 nis_backend_ptr_t be; 56 void *a; 57 { 58 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 59 char addrstr[16]; 60 char *pnull; 61 nss_status_t rc; 62 63 if (nettoa((int)argp->key.netaddr.net, addrstr, 16, &pnull) != 0) 64 return (NSS_UNAVAIL); /* it's really ENOMEM */ 65 rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", addrstr, 0); 66 67 /* 68 * if not found, try again with the untruncated address string 69 * that has the trailing zero(s) 70 */ 71 if (rc == NSS_NOTFOUND && pnull != NULL) { 72 *pnull = '.'; 73 rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", 74 addrstr, 0); 75 } 76 return (rc); 77 } 78 79 static nis_backend_op_t net_ops[] = { 80 _nss_nis_destr, 81 _nss_nis_endent, 82 _nss_nis_setent, 83 _nss_nis_getent_netdb, 84 getbyname, 85 getbyaddr 86 }; 87 88 /*ARGSUSED*/ 89 nss_backend_t * 90 _nss_nis_networks_constr(dummy1, dummy2, dummy3) 91 const char *dummy1, *dummy2, *dummy3; 92 { 93 return (_nss_nis_constr(net_ops, 94 sizeof (net_ops) / sizeof (net_ops[0]), 95 "networks.byaddr")); 96 } 97 98 /* 99 * Takes an unsigned integer in host order, and returns a printable 100 * string for it as a network number. To allow for the possibility of 101 * naming subnets, only trailing dot-zeros are truncated. The location 102 * where the string is truncated (or set to '\0') is returned in *pnull. 103 */ 104 static int 105 nettoa(int anet, char *buf, int buflen, char **pnull) 106 { 107 char *p; 108 struct in_addr in; 109 int addr; 110 111 *pnull = NULL; 112 113 if (buf == 0) 114 return (1); 115 in = inet_makeaddr(anet, INADDR_ANY); 116 addr = in.s_addr; 117 (void) strncpy(buf, inet_ntoa(in), buflen); 118 if ((IN_CLASSA_HOST & htonl(addr)) == 0) { 119 p = strchr(buf, '.'); 120 if (p == NULL) 121 return (1); 122 *p = 0; 123 *pnull = p; 124 } else if ((IN_CLASSB_HOST & htonl(addr)) == 0) { 125 p = strchr(buf, '.'); 126 if (p == NULL) 127 return (1); 128 p = strchr(p+1, '.'); 129 if (p == NULL) 130 return (1); 131 *p = 0; 132 *pnull = p; 133 } else if ((IN_CLASSC_HOST & htonl(addr)) == 0) { 134 p = strrchr(buf, '.'); 135 if (p == NULL) 136 return (1); 137 *p = 0; 138 *pnull = p; 139 } 140 return (0); 141 } 142