]>
Commit | Line | Data |
---|---|---|
ad26538e | 1 | /* |
eefd15f9 BH |
2 | * PowerDNS BIND Zone to LDAP converter |
3 | * Copyright (C) 2003 Norbert Sendetzky | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
06bd9ccf | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
ad26538e BH |
18 | */ |
19 | ||
20 | ||
ad26538e | 21 | #include <map> |
eefd15f9 | 22 | #include <string> |
ad26538e BH |
23 | #include <iostream> |
24 | #include <stdio.h> | |
ad26538e BH |
25 | #include "arguments.hh" |
26 | #include "zoneparser.hh" | |
27 | #include "bindparser.hh" | |
28 | #include "statbag.hh" | |
29 | #include "misc.hh" | |
eefd15f9 BH |
30 | #include "dns.hh" |
31 | ||
32 | ||
33 | using std::map; | |
34 | using std::string; | |
35 | using std::vector; | |
ad26538e BH |
36 | |
37 | ||
38 | ||
39 | StatBag S; | |
40 | ArgvMap args; | |
eefd15f9 | 41 | bool g_dnsttl; |
ad26538e BH |
42 | string g_basedn; |
43 | string g_zonename; | |
44 | map<string,bool> g_objects; | |
45 | ||
46 | ||
eefd15f9 BH |
47 | |
48 | static void callback_simple( unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio ) | |
ad26538e | 49 | { |
e1d03bb0 | 50 | string host; |
eefd15f9 | 51 | string::size_type pos; |
ad26538e BH |
52 | vector<string> parts; |
53 | string domain2 = ZoneParser::canonic( domain ); | |
ad26538e BH |
54 | |
55 | ||
eefd15f9 BH |
56 | if( ( pos = domain2.rfind( g_zonename ) ) == string::npos ) |
57 | { | |
58 | cerr << "Domain " << domain2 << " not part of " << g_zonename << endl; | |
59 | return; | |
60 | } | |
61 | ||
62 | host = ZoneParser::canonic( domain2.substr( 0, pos ) ); | |
e1d03bb0 BH |
63 | |
64 | cout << "dn: dc="; | |
65 | if( !host.empty() ) { cout << host << ",dc="; } | |
66 | cout << g_zonename << "," << g_basedn << endl; | |
67 | ||
68 | if( host.empty() ) { host = g_zonename; } | |
69 | ||
70 | if( !g_objects[domain2] ) | |
71 | { | |
72 | g_objects[domain2] = true; | |
eefd15f9 | 73 | |
e1d03bb0 | 74 | cout << "changetype: add" << endl; |
e1d03bb0 BH |
75 | cout << "objectclass: dnsdomain2" << endl; |
76 | cout << "objectclass: domainrelatedobject" << endl; | |
77 | cout << "dc: " << host << endl; | |
eefd15f9 | 78 | if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; } |
e1d03bb0 BH |
79 | cout << "associateddomain: " << domain2 << endl; |
80 | } | |
81 | else | |
82 | { | |
83 | cout << "changetype: modify" << endl; | |
0bd420b4 | 84 | cout << "add: " << qtype << "Record" << endl; |
e1d03bb0 BH |
85 | } |
86 | ||
87 | cout << qtype << "Record: "; | |
88 | if( prio != 0 ) { cout << prio << " "; } | |
eefd15f9 | 89 | cout << ZoneParser::canonic( content ) << endl << endl; |
e1d03bb0 BH |
90 | } |
91 | ||
92 | ||
eefd15f9 | 93 | |
e1d03bb0 BH |
94 | static void callback_tree( unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio ) |
95 | { | |
eefd15f9 BH |
96 | unsigned int i; |
97 | string dn, net; | |
98 | vector<string> parts; | |
e1d03bb0 | 99 | string domain2 = ZoneParser::canonic( domain ); |
e1d03bb0 | 100 | |
eefd15f9 BH |
101 | stringtok( parts, domain2, "." ); |
102 | if( parts.empty() ) { return; } | |
e1d03bb0 | 103 | |
eefd15f9 | 104 | for( i = parts.size() - 1; i > 0; i-- ) |
e1d03bb0 | 105 | { |
eefd15f9 BH |
106 | net = parts[i] + net; |
107 | dn = "dc=" + parts[i] + "," + dn; | |
108 | ||
109 | if( !g_objects[net] ) | |
e1d03bb0 | 110 | { |
eefd15f9 | 111 | g_objects[net] = true; |
e1d03bb0 | 112 | |
eefd15f9 | 113 | cout << "dn: " << dn << g_basedn << endl; |
e1d03bb0 | 114 | cout << "changetype: add" << endl; |
0bd420b4 | 115 | cout << "objectclass: dnsdomain2" << endl; |
e1d03bb0 | 116 | cout << "objectclass: domainrelatedobject" << endl; |
eefd15f9 | 117 | cout << "dc: " << parts[i] << endl; |
e1d03bb0 BH |
118 | cout << "associateddomain: " << net << endl << endl; |
119 | } | |
e1d03bb0 | 120 | |
eefd15f9 | 121 | net = "." + net; |
ad26538e | 122 | } |
eefd15f9 BH |
123 | |
124 | cout << "dn: " << "dc=" << parts[0] << "," << dn << g_basedn << endl; | |
ad26538e | 125 | |
e1d03bb0 | 126 | if( !g_objects[domain2] ) |
ad26538e BH |
127 | { |
128 | g_objects[domain2] = true; | |
eefd15f9 | 129 | |
ad26538e | 130 | cout << "changetype: add" << endl; |
e1d03bb0 | 131 | cout << "objectclass: dnsdomain2" << endl; |
ad26538e BH |
132 | cout << "objectclass: domainrelatedobject" << endl; |
133 | cout << "dc: " << parts[0] << endl; | |
eefd15f9 | 134 | if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; } |
ad26538e BH |
135 | cout << "associateddomain: " << domain2 << endl; |
136 | } | |
137 | else | |
138 | { | |
139 | cout << "changetype: modify" << endl; | |
0bd420b4 | 140 | cout << "add: " << qtype << "Record" << endl; |
ad26538e BH |
141 | } |
142 | ||
e1d03bb0 BH |
143 | cout << qtype << "Record: "; |
144 | if( prio != 0 ) { cout << prio << " "; } | |
eefd15f9 | 145 | cout << ZoneParser::canonic( content ) << endl << endl; |
ad26538e BH |
146 | } |
147 | ||
148 | ||
eefd15f9 | 149 | |
ad26538e BH |
150 | int main( int argc, char* argv[] ) |
151 | { | |
ad26538e BH |
152 | BindParser BP; |
153 | ZoneParser ZP; | |
e1d03bb0 | 154 | vector<string> parts; |
ad26538e BH |
155 | |
156 | ||
ad26538e BH |
157 | try |
158 | { | |
159 | #if __GNUC__ >= 3 | |
160 | ios_base::sync_with_stdio( false ); | |
161 | #endif | |
162 | ||
163 | args.setCmd( "help", "Provide a helpful message" ); | |
164 | args.setSwitch( "verbose", "Verbose comments on operation" ) = "no"; | |
165 | args.setSwitch( "resume", "Continue after errors" ) = "no"; | |
eefd15f9 | 166 | args.setSwitch( "dnsttl", "Add dnsttl attribute to every entry" ) = "no"; |
ad26538e | 167 | args.set( "named-conf", "Bind 8 named.conf to parse" ) = ""; |
e1d03bb0 BH |
168 | args.set( "zone-file", "Zone file to parse" ) = ""; |
169 | args.set( "zone-name", "Specify a zone name if zone is set" ) = ""; | |
eefd15f9 BH |
170 | args.set( "basedn", "Base DN to store objects below" ) = "ou=hosts,o=mycompany,c=de"; |
171 | args.set( "layout", "How to arrange entries in the directory (simple or as tree)" ) = "simple"; | |
ad26538e BH |
172 | |
173 | args.parse( argc, argv ); | |
174 | ||
175 | if( argc < 2 || args.mustDo( "help" ) ) | |
176 | { | |
177 | cerr << "Syntax:" << endl << endl; | |
178 | cerr << args.helpstring() << endl; | |
179 | exit( 1 ); | |
180 | } | |
181 | ||
182 | g_basedn = args["basedn"]; | |
eefd15f9 BH |
183 | g_dnsttl = args.mustDo( "dnsttl" ); |
184 | ||
185 | ZP.setCallback( &callback_simple ); | |
186 | if( args["layout"] == "tree" ) | |
e1d03bb0 | 187 | { |
eefd15f9 | 188 | ZP.setCallback( &callback_tree ); |
e1d03bb0 | 189 | } |
ad26538e | 190 | |
e1d03bb0 | 191 | if( !args["named-conf"].empty() ) |
ad26538e | 192 | { |
e1d03bb0 BH |
193 | BP.setVerbose( args.mustDo( "verbose" ) ); |
194 | BP.parse( args["named-conf"] ); | |
ad26538e BH |
195 | ZP.setDirectory( BP.getDirectory() ); |
196 | const vector<BindDomainInfo> &domains = BP.getDomains(); | |
197 | ||
e1d03bb0 | 198 | for( vector<BindDomainInfo>::const_iterator i = domains.begin(); i != domains.end(); i++ ) |
ad26538e BH |
199 | { |
200 | try | |
201 | { | |
e1d03bb0 | 202 | if( i->name != "." && i->name != "localhost" && i->name != "0.0.127.in-addr.arpa" ) |
ad26538e BH |
203 | { |
204 | cerr << "Parsing file: " << i->filename << ", domain: " << i->name << endl; | |
e1d03bb0 | 205 | g_zonename = i->name; |
ad26538e BH |
206 | ZP.parse( i->filename, i->name, 0 ); |
207 | } | |
208 | } | |
209 | catch( AhuException &ae ) | |
210 | { | |
211 | cerr << "Fatal error: " << ae.reason << endl; | |
212 | if( !args.mustDo( "resume" ) ) | |
213 | { | |
214 | return 1; | |
215 | } | |
216 | } | |
217 | } | |
218 | } | |
219 | else | |
220 | { | |
e1d03bb0 BH |
221 | if( args["zone-file"].empty() || args["zone-name"].empty() ) |
222 | { | |
223 | cerr << "Error: At least zone-file and zone-name are required" << endl; | |
224 | return 1; | |
225 | } | |
226 | ||
e1d03bb0 | 227 | g_zonename = args["zone-name"]; |
ad26538e | 228 | ZP.setDirectory( "." ); |
e1d03bb0 | 229 | ZP.parse( args["zone-file"], args["zone-name"], 0 ); |
ad26538e BH |
230 | } |
231 | } | |
232 | catch( AhuException &ae ) | |
233 | { | |
234 | cerr << "Fatal error: " << ae.reason << endl; | |
235 | return 1; | |
236 | } | |
237 | catch( exception &e ) | |
238 | { | |
239 | cerr << "Died because of STL error: " << e.what() << endl; | |
240 | return 1; | |
241 | } | |
242 | catch( ... ) | |
243 | { | |
244 | cerr << "Died because of unknown exception" << endl; | |
245 | return 1; | |
246 | } | |
247 | ||
248 | return 0; | |
249 | } |