nis-util
1.0.D108
|
00001 // 00002 // nis-util - NIS Administration Utilities 00003 // Copyright (C) 2001, 2008, 2009, 2011, 2012 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or (at 00008 // your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #include <lib/ac/errno.h> 00020 #include <lib/ac/sys/stat.h> 00021 #include <lib/ac/unistd.h> 00022 00023 #include <lib/space/ethers/slurp.h> 00024 #include <lib/space/hosts/slurp.h> 00025 00026 00027 space_ethers_slurp::~space_ethers_slurp() 00028 { 00029 } 00030 00031 00032 space_ethers_slurp::space_ethers_slurp( 00033 const rcstring &a_filename, 00034 const space_hosts_slurp::pointer &a_hosts 00035 ) : 00036 space_ethers(a_filename), 00037 hosts(a_hosts) 00038 { 00039 } 00040 00041 00042 space_ethers_slurp::pointer 00043 space_ethers_slurp::create(const rcstring &a_filename, 00044 const space_hosts_slurp::pointer &a_hosts) 00045 { 00046 return pointer(new space_ethers_slurp(a_filename, a_hosts)); 00047 } 00048 00049 00050 void 00051 space_ethers_slurp::process(const record::pointer &rp0) 00052 { 00053 record::pointer rp = rp0; 00054 00055 // 00056 // Check MAC address. 00057 // 00058 { 00059 by_addr_t::iterator it = by_addr.find(rp->get_mac_address()); 00060 if (it != by_addr.end()) 00061 { 00062 error 00063 ( 00064 rp->get_source_location(), 00065 "duplicate %s MAC address...", 00066 rp->get_mac_address().quote_c().c_str() 00067 ); 00068 error 00069 ( 00070 it->second->get_source_location(), 00071 "... here is the first %s MAC address", 00072 it->second->get_mac_address().quote_c().c_str() 00073 ); 00074 } 00075 else 00076 { 00077 by_addr.insert(by_addr_t::value_type(rp->get_mac_address(), rp)); 00078 } 00079 } 00080 00081 // 00082 // Check IP address. 00083 // 00084 if (!rp->get_ip_address().empty()) 00085 { 00086 if (hosts) 00087 { 00088 space_hosts::record::pointer hp = 00089 hosts->query_by_address(rp->get_ip_address()); 00090 if (hp) 00091 { 00092 error 00093 ( 00094 rp->get_source_location(), 00095 "some NIS clients do not expect an IP address, " 00096 "replace %s with %s for maximum interoperability", 00097 rp->get_ip_address().quote_c().c_str(), 00098 hp->get_names().front().quote_c().c_str() 00099 ); 00100 00101 // re-write the record, using the correct name. 00102 rp = 00103 record::create 00104 ( 00105 rp->get_source_location(), 00106 rp->get_mac_address(), 00107 hp->get_names().front(), 00108 rp->get_ip_address() 00109 ); 00110 } 00111 else 00112 { 00113 error 00114 ( 00115 rp->get_source_location(), 00116 "some NIS clients do not expect an IP address, replace " 00117 "the %s IP address with the host name for maximum " 00118 "interoperability; and also add it to the hosts map", 00119 rp->get_ip_address().quote_c().c_str() 00120 ); 00121 } 00122 } 00123 00124 by_ip_addr_t::iterator it = by_ip_addr.find(rp->get_ip_address()); 00125 if (it != by_ip_addr.end()) 00126 { 00127 assert(it->second); 00128 error 00129 ( 00130 rp->get_source_location(), 00131 "duplicate %s ip address...", 00132 rp->get_ip_address().c_str() 00133 ); 00134 if (it->second->get_ip_address().empty()) 00135 { 00136 error 00137 ( 00138 it->second->get_source_location(), 00139 "... here is the first reference" 00140 ); 00141 } 00142 else 00143 { 00144 error 00145 ( 00146 it->second->get_source_location(), 00147 "... here is the first %s ip address", 00148 it->second->get_ip_address().quote_c().c_str() 00149 ); 00150 } 00151 } 00152 else 00153 { 00154 by_name.insert 00155 ( 00156 by_ip_addr_t::value_type(rp->get_ip_address(), rp) 00157 ); 00158 } 00159 } 00160 00161 // 00162 // Check host name. 00163 // 00164 if (!rp->get_name().empty()) 00165 { 00166 if (hosts) 00167 { 00168 space_hosts::record::pointer hp = 00169 hosts->query_by_name(rp->get_name()); 00170 if (!hp) 00171 { 00172 error 00173 ( 00174 rp->get_source_location(), 00175 "host %s does not exist in the hosts map", 00176 rp->get_name().quote_c().c_str() 00177 ); 00178 } 00179 else if (rp->get_ip_address().empty()) 00180 { 00181 // rewrite the record with the IP address 00182 rp = 00183 space_ethers::record::create 00184 ( 00185 rp->get_source_location(), 00186 rp->get_mac_address(), 00187 rp->get_name(), 00188 hp->get_ip_address() 00189 ); 00190 by_ip_addr_t::iterator ipit = 00191 by_ip_addr.find(hp->get_ip_address()); 00192 if (ipit != by_ip_addr.end()) 00193 { 00194 error 00195 ( 00196 rp->get_source_location(), 00197 "duplicate %s ip address...", 00198 rp->get_ip_address().quote_c().c_str() 00199 ); 00200 if (ipit->second->get_ip_address().empty()) 00201 { 00202 error 00203 ( 00204 ipit->second->get_source_location(), 00205 "... here is the first reference" 00206 ); 00207 } 00208 else 00209 { 00210 error 00211 ( 00212 ipit->second->get_source_location(), 00213 "... here is the first %s ip address", 00214 rp->get_ip_address().quote_c().c_str() 00215 ); 00216 } 00217 } 00218 else 00219 { 00220 by_ip_addr.insert 00221 ( 00222 by_ip_addr_t::value_type(rp->get_ip_address(), rp) 00223 ); 00224 } 00225 } 00226 } 00227 00228 // We use a lower-case name intentionally, 00229 // because DNS things names are not case sensitive. 00230 by_name_t::iterator it = by_name.find(rp->get_name().downcase()); 00231 if (it != by_name.end()) 00232 { 00233 // but preserve case in the error messages 00234 error 00235 ( 00236 rp->get_source_location(), 00237 "duplicate %s host name...", 00238 rp->get_name().c_str() 00239 ); 00240 if (it->second->get_name().empty()) 00241 { 00242 error 00243 ( 00244 it->second->get_source_location(), 00245 "... here is the first reference" 00246 ); 00247 } 00248 else 00249 { 00250 error 00251 ( 00252 it->second->get_source_location(), 00253 "... here is the first %s host name", 00254 it->second->get_name().quote_c().c_str() 00255 ); 00256 } 00257 } 00258 else 00259 { 00260 // We use a lower-case name intentionally, 00261 // because DNS thinks host names are not case sensitive. 00262 by_name.insert 00263 ( 00264 by_name_t::value_type(rp->get_name().downcase(), rp) 00265 ); 00266 } 00267 } 00268 00269 // 00270 // Check line length. 00271 // 00272 if (rp->representation().size() >= 512) 00273 { 00274 error 00275 ( 00276 rp->get_source_location(), 00277 "line too long (NIS limits records to 511 bytes, NIS+ limits " 00278 "records to 1023 bytes)" 00279 ); 00280 } 00281 } 00282 00283 00284 void 00285 space_ethers_slurp::read_and_process(void) 00286 { 00287 for (;;) 00288 { 00289 space_ethers::record::pointer rp = get(); 00290 if (!rp) 00291 break; 00292 process(rp); 00293 } 00294 close(); 00295 } 00296 00297 00298 space_ethers::record::pointer 00299 space_ethers_slurp::query_by_name(const rcstring &name) 00300 const 00301 { 00302 by_name_t::const_iterator it = by_name.find(name); 00303 if (it == by_name.end()) 00304 return record::pointer(); 00305 return it->second; 00306 } 00307 00308 00309 space_ethers::record::pointer 00310 space_ethers_slurp::query_by_address(const rcstring &address) 00311 const 00312 { 00313 by_addr_t::const_iterator it = by_addr.find(address); 00314 if (it == by_addr.end()) 00315 return record::pointer(); 00316 return it->second; 00317 } 00318 00319 00320 // vim: set ts=8 sw=4 et :