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 #include "nis_common.h" 31 #include <synch.h> 32 #include <netdb.h> 33 #include <sys/socket.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #include <string.h> 37 38 static int nettoa(int anet, char *buf, int buflen, char **pnull); 39 40 static nss_status_t 41 getbyname(be, a) 42 nis_backend_ptr_t be; 43 void *a; 44 { 45 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 46 47 return (_nss_nis_lookup(be, argp, 1, "networks.byname", 48 argp->key.name, 0)); 49 } 50 51 static nss_status_t 52 getbyaddr(be, a) 53 nis_backend_ptr_t be; 54 void *a; 55 { 56 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 57 char addrstr[16]; 58 char *pnull; 59 nss_status_t rc; 60 61 if (nettoa((int)argp->key.netaddr.net, addrstr, 16, &pnull) != 0) 62 return (NSS_UNAVAIL); /* it's really ENOMEM */ 63 rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", addrstr, 0); 64 65 /* 66 * if not found, try again with the untruncated address string 67 * that has the trailing zero(s) 68 */ 69 if (rc == NSS_NOTFOUND && pnull != NULL) { 70 *pnull = '.'; 71 rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", 72 addrstr, 0); 73 } 74 return (rc); 75 } 76 77 static nis_backend_op_t net_ops[] = { 78 _nss_nis_destr, 79 _nss_nis_endent, 80 _nss_nis_setent, 81 _nss_nis_getent_netdb, 82 getbyname, 83 getbyaddr 84 }; 85 86 /*ARGSUSED*/ 87 nss_backend_t * 88 _nss_nis_networks_constr(dummy1, dummy2, dummy3) 89 const char *dummy1, *dummy2, *dummy3; 90 { 91 return (_nss_nis_constr(net_ops, 92 sizeof (net_ops) / sizeof (net_ops[0]), 93 "networks.byaddr")); 94 } 95 96 /* 97 * Takes an unsigned integer in host order, and returns a printable 98 * string for it as a network number. To allow for the possibility of 99 * naming subnets, only trailing dot-zeros are truncated. The location 100 * where the string is truncated (or set to '\0') is returned in *pnull. 101 */ 102 static int 103 nettoa(int anet, char *buf, int buflen, char **pnull) 104 { 105 char *p; 106 struct in_addr in; 107 int addr; 108 109 *pnull = NULL; 110 111 if (buf == 0) 112 return (1); 113 in = inet_makeaddr(anet, INADDR_ANY); 114 addr = in.s_addr; 115 (void) strncpy(buf, inet_ntoa(in), buflen); 116 if ((IN_CLASSA_HOST & htonl(addr)) == 0) { 117 p = strchr(buf, '.'); 118 if (p == NULL) 119 return (1); 120 *p = 0; 121 *pnull = p; 122 } else if ((IN_CLASSB_HOST & htonl(addr)) == 0) { 123 p = strchr(buf, '.'); 124 if (p == NULL) 125 return (1); 126 p = strchr(p+1, '.'); 127 if (p == NULL) 128 return (1); 129 *p = 0; 130 *pnull = p; 131 } else if ((IN_CLASSC_HOST & htonl(addr)) == 0) { 132 p = strrchr(buf, '.'); 133 if (p == NULL) 134 return (1); 135 *p = 0; 136 *pnull = p; 137 } 138 return (0); 139 } 140