]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/backends/bind/zone2ldap.cc
the FSF has moved!
[thirdparty/pdns.git] / pdns / backends / bind / zone2ldap.cc
CommitLineData
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
33using std::map;
34using std::string;
35using std::vector;
ad26538e
BH
36
37
38
39StatBag S;
40ArgvMap args;
eefd15f9 41bool g_dnsttl;
ad26538e
BH
42string g_basedn;
43string g_zonename;
44map<string,bool> g_objects;
45
46
eefd15f9
BH
47
48static 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
94static 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
150int 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}