zentyal-dns-2.3.10+quantal1/0000775000000000000000000000000012017140137012453 5ustar zentyal-dns-2.3.10+quantal1/COPYING0000664000000000000000000004311012017140137013505 0ustar GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. zentyal-dns-2.3.10+quantal1/debian/0000775000000000000000000000000012017140137013675 5ustar zentyal-dns-2.3.10+quantal1/debian/compat0000664000000000000000000000000212017140137015073 0ustar 5 zentyal-dns-2.3.10+quantal1/debian/copyright0000664000000000000000000000214112017140137015626 0ustar This package was debianized by Zentyal Packaging Maintainers Fri, 20 Feb 2005 15:13:22 +0100. It was downloaded from http://www.zentyal.org/ Files: * Upstream Author: eBox Technologies S.L. Copyright (C) 2004-2012 eBox Technologies S.L. License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2 file. The Debian packaging is: (C) 2004-2011, Zentyal Packaging Maintainers and is licensed under the GPL, see `/usr/share/common-licenses/GPL-2'. zentyal-dns-2.3.10+quantal1/debian/zentyal-dns.postrm0000664000000000000000000000033012017140137017407 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in purge) # purge configuration /usr/share/zentyal/purge-module dns ;; remove) dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-dns-2.3.10+quantal1/debian/control0000664000000000000000000000176712017140137015313 0ustar Source: zentyal-dns Section: web Priority: optional Maintainer: Zentyal Packaging Maintainers Uploaders: Jorge Salamero Sanz Build-Depends: zbuildtools Standards-Version: 3.9.2 Homepage: http://www.zentyal.org/ Vcs-Browser: http://git.zentyal.org/zentyal.git/tree/quantal:/main/dns Vcs-Git: git://git.zentyal.org/zentyal.git Package: zentyal-dns Architecture: all Replaces: ebox-dns (<< 2.0.100) Breaks: ebox-dns (<< 2.0.100) Depends: zentyal-core (>= 2.3), zentyal-core (<< 2.3.100), zentyal-network, zentyal-firewall, bind9, libcrypt-openssl-random-perl, ${misc:Depends} Description: Zentyal - DNS Service Zentyal is a Linux small business server that can act as a Gateway, Unified Threat Manager, Office Server, Infrastructure Manager, Unified Communications Server or a combination of them. One single, easy-to-use platform to manage all your network services. . This module adds a DNS server to Zentyal, allowing faster name resolution and local domains. zentyal-dns-2.3.10+quantal1/debian/zentyal-dns.postinst0000664000000000000000000000043712017140137017756 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in configure) # initial setup /usr/share/zentyal/initial-setup --no-restart dns $2 # restart module invoke-rc.d zentyal dns restart || true dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-dns-2.3.10+quantal1/debian/source/0000775000000000000000000000000012017140137015175 5ustar zentyal-dns-2.3.10+quantal1/debian/source/format0000664000000000000000000000001512017140137016404 0ustar 3.0 (native) zentyal-dns-2.3.10+quantal1/debian/ebox.bind9.upstart0000664000000000000000000000037512017140137017267 0ustar pre-start script invoke-rc.d bind9 stop || true modprobe capability >/dev/null 2>&1 || true mkdir -p /var/run/named chmod 775 /var/run/named chown root:bind /var/run/named >/dev/null 2>&1 || true end script exec /usr/sbin/named -u bind -f respawn zentyal-dns-2.3.10+quantal1/debian/rules0000775000000000000000000000010612017140137014752 0ustar #!/usr/bin/make -f include /usr/share/zbuildtools/1/rules/zentyal.mk zentyal-dns-2.3.10+quantal1/debian/changelog0000664000000000000000000001765712017140137015567 0ustar zentyal-dns (2.3.10+quantal1) quantal; urgency=low * New upstream release for Quantal -- Jorge Salamero Sanz Tue, 28 Aug 2012 14:55:53 +0200 zentyal-dns (2.3.10) precise; urgency=low * New upstream release -- José A. Calvo Thu, 23 Aug 2012 03:14:11 +0200 zentyal-dns (2.3.9) precise; urgency=low * New upstream release -- José A. Calvo Thu, 12 Jul 2012 02:47:01 +0200 zentyal-dns (2.3.8) precise; urgency=low * New upstream release -- José A. Calvo Thu, 21 Jun 2012 12:40:51 +0200 zentyal-dns (2.3.7) precise; urgency=low * New upstream release -- José A. Calvo Thu, 14 Jun 2012 04:50:31 +0200 zentyal-dns (2.3.6) precise; urgency=low * New upstream release -- José A. Calvo Mon, 11 Jun 2012 00:41:26 +0200 zentyal-dns (2.3.5) precise; urgency=low * New upstream release -- José A. Calvo Mon, 02 Apr 2012 17:52:09 +0200 zentyal-dns (2.3.4) precise; urgency=low * New upstream release -- José A. Calvo Mon, 26 Mar 2012 17:12:14 +0200 zentyal-dns (2.3.1) precise; urgency=low * New upstream release -- José A. Calvo Tue, 06 Mar 2012 11:57:38 +0100 zentyal-dns (2.3-1) precise; urgency=low * Updated Standards-Version to 3.9.2 -- José A. Calvo Wed, 08 Feb 2012 16:12:43 +0100 zentyal-dns (2.3) precise; urgency=low * New upstream release -- José A. Calvo Mon, 30 Jan 2012 01:42:49 +0100 zentyal-dns (2.2.1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 25 Oct 2011 21:32:21 +0200 zentyal-dns (2.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 13 Sep 2011 04:40:36 +0200 zentyal-dns (2.1.6) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 10 Sep 2011 12:31:06 +0200 zentyal-dns (2.1.5) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 24 Aug 2011 03:19:13 +0200 zentyal-dns (2.1.4) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 15 Jun 2011 11:26:40 +0200 zentyal-dns (2.1.3) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 14 Jun 2011 00:36:47 +0200 zentyal-dns (2.1.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 10 May 2011 22:17:32 +0200 zentyal-dns (2.1.1) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 13 Mar 2011 18:36:43 +0100 zentyal-dns (2.1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 22 Feb 2011 03:12:06 +0100 ebox-dns (2.0.1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 28 Sep 2010 23:56:15 +0200 ebox-dns (2.0) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 30 Aug 2010 21:49:47 +0200 ebox-dns (1.5.1-1ubuntu1~ppa1~lucid1) lucid; urgency=low * Added creation of report table -- José A. Calvo Thu, 01 Jul 2010 02:13:27 +0200 ebox-dns (1.5.1-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 13 May 2010 01:31:54 +0200 ebox-dns (1.5-0ubuntu1) lucid; urgency=low [Javier Uruen Val] * New upstream release (LP: #521806) * debian/control - Bump eBox dependency - Add dependency on libcrypt-openssl-random-perl - Update description -- Javier Uruen Val Sun, 07 Feb 2010 18:51:11 +0100 ebox-dns (1.3.5-0ubuntu1) karmic; urgency=low [Javier Uruen Val] * New upstream release [LP: TBD] * cdbs/ebox.mk - GConf schemas are not used anymore - Remove SCHEMASPATH variable - Remove schemadir variabl - Use new upstart directory and file naming convention * debian/control - Bump standards version - Bump eBox depenency * debian/ebox-dns.postinst - Fix indentation - Do not pkill gconfd as it's not necessary anymore - Run ebox trigger * debian/ebox-dns.postrm - Add set -e * debian/rules - Do not include debian/cdbs/gnome.mk * debian/watch - Change URL -- Javier Uruen Val Wed, 05 Aug 2009 12:29:43 +0200 debox-dns (0.12.1-0ubuntu1) jaunty; urgency=low [ Javier Uruen Val ] * New upstream release. Closes (LP: #318822) * debian/control: - Bump standar version. - Drop dpatch build dependency. * debian/watch: - add watch file. -- Mathias Gug Mon, 26 Jan 2009 18:48:57 -0500 ebox-dns (0.11-0ubuntu3) hardy; urgency=low * debian/patches/02_is_running_interface. - Check for a running interface. -- Chuck Short Mon, 31 Mar 2008 08:26:02 -0400 ebox-dns (0.11-0ubuntu2) hardy; urgency=low * debian/patches/01_backport_0.11.9 - Various fixes for ebox-dns. -- Chuck Short Wed, 26 Mar 2008 10:38:55 -0400 ebox-dns (0.11-0ubuntu1) hardy; urgency=low * Update build depends. -- Chuck Short Tue, 04 Mar 2008 14:25:47 -0500 ebox-dns (0.11-0ubuntu1~ppa1) hardy; urgency=low * New upstream version. -- Chuck Short Thu, 21 Feb 2008 13:43:23 -0500 ebox-dns (0.11-0ubuntu1~ppa1) hardy; urgency=low * New upstream release -- Javier Uruen Val Mon, 18 Feb 2008 14:58:55 +0100 ebox-dns (0.11-1) unstable; urgency=low * Create /var/run/bind/run directory in upstart script -- Javier Uruen Val Sun, 20 Jan 2008 21:41:49 +0100 ebox-dns (0.11) unstable; urgency=low * New upstream release -- Javier Uruen Val Wed, 28 Nov 2007 15:23:32 +0100 ebox-dns (0.10.99) unstable; urgency=low * New upstream release -- Javier Uruen Val Thu, 01 Nov 2007 21:38:12 +0100 ebox-dns (0.10) unstable; urgency=low * New upstream release -- Javier Uruen Val Wed, 10 Oct 2007 21:53:47 +0200 ebox-dns (0.9.100) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 04 Sep 2007 14:12:36 +0200 ebox-dns (0.9.99) unstable; urgency=low * New upstream release -- Javier Amor Garcia Tue, 24 Jul 2007 12:30:26 +0200 ebox-dns (0.9.3) unstable; urgency=low * New upstream release -- Javier Uruen Val Sun, 24 Jun 2007 16:38:47 +0200 ebox-dns (0.9.2) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 12 Jun 2007 18:59:26 +0200 ebox-dns (0.9.1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 15 May 2007 13:02:24 +0200 ebox-dns (0.9) unstable; urgency=low * New upstream release -- Javier Amor Garcia Wed, 28 Mar 2007 15:39:36 +0200 ebox-dns (0.8.99) unstable; urgency=low * New upstream release -- Enrique José Hernández Blasco Fri, 2 Feb 2007 18:32:54 +0100 ebox-dns (0.8.2) unstable; urgency=low * New upstream release -- Isaac Clerencia Sat, 13 Jan 2007 09:43:18 +0000 ebox-dns-cache (0.7.1) unstable; urgency=low * New upstream release -- Daniel Baeyens Sicilia Wed, 22 Mar 2006 16:04:24 +0100 ebox-dns-cache (0.7.0.99-rc1+0.7.1-rc1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 17 Jan 2006 11:43:30 +0100 ebox-dns-cache (0.5.1) unstable; urgency=low * New upstream release -- Guillermo Ontañón Mon, 14 Mar 2005 14:31:51 +0100 ebox-dns-cache (0.5) unstable; urgency=low * New upstream release -- Isaac Clerencia Thu, 3 Mar 2005 19:54:56 +0100 ebox-dns-cache (0.4-2) unstable; urgency=low * New upstream release -- Isaac Clerencia Sat, 4 Dec 2004 16:36:45 +0100 zentyal-dns-2.3.10+quantal1/conf/0000775000000000000000000000000012017140137013400 5ustar zentyal-dns-2.3.10+quantal1/conf/dns.conf0000664000000000000000000000107512017140137015036 0ustar # This file contains the most basic settings, most other stuff is configured # using the web interface. # # Everything after a '#' character is ignored # # All whitespace is ignored # # Config keys are set this way: # # key = value # # They may contain comments at the end: # # key = value # this is ignored # Internal networks allowed to do recursive queries # to eBox DNS caching server. Localnetworks are already # allowed and this settings is intended to allow networks # reachable through static routes. # Example: intnets = 192.168.99.0/24,192.168.98.0/24 intnets = zentyal-dns-2.3.10+quantal1/src/0000775000000000000000000000000012017140137013242 5ustar zentyal-dns-2.3.10+quantal1/src/templates/0000775000000000000000000000000012017140137015240 5ustar zentyal-dns-2.3.10+quantal1/src/templates/ajax/0000775000000000000000000000000012017140137016163 5ustar zentyal-dns-2.3.10+quantal1/src/templates/ajax/viewer/0000775000000000000000000000000012017140137017464 5ustar zentyal-dns-2.3.10+quantal1/src/templates/ajax/viewer/domainTypeViewer.mas0000664000000000000000000000050512017140137023461 0ustar <%init> use EBox::DNS; <%args> $data % if (defined $data->printableValue() and % $data->value() eq EBox::DNS::DYNAMIC_ZONE() or % $data->value() eq EBox::DNS::DLZ_ZONE()) { yes % } else { no % } zentyal-dns-2.3.10+quantal1/src/templates/edit.mas0000664000000000000000000000541312017140137016672 0ustar <%args> $domain @hostnames <%init> use EBox::Gettext;

<% __x('Host list for domain {domain}', domain => $domain->{'name'}) %>

% if(@hostnames != 0) { % foreach my $host (@hostnames) { % } % }
<% __('IP') %> <% __('Host name') %> <% __('Action') %>
<% $host->{'ip'} %> <% $host->{'name'} %> &hostname=<% $host->{'id'} %>'> <% __('Delete') %>
% my @aliases = @{$host->{'aliases'}}; % if(@aliases != 0) { % foreach my $alias (@aliases) { % } % }
<%__('Alias') %>
<%__('Alias') %> <% $alias->{'name'} %> &hostname=<% $host->{'id'} %>&alias=<% $alias->{'id'} %>'> <% __('Delete') %>

<%__('delete')%>
zentyal-dns-2.3.10+quantal1/src/templates/index.mas0000664000000000000000000000327112017140137017054 0ustar <%args> $active @domains <%init> use EBox::Gettext;
<& enable.mas, title => __('DNS service status'), active => $active &>

<% __('Domain list') %>

% if(@domains != 0) { % foreach my $dom (@domains) { % } % }
<% __('Name') %> <% __('Action') %>
<% $dom->{'name'} %> <% __('Edit') %> - '> <% __('Delete') %>

<%__('edit')%>
<%__('delete')%>
zentyal-dns-2.3.10+quantal1/src/scripts/0000775000000000000000000000000012017140137014731 5ustar zentyal-dns-2.3.10+quantal1/src/scripts/initial-setup0000775000000000000000000000005112017140137017442 0ustar #!/bin/bash chmod g+w /etc/bind exit 0 zentyal-dns-2.3.10+quantal1/src/scripts/enable-module0000775000000000000000000000017112017140137017367 0ustar #!/bin/bash # stop bind9 invoke-rc.d bind9 stop # remove startup link update-rc.d -f bind9 remove chmod g+w /etc/bind zentyal-dns-2.3.10+quantal1/src/EBox/0000775000000000000000000000000012017140137014077 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/Composite/0000775000000000000000000000000012017140137016041 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/Composite/Global.pm0000664000000000000000000000252412017140137017602 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::DNS::Composite::Global # # This class is used to display the global DNS options in a common way # package EBox::DNS::Composite::Global; use base 'EBox::Model::Composite'; use strict; use warnings; use EBox::Gettext; use EBox::Global; # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $pageTitle = 'DNS'; my $description = { layout => 'top-bottom', name => 'Global', pageTitle => $pageTitle, printableName => $pageTitle, compositeDomain => 'DNS', }; return $description; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/View/0000775000000000000000000000000012017140137015011 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/View/DomainTableCustomizer.pm0000664000000000000000000000340012017140137021610 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA # Class: EBox::DNS::View::GatewayTableCustomizer # # This class is used to override the EBox::View::Customizer method # that allows modification on the fields of the DomainTable mode. # # We hide the dynamic attribute in add new form # package EBox::DNS::View::DomainTableCustomizer; use base 'EBox::View::Customizer'; use strict; use warnings; # Group: Public methods # Method: initHTMLStateField # # Given a field, it returns if the field has to be shown. hidden, or disabled # TODO This method should be deleted when the hiddenOnSetter attribute of the # domain field will work ok # # Parameters: # # (Positional) # # fieldName - string containing the field name # fields - array ref of instancied types with their current values # # Returns: # # One of these strings: # # show # hide # disable # sub initHTMLStateField { my ($self, $fieldName, $fields) = @_; if (defined($fieldName) and ($fieldName eq 'type')) { return 'hide'; } else { return $self->SUPER::initHTMLStateField($fieldName, $fields); } } 1; zentyal-dns-2.3.10+quantal1/src/EBox/DNS.pm0000664000000000000000000013512512017140137015070 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::DNS; use strict; use warnings; use base qw(EBox::Module::Service EBox::FirewallObserver); use EBox::Objects; use EBox::Gettext; use EBox::Config; use EBox::Exceptions::Sudo::Command; use EBox::Service; use EBox::Menu::Item; use EBox::Sudo; use EBox::Validate qw( :all ); use EBox::DNS::Model::DomainTable; use EBox::DNS::Model::HostnameTable; use EBox::DNS::Model::AliasTable; use EBox::Model::Manager; use EBox::Sudo; use EBox::DNS::FirewallHelper; use Error qw(:try); use File::Temp; use File::Slurp; use Fcntl qw(:seek); use IO::Socket::INET; use Net::IP; use Perl6::Junction qw(any); use Tie::File; use constant BIND9CONFDIR => "/etc/bind"; use constant BIND9CONFFILE => "/etc/bind/named.conf"; use constant BIND9CONFOPTIONSFILE => "/etc/bind/named.conf.options"; use constant BIND9CONFLOCALFILE => "/etc/bind/named.conf.local"; use constant BIND9INIT => "/etc/init.d/bind9"; use constant BIND9_UPDATE_ZONES => "/var/lib/bind"; use constant PIDFILE => "/var/run/bind/run/named.pid"; use constant KEYSFILE => BIND9CONFDIR . '/keys'; use constant DNS_CONF_FILE => EBox::Config::etc() . 'dns.conf'; use constant DNS_INTNETS => 'intnets'; use constant NS_UPDATE_CMD => 'nsupdate'; use constant DELETED_RR_KEY => 'deleted_rr'; use constant DNS_PORT => 53; # This constants are used to fill the domain type field of the # DomainTable model use constant STATIC_ZONE => 'static'; use constant DYNAMIC_ZONE => 'dynamic'; use constant DLZ_ZONE => 'dlz'; sub _create { my $class = shift; my $self = $class->SUPER::_create(name => 'dns', printableName => 'DNS', @_); bless ($self, $class); return $self; } # Method: appArmorProfiles # # Overrides to set the own AppArmor profile # # Overrides: # # # sub appArmorProfiles { my ($self) = @_; EBox::info('Setting DNS apparmor profile'); my @params = (); return [ { 'binary' => 'usr.sbin.named', 'local' => 1, 'file' => 'dns/apparmor-named.local.mas', 'params' => \@params, } ]; } # samba it is in dependecies bz it must be started before than DNS but is not # needed for restore and dns can work without it sub restoreDependencies { my ($self) = @_; my $global = EBox::Global->getInstance(); my @deps = grep { $_ ne 'samba' } @{ $global->modDepends($self->name) }; return \@deps; } # Method: addDomain # # Add new domain to table model # # Parameters: # # Check for details # sub addDomain { my ($self, $domainData) = @_; my $domainModel = $self->model('DomainTable'); $domainModel->addDomain($domainData); } # Method: addService # # Add a new SRV record to the domain # # Parameters: # # Check for details # sub addService { my ($self, $domain, $service) = @_; my $model = $self->model('DomainTable'); $model->addService($domain, $service); } # Method: delService # # Deletes a SRV record from the domain # # Parameters: # # Check for details # sub delService { my ($self, $domain, $service) = @_; my $model = $self->model('DomainTable'); $model->delService($domain, $service); } # Method: addText # # Add a new TXT record to the domain # # Parameters: # # Check for details # sub addText { my ($self, $domain, $txt) = @_; my $model = $self->model('DomainTable'); $model->addText($domain, $txt); } # Method: delText # # Deletes a TXT record from the domain # # Parameters: # # Check for details # sub delText { my ($self, $domain, $txt) = @_; my $model = $self->model('DomainTable'); $model->delText($domain, $txt); } # Method: addHost # # Adds a host to the domain # # Parameters: # # Check for details # sub addHost { my ($self, $domain, $host) = @_; my $model = $self->model('DomainTable'); $model->addHost($domain, $host); } # Method: delHost # # Deletes a host from the domain # # Parameters: # # Check for details # sub delHost { my ($self, $domain, $host) = @_; my $model = $self->model('DomainTable'); $model->delHost($domain, $host); } # Method: domains # # Returns an array with all domain names # # Returns: # # Array ref - containing hash refs with the following elements: # name - String the domain's name # type - String indicating the domain type (static, dynamic, dlz) # sub domains { my $self = shift; my $array = []; my $model = $self->model('DomainTable'); foreach my $id (@{$model->ids()}) { my $row = $model->row($id); my $domaindata = { name => $row->valueByName('domain'), type => $row->valueByName('type'), dlzDbPath => $row->valueByName('dlzDbPath') }; push @{$array}, $domaindata; } return $array; } # Method: getHostnames # # Given a domain name, it returns an array ref of hostnames that # it contains. # # Parameters: # # domain - String the domain's name # # Returns: # # array ref - containing the same structure as # returns # sub getHostnames { my ($self, $domain) = @_; unless (defined $domain) { throw EBox::Exceptions::MissingArgument('domain'); } my $domainRow = $self->model('DomainTable')->findRow(domain => $domain); unless (defined $domainRow) { throw EBox::Exceptions::DataNotFound(data => __('domain'), value => $domain); } return $self->_hostnames($domainRow->subModel('hostnames')); } # Method: aliases # # Returns an array with all alias structure of a hostname # # Parameters: # # model - Model to iterate over # # Returns: # # array ref with this structure data: # name - alias name # sub aliases { my ($self, $model) = @_; my $array = []; foreach my $id (@{$model->ids()}) { my $row = $model->row($id); push @{$array}, $row->valueByName('alias'); } return $array; } # Method: hostIpAddresses # # Returns an array with all IP of a hostname # # Parameters: # # model - Model to iterate over # # Returns: # # array ref with this structure data: # ip - Ip address # sub hostIpAddresses { my ($self, $model) = @_; my $array = []; foreach my $id (@{$model->ids()}) { my $row = $model->row($id); push @{$array}, $row->valueByName('ip'); } return $array; } # Method: getServices # # Given a domain name, it returns an array ref of SRV records that # it contains. # # Parameters: # # domain - String the domain's name # # Returns: # # array ref - containing the same structure as # returns # sub getServices { my ($self, $domain) = @_; my $domainRow = $self->model('DomainTable')->findRow(domain => $domain); unless (defined $domainRow) { throw EBox::Exceptions::DataNotFound(data => __('domain'), value => $domain); } my $model = $domainRow->subModel('srv'); return $self->_serviceRecords($model); } # Method: getTexts # # Given a domain name, it returns an array ref of TXT records that # it contains. # # Parameters: # # domain - String the domain's name # # Returns: # # array ref - containing the same structure as # returns # sub getTexts { my ($self, $domain) = @_; my $domainRow = $self->model('DomainTable')->findRow(domain => $domain); unless (defined $domainRow) { throw EBox::Exceptions::DataNotFound(data => __('domain'), value => $domain); } return $self->_textRecords($domainRow->subModel('txt')); } # Method: findAlias # # Return the hostname which the alias refers to given a domain # # Parameters: # # domainName - String the domain name # alias - String the alias name # # Returns: # # String - the hostname which the alias refers to # # Exceptions: # # - thrown if any compulsory # argument is missing # # - thrown if the domain does # not exist or the alias does not exist # sub findAlias { my ($self, $domainName, $alias) = @_; $domainName or throw EBox::Exceptions::MissingArgument('domainName'); $alias or throw EBox::Exceptions::MissingArgument('alias'); my $domModel = $self->model('DomainTable'); $domModel->{cachedVersion} = 0; my $id = $domModel->find(domain => $domainName); unless (defined ($id)) { throw EBox::Exceptions::DataNotFound(data => 'domain', value => $domainName); } my $row = $domModel->row($id); foreach my $ids (@{$row->subModel('hostnames')->ids()}) { my $hostnameRow = $row->subModel('hostnames')->row($id); for my $aliasId (@{$hostnameRow->subModel('alias')->ids()}) { my $aliasRow = hostnameRow->subModel('alias')->row($aliasId); if ($alias eq $aliasRow->valueByName('alias')) { return $hostnameRow->valueByName('hostname'); } } } throw EBox::Exceptions::DataNotFound(data => 'alias', value => $alias); } # Method: NameserverHost # # Return those host which is the nameserver for every domain. # # Returns: # # String - the nameserver host name for every eBox defined domain # sub NameserverHost { my ($self) = @_; my $sysinfo = EBox::Global->modInstance('sysinfo'); return $sysinfo->hostName(); } # Method: usedFiles # # Override EBox::Module::Service::usedFiles # sub usedFiles { my ($self) = @_; my $files = [ { 'file' => BIND9CONFFILE, 'module' => 'dns', 'reason' => __('main bind9 configuration file'), }, { 'file' => BIND9CONFOPTIONSFILE, 'module' => 'dns', 'reason' => __('bind9 options configuration file'), }, { 'file' => BIND9CONFLOCALFILE , 'module' => 'dns', 'reason' => __('local bind9 configuration file'), }, { 'file' => KEYSFILE, 'module' => 'dns', 'reason' => __('Keys configuration file'), }, ]; } # Method: actions # # Overrides: # # # sub actions { return [ { 'action' => __x('Change the permissions for {dir} to allow writing to bind group', dir => BIND9CONFDIR), 'reason' => __('Let the bind daemon to be dynamically updated'), 'module' => 'dns' }, { 'action' => __('Remove bind9 init script link'), 'reason' => __('Zentyal will take care of starting and stopping ' . 'the services.'), 'module' => 'dns' }, { 'action' => __('Override named apparmor profile'), 'reason' => __('To allow samba daemon load Active Directory zone'), 'module' => 'dns', }, ]; } # Method: initialSetup # # Overrides: # EBox::Module::Base::initialSetup # sub initialSetup { my ($self, $version) = @_; # Create default rules and services only if installing the first time unless ($version) { my $services = EBox::Global->modInstance('services'); my $serviceName = 'dns'; unless ($services->serviceExists(name => $serviceName)) { $services->addMultipleService( 'name' => $serviceName, 'printableName' => 'DNS', 'description' => __('Domain Name Service'), 'readOnly' => 1, 'services' => $self->_services(), ); } my $firewall = EBox::Global->modInstance('firewall'); $firewall->setInternalService($serviceName, 'accept'); $firewall->saveConfigRecursive(); } # Execute initial-setup script to create SQL tables $self->SUPER::initialSetup($version); } sub _services { my ($self) = @_; return [ { 'protocol' => 'udp', 'sourcePort' => 'any', 'destinationPort' => 53, }, { 'protocol' => 'tcp', 'sourcePort' => 'any', 'destinationPort' => 53, }, ]; } # Method: _daemons # # Override # sub _daemons { return [ { 'name' => 'ebox.bind9' } ]; } # Method: enableService # # Overrides: # # # sub enableService { my ($self, $status) = @_; $self->SUPER::enableService($status); # Mark network module as changed to set localhost as the primary resolver if ($self->changed()) { my $net = EBox::Global->modInstance('network'); $net->setAsChanged(); } } # Method: _setConf # # Overrides: # # # sub _setConf { my ($self) = @_; my $keytabPath = undef; my $sambaZone = undef; if (EBox::Global->modExists('samba')) { my $sambaModule = EBox::Global->modInstance('samba'); if ($sambaModule->isEnabled()) { if (EBox::Sudo::fileTest('-f', EBox::Samba::SAMBA_DNS_KEYTAB())) { $keytabPath = EBox::Samba::SAMBA_DNS_KEYTAB(); } if (EBox::Sudo::fileTest('-f', EBox::Samba::SAMBA_DNS_ZONE())) { $sambaZone = EBox::Samba::SAMBA_DNS_ZONE(); } } } my @array = (); $self->writeConfFile(BIND9CONFFILE, "dns/named.conf.mas", \@array); push (@array, 'forwarders' => $self->_forwarders()); push (@array, 'keytabPath' => $keytabPath); $self->writeConfFile(BIND9CONFOPTIONSFILE, "dns/named.conf.options.mas", \@array); # Delete the already removed RR from dynamic and dlz zones $self->_removeDeletedRR(); # Delete files from no longer used domains $self->_removeDomainsFiles(); # Hash to store the keys indexed by name, storing the secret my %keys = (); my @domainData = (); my @domainIds = @{$self->_domainIds()}; foreach my $domainId (@domainIds) { my $domdata = $self->_completeDomain($domainId); # Store the domain data to create the reverse zones push (@domainData, $domdata); my $file; if ($domdata->{'type'} eq DLZ_ZONE) { # Update the zone but do not write file. # TODO $self->_updateDynDirectZone($domdata); next; } elsif ($domdata->{'type'} eq DYNAMIC_ZONE) { $file = BIND9_UPDATE_ZONES; } else { $file = BIND9CONFDIR; } $file .= '/db.' . $domdata->{'name'}; # Prevent to write the file again if this is dynamic and the # journal file has been already created if ($domdata->{'type'} eq DYNAMIC_ZONE and -e "${file}.jnl") { $self->_updateDynDirectZone($domdata); } else { @array = (); push (@array, 'domain' => $domdata); $self->writeConfFile($file, "dns/db.mas", \@array); EBox::Sudo::root("chown bind:bind '$file'"); } # Add the updater key if the zone is dynamic if ($domdata->{'type'} eq DYNAMIC_ZONE) { $keys{$domdata->{'name'}} = $domdata->{'tsigKey'}; } } my $reversedData = $self->switchToReverseInfoData(\@domainData); # Remove the unused reverse files $self->_removeUnusedReverseFiles($reversedData); my @inaddrs = (); foreach my $group (keys $reversedData) { my $reversedDataItem = $reversedData->{$group}; my $file; if ($reversedDataItem->{'type'} ne STATIC_ZONE) { $file = BIND9_UPDATE_ZONES; } else { $file = BIND9CONFDIR; } $file .= "/db." . $group; if ($reversedDataItem->{'type'} and -e "${file}.jnl" ) { # TODO $self->_updateDynReverseZone($reversedDataItem); } else { @array = (); push (@array, 'groupip' => $group); push (@array, 'rdata' => $reversedDataItem); $self->writeConfFile($file, "dns/dbrev.mas", \@array); EBox::Sudo::root("chown bind:bind '$file'"); } # Store to write the zone in named.conf.local push (@inaddrs, { ip => $group, file => $file, keyNames => [ $reversedDataItem->{'tsigKeyName'} ], } ); } my @domains = @{$self->domains()}; my @intnets = @{$self->_intnets()}; @array = (); push(@array, 'confDir' => BIND9CONFDIR); push(@array, 'dynamicConfDir' => BIND9_UPDATE_ZONES); push(@array, 'domains' => \@domains); push(@array, 'inaddrs' => \@inaddrs); push(@array, 'intnets' => \@intnets); $self->writeConfFile(BIND9CONFLOCALFILE, "dns/named.conf.local.mas", \@array); @array = ( 'keys' => \%keys ); $self->writeConfFile(KEYSFILE, 'dns/keys.mas', \@array, {'uid' => 'root', 'gid' => 'bind', mode => '640'}); # Set transparent DNS cache $self->_setTransparentCache(); } # Method: menu # # Overrides EBox::Module method. # sub menu { my ($self, $root) = @_; $root->add(new EBox::Menu::Item('text' => $self->printableName(), 'url' => 'DNS/Composite/Global', 'separator' => 'Infrastructure', 'order' => 420)); } sub logReportInfo { my ($self) = @_; my $domains = @{$self->domains()}; my $data = [ { 'table' => 'dns_domains', 'values' => { 'domains' => $domains } } ]; return $data; } sub consolidateReportInfoQueries { return [ { 'target_table' => 'dns_domains_report', 'query' => { 'select' => 'domains', 'from' => 'dns_domains' } } ]; } # Method: report # # Overrides: # sub report { my ($self, $beg, $end, $options) = @_; my $report = {}; $report->{'domains'} = $self->runMonthlyQuery($beg, $end, { 'select' => 'domains', 'from' => 'dns_domains_report', }, { 'name' => 'domains' }); return $report; } # Method: keysFile # # Get the keys file path # # Returns: # # String - the keys file path # sub keysFile { return KEYSFILE; } # Group: Protected methods # Method: _postServiceHook # # Override this method to try to update the dynamic and dlz zones # from static definition if the daemon was stopped on configuration # regeneration # # Overrides: # # # sub _postServiceHook { my ($self, $enabled) = @_; if ( $enabled ) { my $nTry = 0; do { sleep(1); } while ( $nTry < 5 and (not $self->_isNamedListening())); if ( $nTry < 5 ) { foreach my $cmd (@{$self->{nsupdateCmds}}) { EBox::Sudo::root($cmd); my ($filename) = $cmd =~ m:\s(.*?)$:; unlink($filename); # Remove the temporary file } delete $self->{nsupdateCmds}; } } return $self->SUPER::_postServiceHook($enabled); } # Group: Private methods sub _intnets { my ($self) = @_; my $intnets_string = EBox::Config::configkeyFromFile(DNS_INTNETS, DNS_CONF_FILE); my @intnets = (); if (defined($intnets_string)) { @intnets = split(',', $intnets_string); } return \@intnets; } # Method: _domainIpAddresses # # Returns an array ref with all domain ip addresses # # Parameters: # # model to iterate over # # Returns: # # array ref # sub _domainIpAddresses { my ($self, $model) = @_; my @array; foreach my $id (@{$model->ids()}) { my $row = $model->row($id); push (@array, $row->valueByName('ip')); } return \@array; } # Method: _hostnames # # Returns an array with all hostname structure # # Parameters: # model to iterate over # # Returns: # array ref with this structure data: # # 'name': hostname # 'ip': an array ref containing the IP addresses of the host # 'aliases': an array ref returned by method. # sub _hostnames { my ($self, $model) = @_; my @array; foreach my $id (@{$model->ids()}) { my $hostname = $model->row($id); my $hostdata; $hostdata->{'name'} = $hostname->valueByName('hostname'); $hostdata->{'ip'} = $self->hostIpAddresses($hostname->subModel('ipAddresses')); $hostdata->{'aliases'} = $self->aliases($hostname->subModel('alias')); push(@array, $hostdata); } return \@array; } # Method: _serviceRecords # # Returns an array with all SRV records of a domain # # Parameters: # # model - Model to iterate over # # Returns: # # array ref with this structure data: # name - Service name # protocol - Service protocol # priority - Service priority # weight - Service weight # port - Service port # target - Service target host # sub _serviceRecords { my ($self, $model) = @_; my $array = []; foreach my $id (@{$model->ids()}) { my $service = $model->row($id); my $data = {}; $data->{name} = $service->valueByName('service_name'); $data->{protocol} = $service->valueByName('protocol'); $data->{priority} = $service->valueByName('priority'); $data->{weight} = $service->valueByName('weight'); $data->{port} = $service->valueByName('port'); my $selected = $service->elementByName('hostName')->selectedType(); if ($selected eq 'custom') { $data->{target} = $service->valueByName('custom'); } elsif ($selected eq 'ownerDomain') { my $rowId = $service->valueByName('ownerDomain'); $data->{target} = $service->parentRow() ->subModel('hostnames') ->row($rowId) ->valueByName('hostname'); } push @{$array}, $data; } return $array; } # Method: _textRecords # # Returns an array with all TXT records of a domain # # Parameters: # # model - Model to iterate over # # Returns: # # array ref with this structure data: # name # data # sub _textRecords { my ($self, $model) = @_; my $array = []; foreach my $id (@{$model->ids()}) { my $txt = $model->row($id); my $data = {}; $data->{data} = $txt->valueByName('txt_data'); my $selected = $txt->elementByName('hostName')->selectedType(); if ($selected eq 'custom') { $data->{target} = $txt->valueByName('custom'); } elsif ($selected eq 'ownerDomain') { my $rowId = $txt->valueByName('ownerDomain'); $data->{target} = $txt->parentRow() ->subModel('hostnames') ->row($rowId) ->valueByName('hostname'); } elsif ($selected eq 'domain') { $data->{target} = $txt->valueByName('domain'); } push @{$array}, $data; } return $array; } # Method: _formatMailExchangers # # Format the mail exchangers to write configuration settings # properly. That is, custom MX records appends a full stop after # the type value. # # Parameters: # # mailExchangers - model to iterate over # # hostName - String the host's name # id - String the row identifier # preference - Int the preference attribute # ownerDomain - if the hostname owns to the same domain. # custom - if the hostname is a foreign one # # Returns: # # Array ref of hashes containing the following keys: # # hostName # preference sub _formatMailExchangers { my ($self, $mailExchangers) = @_; my @mailExchangers; foreach my $id (@{$mailExchangers->ids()}) { my $mx = $mailExchangers->row($id); my $hostName = $mx->valueByName('hostName'); if ($mx->elementByName('hostName')->selectedType() eq 'custom') { unless ( $hostName =~ m:\.$: ) { $hostName .= '.'; } } else { $hostName = $mx->parentRow() ->subModel('hostnames') ->row($hostName) ->valueByName('hostname'); } push (@mailExchangers, { hostName => $hostName, preference => $mx->valueByName('preference') }); } return \@mailExchangers; } # Method: _formatNameServers # # Format the name servers to write configuration settings # properly. That is, custom NS records appends a full stop after # the type value. # # If it has none configured, it will configure the following: # # @ NS 127.0.0.1 # If there is no hostname named NS # @ NS ns # If there is a hostname whose name is 'ns' # # Parameters: # # nameServers - model to iterate over # # hostName - String the host's name # id - String the row identifier # ownerDomain - if the hostname owns to the same domain. # custom - if the hostname is a foreign one # # hostnames - model with hostnames for that domain # # Returns: # # Array ref of the name servers to set on # sub _formatNameServers { my ($self, $nameServers, $hostnames) = @_; my @nameservers; foreach my $id (@{$nameServers->ids()}) { my $ns = $nameServers->row($id); my $hostName = $ns->valueByName('hostName'); if ($ns->elementByName('hostName')->selectedType() eq 'custom') { unless ( $hostName =~ m:\.$: ) { $hostName .= '.'; } } else { $hostName = $ns->printableValueByName('hostName'); } push (@nameservers, $hostName); } if ( @nameservers == 0 ) { # Look for any hostname whose name is 'ns' my $matchedId = $hostnames->findId(hostname => $self->NameserverHost()); if ( defined($matchedId) ) { push(@nameservers, $self->NameserverHost()); } } return \@nameservers; } # Method: _formatTXT # # Format the TXT records to write configuration settings # properly # # Parameters: # # text - model to iterate over # # hostName - String the host's name # id - String the row identifier # txt_data - String the TXT record data # # Returns: # # Array ref of hashes containing the following keys: # # hostName # txt_data sub _formatTXT { my ($self, $txt) = @_; my @txtRecords; foreach my $id (@{$txt->ids()}) { my $row = $txt->row($id); my $hostName = $row->valueByName('hostName'); if ($row->elementByName('hostName')->selectedType() eq 'domain') { $hostName = $row->parentRow()->valueByName('domain') . '.'; } elsif ($row->elementByName('hostName')->selectedType() eq 'ownerDomain') { $hostName = $row->parentRow() ->subModel('hostnames') ->row($hostName) ->valueByName('hostname'); } else { $hostName = $row->valueByName('hostName'); } push (@txtRecords, { hostName => $hostName, txt_data => $row->valueByName('txt_data') }); } return \@txtRecords; } # Method: _formatSRV # # Format the SRV records to write configuration settings # properly # # Parameters: # # srv - model to iterate over # # service_name - String the service's name # protocol - String the protocol # name - The domain name for which this record is valid. # priority - Int the priority # weight - Int the weight # port - Int the target port # id - String the row identifier # hostName - String the target host name # # Returns: # # Array ref of hashes containing the following keys: # # service_name # protocol # name # priority # weight # target_port # target_host # sub _formatSRV { my ($self, $srv) = @_; my @srvRecords; foreach my $id (@{$srv->ids()}) { my $row = $srv->row($id); my $targetHost = $row->valueByName('hostName'); if ($row->elementByName('hostName')->selectedType() eq 'custom') { unless ( $targetHost =~ m:\.$: ) { $targetHost = $targetHost . '.'; } } else { $targetHost = $row->parentRow() ->subModel('hostnames') ->row($targetHost) ->valueByName('hostname'); } push (@srvRecords, { service_name => $row->valueByName('service_name'), protocol => $row->valueByName('protocol'), priority => $row->valueByName('priority'), weight => $row->valueByName('weight'), target_port => $row->valueByName('port'), target_host => $targetHost, }); } return \@srvRecords; } # Method: _completeDomain # # Return a structure with all required data to build bind db config files # # Parameters: # # domain - String the domain's identifier # # Returns: # # hash ref - structure data with: # # 'name': domain name # 'ipAddresses': array ref containing domain ip addresses # 'type' : the domain type (static, dynamic or dlz) # 'tsigKey' : the TSIG key if the domain is dynamic # 'hosts': an array ref returned by method. # 'mailExchangers' : an array ref returned by # 'nameServers' : an array ref returned by # 'txt' : an array ref returned by # 'srv' : an array ref returned by # sub _completeDomain # (domainId) { my ($self, $domainId) = @_; my $model = $self->model('DomainTable'); my $row = $model->row($domainId); my $domdata; $domdata->{'name'} = $row->valueByName('domain'); $domdata->{'type'} = $row->valueByName('type'); $domdata->{'tsigKey'} = $row->valueByName('tsigKey'); $domdata->{'ipAddresses'} = $self->_domainIpAddresses( $row->subModel('ipAddresses')); $domdata->{'hosts'} = $self->_hostnames( $row->subModel('hostnames')); $domdata->{'mailExchangers'} = $self->_formatMailExchangers( $row->subModel('mailExchangers')); $domdata->{'nameServers'} = $self->_formatNameServers($row->subModel('nameServers'), $row->subModel('hostnames')); $domdata->{'txt'} = $self->_formatTXT($row->subModel('txt')); $domdata->{'srv'} = $self->_formatSRV($row->subModel('srv')); # The primary name server $domdata->{'primaryNameServer'} = $self->NameserverHost(); return $domdata; } # Return the forwarders, if any sub _forwarders { my ($self) = @_; my $fwdModel = $self->model('Forwarder'); my $forwarders = []; foreach my $id (@{$fwdModel->ids()}) { push (@{$forwarders}, $fwdModel->row($id)->valueByName('forwarder')); } return $forwarders; } # Return the domain row ids in an array ref sub _domainIds { my ($self) = @_; my $model = $self->model('DomainTable'); return $model->ids(); } # Update an already created dynamic reverse zone using nsupdate sub _updateDynReverseZone { my ($self, $rdata) = @_; my $fh = new File::Temp(DIR => EBox::Config::tmp()); my $zone = $rdata->{'groupip'} . ".in-addr.arpa"; foreach my $groupItem (@{$rdata->{'domain'}}) { foreach my $host (@{$groupItem->{'hosts'}}) { print $fh 'update delete ' . $host->{'ip'} . ".$zone. PTR\n"; my $prefix = ""; $prefix = $host->{'name'} . '.' if ( $host->{'name'} ); print $fh 'update add ' . $host->{'ip'} . ".$zone. 259200 PTR $prefix" . $groupItem->{'name'} . ".\n"; } } # Send the previous commands in batch if ( $fh->tell() > 0 ) { close($fh); tie my @file, 'Tie::File', $fh->filename(); unshift(@file, "zone $zone"); push(@file, "send"); untie(@file); $self->_launchNSupdate($fh); } } # Update the dynamic direct zone sub _updateDynDirectZone { my ($self, $domData) = @_; my $zone = $domData->{'name'}; my $fh = new File::Temp(DIR => EBox::Config::tmp()); print $fh "zone $zone\n"; # Delete everything to make sure the RRs are deleted # Likewise, MX applies # We cannot do it with dhcpd like records print $fh "update delete $zone A\n"; foreach my $ip (@{$domData->{'ipAddresses'}}) { print $fh "update add $zone 259200 A " . $ip . "\n"; } # print $fh "update delete $zone NS\n"; foreach my $ns (@{$domData->{'nameServers'}}) { if ($ns !~ m:\.:g) { $ns .= ".$zone"; } print $fh "update add $zone 259200 NS $ns\n"; } my %seen = (); foreach my $host (@{$domData->{'hosts'}}) { unless ($seen{$host->{'name'}}) { # To avoid deleting same name records with different IP addresses print $fh 'update delete ' . $host->{'name'} . ".$zone A\n"; } $seen{$host->{'name'}} = 1; foreach my $ip (@{$host->{ip}}) { print $fh 'update add ' . $host->{'name'} . ".$zone 259200 A $ip\n"; } foreach my $alias (@{$host->{'aliases'}}) { print $fh 'update delete ' . $alias . ".$zone CNAME\n"; print $fh 'update add ' . $alias . ".$zone 259200 CNAME " . $host->{'name'} . ".$zone\n"; } } print $fh "update delete $zone MX\n"; foreach my $mxRR ( @{$domData->{'mailExchangers'}} ) { my $mx = $mxRR->{'hostName'}; if ( $mx !~ m:\.:g ) { $mx .= ".$zone"; } print $fh "update add $zone 259200 MX " . $mxRR->{'preference'} . " $mx\n"; } foreach my $txtRR ( @{$domData->{'txt'}} ) { my $txt = $txtRR->{'hostName'}; if ( $txt !~ m:\.:g ) { $txt .= ".$zone"; } print $fh "update add $txt 259200 TXT " . $txtRR->{'txt_data'} . "\n"; } foreach my $srvRR ( @{$domData->{'srv'}} ) { if ( $srvRR->{'target_host'} !~ m:\.:g ) { $srvRR->{'target_host'} .= ".$zone"; } print $fh 'update add _' . $srvRR->{'service_name'} . '._' . $srvRR->{'protocol'} . ".${zone}. 259200 SRV " . $srvRR->{'priority'} . ' ' . $srvRR->{'weight'} . ' ' . $srvRR->{'target_port'} . ' ' . $srvRR->{'target_host'} . "\n"; } print $fh "send\n"; $self->_launchNSupdate($fh); } # Remove no longer available RR in dynamic zones sub _removeDeletedRR { my ($self) = @_; my $deletedRRs = $self->st_get_list(DELETED_RR_KEY); my $fh = new File::Temp(DIR => EBox::Config::tmp()); foreach my $rr (@{$deletedRRs}) { print $fh "update delete $rr\n"; } if ( $fh->tell() > 0 ) { print $fh "send\n"; $self->_launchNSupdate($fh); $self->st_unset(DELETED_RR_KEY); } } # Send the nsupdate command or defer to the postservice hook sub _launchNSupdate { my ($self, $fh) = @_; my $cmd = NS_UPDATE_CMD . ' -l -t 10 ' . $fh->filename(); if ( $self->_isNamedListening() ) { try { EBox::Sudo::root($cmd); } otherwise { $fh->unlink_on_destroy(0); # For debug purposes }; } else { $self->{nsupdateCmds} = [] unless exists $self->{nsupdateCmds}; push(@{$self->{nsupdateCmds}}, $cmd); $fh->unlink_on_destroy(0); EBox::warn('Cannot contact with named, trying in posthook'); } } # Check if named is listening sub _isNamedListening { my ($self) = @_; my $sock = new IO::Socket::INET(PeerAddr => '127.0.0.1', PeerPort => 53, Proto => 'tcp'); if ( $sock ) { close($sock); return 1; } else { return 0; } } # Remove no longer used domain files to avoid confusing the user sub _removeDomainsFiles { my ($self) = @_; return if ($self->isReadOnly()); my $oldList = $self->st_get_list('domain_files'); my $newList = []; my $domainModel = $self->model('DomainTable'); foreach my $id (@{$domainModel->ids()}) { my $row = $domainModel->row($id); my $file; if ($row->valueByName('type') ne STATIC_ZONE) { $file = BIND9_UPDATE_ZONES; } else { $file = BIND9CONFDIR; } $file .= "/db." . $row->valueByName('domain'); push (@{$newList}, $file); } $self->_removeDisjuncFiles($oldList, $newList); $self->st_set_list('domain_files', 'string', $newList); } # Remove no longer used reverse zone files sub _removeUnusedReverseFiles { my ($self, $reversedData) = @_; return if ($self->isReadOnly()); my $oldList = $self->st_get_list('inarpa_files'); my $newList = []; foreach my $group (keys $reversedData) { my $reversedDataItem = $reversedData->{$group}; my $file; if ($reversedDataItem->{'type'} ne STATIC_ZONE) { $file = BIND9_UPDATE_ZONES; } else { $file = BIND9CONFDIR; } $file .= "/db." . $group; push (@{$newList}, $file); } $self->_removeDisjuncFiles($oldList, $newList); $self->st_set_list('inarpa_files', 'string', $newList); } # Delete files from disjunction sub _removeDisjuncFiles { my ($self, $oldList, $newList) = @_; my %newSet = map { $_ => 1 } @{$newList}; # Show the elements in @oldList which are not in %newSet my @disjunc = grep { not exists $newSet{$_} } @{$oldList}; foreach my $file (@disjunc) { if (-f $file) { EBox::Sudo::root("rm -rf '$file'"); } # Remove the jnl if exists as well (only applicable for dyn zones) if (-f "${file}.jnl") { EBox::Sudo::root("rm -rf '${file}.jnl'"); } } } # Set configuration for transparent DNS cache # TODO: Move FirewallHelper to core to avoid this implementation here without # using the framework sub _setTransparentCache { my ($self) = @_; if ( $self->model('Settings')->row()->valueByName('transparent') ) { # The transparent cache DNS setting is enabled my $gl = EBox::Global->getInstance(1); if ( $gl->modExists('firewall') ) { my $fw = $gl->modInstance('firewall'); if ( $fw->isEnabled() ) { my @rules = (); my $net = $gl->modInstance('network'); eval 'use EBox::FirewallHelper;'; my $fwHelper = new EBox::FirewallHelper(); foreach my $iface (@{$net->InternalIfaces()}) { my $addrs = $net->ifaceAddresses($iface); my $input = $fwHelper->_inputIface($iface); foreach my $addr ( map { $_->{address} } @{$addrs} ) { next unless ( defined($addr) and ($addr ne "")); my $rule = "-t nat -A premodules $input " . "! -d $addr -p tcp --dport " . DNS_PORT . ' -j REDIRECT --to-ports ' . DNS_PORT; push(@rules, $rule); $rule = "-t nat -A premodules $input " . "! -d $addr -p udp --dport " . DNS_PORT . ' -j REDIRECT --to-ports ' . DNS_PORT; push(@rules, $rule); } } my @cmds = map { '/sbin/iptables ' . $_ } @rules; EBox::Sudo::root(@cmds); } } } } # Method: addAlias # # Parameters: # - domain # - hostname # - alias: can be a string or a list of string to add more then one alias # # Warning: # alias is added to the first found matching hostname sub addAlias { my ($self, $domain, $hostname, $alias) = @_; $domain or throw EBox::Exceptions::MissingArgument('domain'); my $domainModel = $self->model('DomainTable'); $domainModel->addHostAlias($domain, $hostname, $alias); } # Method: removeAlias # # Remove alias for the doamin and hostname. If there are several hostnames the # alias is removed in all of them # # Parameters: # - domain # - hostname # - alias # # Note: # we implement this because vhosttable does not allow exposed method sub removeAlias { my ($self, $domain, $hostname, $alias) = @_; $domain or throw EBox::Exceptions::MissingArgument('domain'); $hostname or throw EBox::Exceptions::MissingArgument('hostname'); $alias or throw EBox::Exceptions::MissingArgument('alias'); my $domainModel = $self->model('DomainTable'); my $domainRow; foreach my $id (@{ $domainModel->ids() }) { my $row = $domainModel->row($id); if ($row->valueByName('domain') eq $domain) { $domainRow = $row; last; } } if (not $domainRow) { throw EBox::Exceptions::DataNotFound( data => __('domain'), value => $domain ); } my $hostnamesModel = $domainRow->subModel('hostnames'); my $hostnameFound; my $aliasFound; foreach my $id (@{ $hostnamesModel->ids() }) { my $row = $hostnamesModel->row($id); if ($row->valueByName('hostname') eq $hostname) { $hostnameFound = 1; my $aliasModel = $row->subModel('alias'); foreach my $aliasId (@{ $aliasModel->ids() } ) { my $row = $aliasModel->row($aliasId); if ($row->valueByName('alias') eq $alias) { $aliasFound = 1; $aliasModel->removeRow($aliasId); last; } } } } if (not $hostnameFound) { throw EBox::Exceptions::DataNotFound( data => __('hostname'), value => $hostname ); }elsif (not $aliasFound) { throw EBox::Exceptions::DataNotFound( data => __('alias'), value => $alias ); } } sub firewallHelper { my ($self) = @_; if ($self->isEnabled()) { return EBox::DNS::FirewallHelper->new(); } return undef; } # Get the ranges for the given domain if used by DHCP module sub _getRanges { my ($self, $domainData) = @_; my @ranges = (); my $dhcp = EBox::Global->modInstance('dhcp'); my $net = EBox::Global->modInstance('network'); return \@ranges unless (defined($dhcp)); foreach my $iface (grep { $net->ifaceMethod($_) eq 'static'} @{$net->allIfaces()}) { my $dynDNSRow = $dhcp->dynamicDNSDomains($iface); my @domains = ( $dynDNSRow->printableValueByName('dynamic_domain') ); if ( $dynDNSRow->valueByName('static_domain') ne 'same' ) { push(@domains, $dynDNSRow->printableValueByName('static_domain')); } if ( $domainData->{'name'} eq any(@domains) ) { my $initRange = $dhcp->initRange($iface); $initRange =~ s/1$/0/; my $endRange = $dhcp->endRange($iface); my $ip = new Net::IP("$initRange - $endRange"); do { my $rev = Net::IP->new($ip->ip())->reverse_ip(); if ( defined($rev) ) { # It returns 0.netaddr.in-addr.arpa so we need to remove it # to make it compilant with bind zone definition $rev =~ s/^0\.//; $rev =~ s:\.in-addr\.arpa\.::; push(@ranges, $rev); } } while ($ip += 256); } } return \@ranges; } # Method: switchToReverseInfoData # # Return a structure with all necessary data to build reverse db config # files. # # Parameters: # # array ref - structure returned by # # Returns: # # array ref structure data with: # # 'groupip': ip range to define a zone file info # 'dynamic': boolean indicating if the zone is dynamic # 'tsigKeyName' : String indicating the name of the TSIG key for # being updated if the domain is dynamic # 'domain': an array of hosts and domain data: # 'name': domain name # 'hosts': an array of hostnames and hostip: # 'ip': less significant block of an ip address # 'name': name of the host in the domain # sub switchToReverseInfoData { my ($self, $domains) = @_; my $reversedData = {}; foreach my $domain (@{$domains}) { foreach my $host (@{$domain->{'hosts'}}) { # Remove wildcard since it is possible to set a reverse domain next if ($host->{'name'} eq '*'); foreach my $hostIp (@{$host->{'ip'}}) { my @ipblocks = split (/\./, $hostIp); my $groupip = join ('.', $ipblocks[2], $ipblocks[1], $ipblocks[0]); my $ip = $ipblocks[3]; if (exists $reversedData->{$groupip}) { my $d = $reversedData->{$groupip}->{domain}; my $d2 = $domain->{name}; EBox::warn("Domain '$d' already mapped to IP group '$groupip', domain $d2 skipped"); } else { $reversedData->{$groupip} = { type => $domain->{type}, domain => $domain->{name}, hosts => [], ns => [], soa => $domain->{primaryNameServer}, tsigKeyName => $domain->{name}, }; foreach my $ns (@{$domain->{nameServers}}) { push ($reversedData->{$groupip}->{ns}, $ns); } my $hostData = { ip => $ip, name => $host->{'name'}}; push (@{$reversedData->{$groupip}->{hosts}}, $hostData); } } } } return $reversedData; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Types/0000775000000000000000000000000012017140137015203 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/Types/Hostname.pm0000664000000000000000000000474312017140137017327 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the hostname as a valid domain or the wildcard for default value # package EBox::DNS::Types::Hostname; use base 'EBox::Types::DomainName'; use strict; use warnings; use EBox::Gettext; # Group: Public methods # Constructor: new # # The constructor for the # # Returns: # # the recently created object # sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{'type'} = 'hostname'; $self->{'allowUnsafeChars'} = 1; $self->{'help'} = __('A valid domain name or a wildcard (*) value ' . 'must be provided.'); bless($self, $class); return $self; } # Method: cmp # # Overrides: # # # sub cmp { my ($self, $compareType) = @_; unless ($self->isa(ref $compareType)) { return undef; } return uc($self->value()) cmp uc($compareType->value()); } # Group: Protected methods # Method: _paramIsValid # # Check if the params has a correct domain name or the wildcard # # Overrides: # # # # Parameters: # # params - the HTTP parameters with contained the type # # Returns: # # true - if the parameter is a correct hostname in named domain # # Exceptions: # # - throw if it's not a correct # host # sub _paramIsValid { my ($self, $params) = @_; my $value = $params->{$self->fieldName()}; if (defined ( $value )) { if ( $value eq '*' ) { return 1; } else { $self->SUPER::_paramIsValid($params); } } return 1; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/DNS/0000775000000000000000000000000012017140137014523 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/DNS/FirewallHelper.pm0000664000000000000000000000171612017140137017773 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::DNS::FirewallHelper; use base 'EBox::FirewallHelper'; sub output { my ($self) = @_; my @rules; push (@rules, '--protocol udp --dport 53 -j ACCEPT'); push (@rules, '--protocol tcp --dport 53 -j ACCEPT'); return \@rules; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/0000775000000000000000000000000012017140137015137 5ustar zentyal-dns-2.3.10+quantal1/src/EBox/Model/Settings.pm0000664000000000000000000000472512017140137017305 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the form which consists of general settings for DNS # server. The fields are the following ones: # # - transparent # package EBox::DNS::Model::Settings; use base 'EBox::Model::DataForm'; use strict; use warnings; use EBox::Global; use EBox::Gettext; use EBox::Types::Boolean; # Group: Public methods # Constructor: new # # Create a new Text model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my $gl = EBox::Global->getInstance(); my $fwEnabled = 0; if ( $gl->modExists('firewall') ) { $fwEnabled = $gl->modInstance('firewall')->isEnabled(); } my @tableDesc = ( new EBox::Types::Boolean( fieldName => 'transparent', printableName => __('Enable transparent DNS cache'), editable => $fwEnabled, unique => 1, ), ); my $dataTable = { tableName => 'Settings', printableTableName => __('Settings'), modelDomain => 'DNS', defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableDesc, messages => { update => __('Settings changed') }, help => __('Every DNS query will be redirected to local ' . 'DNS server if transparent mode is enabled.'), }; return $dataTable; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/NameServer.pm0000664000000000000000000002105312017140137017545 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the object table which contains the nameservers for a domain, that # is, its NS records . A member of # package EBox::DNS::Model::NameServer; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Global; use EBox::Gettext; use EBox::Types::DomainName; use EBox::Types::Select; use EBox::Types::Union; # Group: Public methods # Constructor: new # # Create a new NameServer model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } # Method: validateTypedRow # # Check the given custom name is a Fully Qualified Domain Name (FQDN) # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; return unless exists $changedFields->{hostName}; if ( $changedFields->{hostName}->selectedType() eq 'custom' ) { my $val = $changedFields->{hostName}->value(); my @parts = split(/\./, $val); unless ( @parts > 2 ) { throw EBox::Exceptions::External(__x('The given host name ' . 'is not a fully qualified domain name (FQDN). ' . 'Do you mean ns.{name}?', name => $val)); } # Check the given custom nameserver is a CNAME record from the # same zone my $zoneRow = $self->parentRow(); my $zone = $zoneRow->valueByName('domain'); my $customZone = join('.', @parts[1 .. $#parts]); if ( $zone eq $customZone ) { # Use ownerDomain to set the nameserver throw EBox::Exceptions::External(__('A custom host name cannot be set ' . 'from the same domain. Use ' . '"This domain" option instead')); } } if ($action eq 'update') { # Add toDelete the RRs for this nameserver my $oldRow = $self->row($changedFields->{id}); my $zoneRow = $oldRow->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $ns = $oldRow->printableValueByName('hostName'); if ( $ns !~ m:\.:g ) { $ns = "$ns.$zone"; } $self->{toDelete} = "$zone NS $ns"; } } } # Method: updatedRowNotify # # Override to add to the list of removed of RRs # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; # The field is added in validateTypedRow if (exists $self->{toDelete}) { $self->_addToDelete($self->{toDelete}); delete $self->{toDelete}; } } # Method: deletedRowNotify # # Overrides to add to the list of deleted RR in dynamic zones # # Overrides: # # # sub deletedRowNotify { my ($self, $row) = @_; my $zoneRow = $row->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $ns = $row->printableValueByName('hostName'); if ( $ns !~ m:\.:g ) { $ns = "$ns.$zone"; } $self->_addToDelete("$zone NS $ns"); } } # Method: removeRow # # Overrides not to allow delete a row if only one element is left # # Overrides: # # # sub removeRow { my ($self, $id, $force) = @_; # Check there is at least a row my $ids = $self->ids(); if ( scalar(@{$ids}) == 1 ) { # Last element to remove throw EBox::Exceptions::External(__('Last name server cannot be removed')); } return $self->SUPER::removeRow($id, $force); } # Method: precondition # # Overrides: # # # sub precondition { my ($self) = @_; if ( $self->parentRow()->readOnly() ) { return 0; } return 1; } # Method: preconditionFailMsg # # Overrides: # # # sub preconditionFailMsg { return __('The domain is set as read only. You cannot add name servers'); } # Method: pageTitle # # Overrides: # # # sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('domain'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::Union( fieldName => 'hostName', printableName => __('Host name'), editable => 1, unique => 1, help => __('If you choose "Custom", ' . 'it should be a Fully Qualified Domain Name'), subtypes => [ new EBox::Types::Select( fieldName => 'ownerDomain', printableName => __('This domain'), foreignModel => \&_hostnameModel, foreignField => 'hostname', editable => 1, unique => 1, ), new EBox::Types::DomainName( fieldName => 'custom', printableName => __('Custom'), editable => 1, unique => 1, ), ], ), ); my $dataTable = { tableName => 'NameServer', printableTableName => __('Name servers'), automaticRemove => 1, modelDomain => 'DNS', defaultActions => ['add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __('It manages the name server (NS) records for this domain'), printableRowName => __('name server record'), order => 1, insertPosition => 'back', }; return $dataTable; } # Group: Private methods # Get the hostname model from DNS module sub _hostnameModel { my ($type) = @_; # FIXME: We cannot use API until the bug in parent deep recursion is fixed # my $parentRow = $type->model()->parentRow(); # if ( defined($parentRow) ) { # return $parentRow->subModel('hostnames'); # } else { # Bug in initialisation code of ModelManager my $model = EBox::Global->modInstance('dns')->model('HostnameTable'); my $dir = $type->model()->directory(); $dir =~ s:nameServers:hostnames:g; $model->setDirectory($dir); return $model; # } } # Add the RR to the deleted list sub _addToDelete { my ($self, $rr) = @_; my $mod = $self->{confmodule}; my $key = EBox::DNS::DELETED_RR_KEY(); my @list = (); if ( $mod->st_entry_exists($key) ) { @list = @{$mod->st_get_list($key)}; } push(@list, $rr); $mod->st_set_list($key, 'string', \@list); } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/HostIpTable.pm0000664000000000000000000000725212017140137017661 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::HostIpTable # # This class inherits from and represents the # object table which basically contains domains names and a reference # to a member # # package EBox::DNS::Model::HostIpTable; use EBox::Global; use EBox::Gettext; use EBox::Types::HostIP; use EBox::Sudo; use strict; use warnings; use base 'EBox::Model::DataTable'; # Group: Public methods sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless ($self, $class); return $self; } # Method: validateTypedRow # # Overrides: # # # # Exceptions: # # - thrown if there is a hostname with # the same ip # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; return unless (exists $changedFields->{ip}); # Check there is no A RR in the same domain with the same ip my $ip = $changedFields->{ip}; my $id = $ip->row()->id(); my $hostnameRow = $ip->row(); my $hostnameParentRow = $hostnameRow->parentRow(); my $hostnameModel = $hostnameParentRow->model(); my $hostnameIds = $hostnameModel->ids(); foreach my $hostId (@{$hostnameIds}) { next if ($hostId eq $id); my $hostname = $ip->row()->parentRow()->model()->row($hostId); my $hostIpModel = $hostname->subModel('ipAddresses'); foreach my $ipId (@{$hostIpModel->ids()}) { my $aIp = $hostIpModel->row($ipId); if ($aIp->elementByName('ip')->isEqualTo($ip)) { throw EBox::Exceptions::External( __x("The IP '{ip}' is already assigned to host '{name}' " . "in the same domain", name => $hostname->valueByName('hostname'), ip => $ip->value())); } } } } sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('hostname'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my @tableHead = (new EBox::Types::HostIP( fieldName => 'ip', printableName => __('IP'), size => '20', unique => 1, editable => 1 )); my $dataTable = { tableName => 'HostIpTable', printableTableName => __('IP'), automaticRemove => 1, defaultController => '/Dns/Controller/HostIpTable', defaultActions => ['add', 'del', 'editField', 'changeView'], tableDescription => \@tableHead, class => 'dataTable', help => __('The host name will be resolved to this list of IP addresses.'), printableRowName => __('IP') }; return $dataTable; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/AliasTable.pm0000664000000000000000000001471212017140137017503 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::AliasTable # # This class inherits from and represents the # object table which basically contains domains names and a reference # to a member # # package EBox::DNS::Model::AliasTable; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Exceptions::DataExists; use EBox::Types::DomainName; use EBox::Sudo; use Net::IP; use strict; use warnings; use base 'EBox::Model::DataTable'; # Group: Public methods sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } # Method: validateTypedRow # # Overrides: # # # # Exceptions: # # - thrown if there is a hostname with # the same name of this added/edited alias within the same domain # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; return unless ( exists $changedFields->{alias} ); my $alias = $changedFields->{alias}; my $olddir = $alias->model()->directory(); # Check it is not the nameserver hostname my $dnsMod = EBox::Global->modInstance('dns'); my $newAlias = $alias->value(); if (uc($newAlias) eq uc($dnsMod->NameserverHost())) { throw EBox::Exceptions::External( __x('An alias cannot be the nameserver host name "{ns}". ' . 'Use a hostname instead', ns => $dnsMod->NameserverHost())); } # Check there is no A RR in the domain with the same name my $domain = $alias->row()->parentRow()->parentRow()->valueByName('domain'); my $hostnameIds = $alias->row()->parentRow()->model()->ids(); foreach my $hostId (@{$hostnameIds}) { my $hostname = $alias->row()->parentRow()->model()->row($hostId); if ($hostname->elementByName('hostname')->isEqualTo($alias)) { throw EBox::Exceptions::External( __x('There is a hostname with the same name "{name}" ' . 'in the same domain', name => $hostname->valueByName('hostname'))); } foreach my $aliasId (@{$hostname->subModel('alias')->ids()}) { my $anAlias = $hostname->subModel('alias')->row($aliasId); next if ($aliasId eq $alias->row()->id()); if ($anAlias->elementByName('alias')->isEqualTo($alias)) { throw EBox::Exceptions::External( __x('There is an alias for {hostname} hostname ' . 'with the same name "{name}" ' . 'in the same domain', hostname => $hostname->valueByName('hostname'), name => $anAlias->valueByName('alias'))); } } } $self->setDirectory($olddir); if ( $action eq 'update' ) { my $oldRow = $self->row($changedFields->{id}); my $zoneRow = $oldRow->parentRow()->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $alias = $oldRow->valueByName('alias'); $self->{toDelete} = "$alias.$zone"; } } } # Method: updatedRowNotify # # Override to add to the list of removed of RRs # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; # The field is added in validateTypedRow if (exists $self->{toDelete}) { $self->_addToDelete($self->{toDelete}); delete $self->{toDelete}; } } # Method: deletedRowNotify # # Overrides to add to the list of deleted RR in dynamic zones # # Overrides: # # # sub deletedRowNotify { my ($self, $row) = @_; # Deleted RRs to account my $zoneRow = $row->parentRow()->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); # Delete all aliases $self->_addToDelete( $row->valueByName('alias') . ".$zone"); } } sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('hostname'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my @tableHead = ( new EBox::Types::DomainName ( 'fieldName' => 'alias', 'printableName' => __('Alias'), 'size' => '20', 'unique' => 1, 'editable' => 1 ) ); my $dataTable = { 'tableName' => 'AliasTable', 'printableTableName' => __('Alias'), 'automaticRemove' => 1, 'defaultController' => '/Dns/Controller/AliasTable', 'defaultActions' => ['add', 'del', 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'class' => 'dataTable', 'help' => __("This is the list of host name aliases. All of them will be resolved to the host's IP addresses list."), 'printableRowName' => __('alias'), 'sortedBy' => 'alias', }; return $dataTable; } # Group: Private methods # Add to the list of deleted RRs sub _addToDelete { my ($self, $domain) = @_; my $mod = $self->{confmodule}; my $key = EBox::DNS::DELETED_RR_KEY(); my @list = (); if ( $mod->st_entry_exists($key) ) { @list = @{$mod->st_get_list($key)}; } push(@list, $domain); $mod->st_set_list($key, 'string', \@list); } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/Text.pm0000664000000000000000000001436312017140137016430 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the object table which contains the free based TXT records for a domain # package EBox::DNS::Model::Text; use base 'EBox::DNS::Model::Record'; use strict; use warnings; use EBox::Exceptions::External; use EBox::Global; use EBox::Gettext; use EBox::Types::Text; use EBox::Types::Select; use EBox::Types::Union; use EBox::Types::Union::Text; # Group: Public methods # Constructor: new # # Create a new Text model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } # Method: validateTypedRow # # Check the given custom name is a Fully Qualified Domain Name (FQDN) # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; if ( exists $changedFields->{txt_data} ) { my $val = $changedFields->{txt_data}->value(); # See RFC 4408 for details if ( length($val) >= 450 ) { throw EBox::Exceptions::External( __x('The {name} cannot be longer than {value} characters', name => $changedFields->{txt_data}->printableName(), value => 450)); } } if ( $action eq 'update' ) { # Add toDelete the RRs for this TXT record my $oldRow = $self->row($changedFields->{id}); my $zoneRow = $oldRow->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $hostname = $allFields->{hostName}; my $record = ''; if ( $hostname->selectedType() eq 'domain' ) { $record = $zone; } else { $record = $hostname->printableValueByName('hostName'); $record = "$record.$zone"; } $self->{toDelete} = "$record TXT"; } } } # Method: deletedRowNotify # # Overrides to add to the list of deleted RR in dynamic zones # # Overrides: # # # sub deletedRowNotify { my ($self, $row) = @_; my $zoneRow = $row->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $hostname = $row->elementByName('hostName'); my $record = ''; if ( $hostname->selectedType() eq 'domain' ) { $record = $zone; } else { $record = $hostname->printableValue('hostName'); $record = "$record.$zone"; } $self->_addToDelete("$record TXT"); } } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::Union( fieldName => 'hostName', printableName => __('Host name'), editable => 1, help => __('If you select the Domain, then you are ' . 'choosing the zone'), subtypes => [ new EBox::Types::Select( fieldName => 'ownerDomain', printableName => __('This domain'), foreignModel => \&_hostnameModel, foreignField => 'hostname', editable => 1, ), new EBox::Types::Union::Text( fieldName => 'domain', printableName => __('Domain'), ), new EBox::Types::Text( fieldName => 'custom', printableName => __('Custom owner'), editable => 1, ), ], ), new EBox::Types::Text( fieldName => 'txt_data', printableName => __x('{txt} data', txt => 'TXT'), editable => 1, help => __('Any data could be provided'), allowUnsafeChars => 1, ), ); my $dataTable = { tableName => 'Text', printableTableName => __x('{txt} records', txt => 'TXT'), automaticRemove => 1, modelDomain => 'DNS', defaultActions => ['add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __('It manages the TXT records for this domain. They are useful to in SPF or DKIM antispam protocols'), printableRowName => __x('{txt} record', txt => 'TXT'), }; return $dataTable; } # Group: Private methods # Get the hostname model from DNS module sub _hostnameModel { my ($type) = @_; # FIXME: We cannot use API until the bug in parent deep recursion is fixed # my $parentRow = $type->model()->parentRow(); # if ( defined($parentRow) ) { # return $parentRow->subModel('hostnames'); # } else { # Bug in initialisation code of ModelManager my $model = EBox::Global->modInstance('dns')->model('HostnameTable'); my $dir = $type->model()->directory(); $dir =~ s:txt:hostnames:g; $model->setDirectory($dir); return $model; # } } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/HostnameTable.pm0000664000000000000000000002176512017140137020236 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::HostnameTable # # This class inherits from and represents # the host names (A resource records) in a domain and a set of alias # described in # package EBox::DNS::Model::HostnameTable; use EBox::DNS::Types::Hostname; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Exceptions::DataExists; use EBox::Model::Manager; use EBox::Types::DomainName; use EBox::Types::HasMany; use EBox::Types::HostIP; use EBox::Sudo; use EBox::Model::Manager; use Net::IP; use strict; use warnings; use base 'EBox::Model::DataTable'; # Group: Public methods sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless ($self, $class); return $self; } # Method: validateTypedRow # # Overrides: # # # # Exceptions: # # - thrown if there is an alias with # the same name for other hostname within the same domain # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; return unless (exists $changedFields->{hostname}); my $newHostName = $changedFields->{hostname}; my $domainModel = $newHostName->row()->model(); for my $id (@{$domainModel->ids()}) { my $row = $domainModel->row($id); # Check there is no CNAME RR in the domain with the same name for my $id (@{$row->subModel('alias')->ids()}) { my $subRow = $row->subModel('alias')->row($id); if ($newHostName->isEqualTo($subRow->elementByName('alias'))) { throw EBox::Exceptions::External( __x('There is an alias with the same name "{name}" ' . 'for "{hostname}" in the same domain', name => $subRow->valueByName('alias'), hostname => $row->valueByName('hostname'))); } } } if ( $action eq 'update' ) { # Add toDelete the RRs for this hostname and its aliases my $oldRow = $self->row($changedFields->{id}); my $zoneRow = $oldRow->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my @toDelete = (); my $zone = $zoneRow->valueByName('domain'); # Delete all aliases my $aliasModel = $oldRow->subModel('alias'); my $ids = $aliasModel->ids(); foreach my $id (@{$ids}) { my $aliasRow = $aliasModel->row($id); push(@toDelete, $aliasRow->valueByName('alias') . ".$zone"); } my $fullHostname = $oldRow->valueByName('hostname') . ".$zone"; push(@toDelete, $fullHostname); $self->{toDelete} = \@toDelete; } } } # Method: updatedRowNotify # # Override to add to the list of removed of RRs # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; # The field is added in validateTypedRow if (exists $self->{toDelete}) { foreach my $rr (@{$self->{toDelete}}) { $self->_addToDelete($rr); } delete $self->{toDelete}; } } # Method: removeRow # # Override not to allow to remove the last NS record if this row # points to this record # # Overrides: # # # sub removeRow { my ($self, $id, $force) = @_; if ( $force and $self->table()->{automaticRemove} ) { # Trying to remove the pointed elements first my $manager = EBox::Model::Manager->instance(); $manager->removeRowsUsingId($self->contextName(), $id); } return $self->SUPER::removeRow($id, $force); } # Method: precondition # # Overrides: # # # sub precondition { my ($self) = @_; if ( $self->parentRow()->readOnly() ) { return 0; } return 1; } # Method: preconditionFailMsg # # Overrides: # # # sub preconditionFailMsg { return __('The domain is set as read only. You cannot add host names'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my @tableHead = ( new EBox::DNS::Types::Hostname ( 'fieldName' => 'hostname', 'printableName' => __('Host name'), 'size' => '20', 'unique' => 1, 'editable' => 1, ), new EBox::Types::HasMany ( 'fieldName' => 'ipAddresses', 'printableName' => __('IP Address'), 'foreignModel' => 'HostIpTable', 'view' => '/DNS/View/HostIpTable', 'backView' => '/DNS/View/HostIpTable', 'size' => '1', ), new EBox::Types::HasMany ( 'fieldName' => 'alias', 'printableName' => __('Alias'), 'foreignModel' => 'AliasTable', 'view' => '/DNS/View/AliasTable', 'backView' => '/DNS/View/AliasTable', 'size' => '1', ) ); my $dataTable = { tableName => 'HostnameTable', printableTableName => __('Host names'), automaticRemove => 1, modelDomain => 'DNS', defaultActions => ['add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableHead, class => 'dataTable', help => __('Automatic reverse resolution is done. If you ' . 'repeat an IP address in another domain, only ' . 'first match will be used by reverse resolution. ' . 'Dynamic zones may erase your manual reverse ' . 'resolution.'), printableRowName => __('host name'), order => 1, insertPosition => 'back', }; return $dataTable; } # Method: deletedRowNotify # # Overrides to remove mail exchangers referencing the deleted # host name and add to the list of deleted RR in dynamic zones # # Overrides: # # # sub deletedRowNotify { my ($self, $row) = @_; # Delete the associated MX RR my $mailExModel = $row->parentRow()->subModel('mailExchangers'); for my $id(@{$mailExModel->ids()}) { my $mailRow = $mailExModel->row($id); my $hostname = $mailRow->elementByName('hostName'); next unless ($hostname->selectedType() eq 'ownerDomain'); if ($hostname->value() eq $row->id()) { $mailExModel->removeRow($mailRow->id()); } } # Deleted RRs to account my $zoneRow = $row->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); # Delete all aliases my $aliasModel = $row->subModel('alias'); my $ids = $aliasModel->ids(); foreach my $id (@{$ids}) { my $aliasRow = $aliasModel->row($id); $self->_addToDelete( $aliasRow->valueByName('alias') . ".$zone"); } my $fullHostname = $row->valueByName('hostname') . ".$zone"; $self->_addToDelete($fullHostname); } } # Method: pageTitle # # Overrides # to show the name of the domain sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('domain'); } # Group: Private methods # Add the RR to the deleted list sub _addToDelete { my ($self, $domain) = @_; my $mod = $self->{confmodule}; my $key = EBox::DNS::DELETED_RR_KEY(); my @list = (); if ( $mod->st_entry_exists($key) ) { @list = @{$mod->st_get_list($key)}; } push (@list, $domain); $mod->st_set_list($key, 'string', \@list); } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/Record.pm0000664000000000000000000000506012017140137016714 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the record with the common methods used by several records in DNS # package EBox::DNS::Model::Record; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Exceptions::NotImplemented; # Method: updatedRowNotify # # Override to add to the list of removed of RRs # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; # The field is added in validateTypedRow if (exists $self->{toDelete}) { $self->_addToDelete($self->{toDelete}); delete $self->{toDelete}; } } # Method: precondition # # Overrides: # # # sub precondition { my ($self) = @_; if ( $self->parentRow()->readOnly() ) { return 0; } return 1; } # Method: preconditionFailMsg # # Overrides: # # # sub preconditionFailMsg { my ($self) = @_; return __x('The domain is set as read only. You cannot add {what}', what => $self->printableName()); } # Method: pageTitle # # Overrides: # # # sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('domain'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { throws EBox::Exceptions::NotImplemented(); } # Group: Private methods # Add the RR to the deleted list sub _addToDelete { my ($self, $rr) = @_; my $mod = $self->{confmodule}; my $key = EBox::DNS::DELETED_RR_KEY(); my @list = (); if ( $mod->st_entry_exists($key) ) { @list = @{$mod->st_get_list($key)}; } push(@list, $rr); $mod->st_set_list($key, 'string', \@list); } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/DomainIpTable.pm0000664000000000000000000000447012017140137020152 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::DomainIpTable # package EBox::DNS::Model::DomainIpTable; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Exceptions::DataExists; use EBox::Types::HostIP; use EBox::Sudo; use strict; use warnings; use base 'EBox::Model::DataTable'; # Group: Public methods sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless ($self, $class); return $self; } sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('domain'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my @tableHead = (new EBox::Types::HostIP( fieldName => 'ip', printableName => __('IP'), size => '20', unique => 1, editable => 1 )); my $dataTable = { tableName => 'DomainIpTable', printableTableName => __('IP'), automaticRemove => 1, defaultController => '/Dns/Controller/DomainIpTable', defaultActions => ['add', 'del', 'editField', 'changeView' ], tableDescription => \@tableHead, class => 'dataTable', printableRowName => __('IP'), sortedBy => 'ip', help => __('The domain name will be resolved to this list of IP addresses.') }; return $dataTable; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/Services.pm0000664000000000000000000002400312017140137017257 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the object table which contains the free based TXT records for a domain # package EBox::DNS::Model::Services; use base 'EBox::DNS::Model::Record'; use strict; use warnings; use EBox::Exceptions::External; use EBox::Global; use EBox::Gettext; use EBox::Types::Composite; use EBox::Types::Int; use EBox::Types::Port; use EBox::Types::Text; use EBox::Types::Select; use EBox::Types::Union; use File::Slurp; # Constants use constant SERVICE_FILE => '/etc/services'; # Group: Public methods # Constructor: new # # Create a new Services model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless ($self, $class); return $self; } # Method: validateTypedRow # # Check the given custom name is a Fully Qualified Domain Name (FQDN) # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; $self->checkService($changedFields, $allFields); $self->checkHostname($changedFields, $allFields); if ($action eq 'update') { # Add toDelete the RRs for this SRV record my $oldRow = $self->row($changedFields->{id}); my $zoneRow = $oldRow->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { my $zone = $zoneRow->valueByName('domain'); my $srvName = $oldRow->valueByName('service_name'); my $protocol = $oldRow->valueByName('protocol'); $self->{toDelete} = "_${srvName}._${protocol}.${zone}. SRV"; } } } # Method: deletedRowNotify # # Overrides to add to the list of deleted RR in dynamic zones # # Overrides: # # # sub deletedRowNotify { my ($self, $row) = @_; my $zoneRow = $row->parentRow(); if ($zoneRow->valueByName('type') ne EBox::DNS::STATIC_ZONE()) { # Add toDelete the RRs for this SRV record my $zone = $zoneRow->valueByName('domain'); my $srvName = $row->valueByName('service_name'); my $protocol = $row->valueByName('protocol'); $self->{toDelete} = "_${srvName}._${protocol}.${zone}. SRV"; } } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::Text( fieldName => 'service_name', printableName => __('Service name'), editable => 1, ), new EBox::Types::Select( fieldName => 'protocol', printableName => __('Protocol'), populate => \&_protocols, editable => 1, ), new EBox::Types::Int( fieldName => 'priority', printableName => __('Priority'), min => 0, max => 65535, defaultValue => 0, editable => 1, help => __('Lower value is greater priority'), ), new EBox::Types::Int( fieldName => 'weight', printableName => __('Weight'), min => 0, max => 65535, defaultValue => 0, editable => 1, help => __('0 indicates no weighting and a greater value ' . 'more chances to be selected with equal ' . 'priority'), ), new EBox::Types::Port( fieldName => 'port', printableName => __('Target port'), editable => 1, ), new EBox::Types::Union( fieldName => 'hostName', printableName => __('Target'), editable => 1, help => __('If you select the "Custom", it should be a ' . 'Fully Qualified Domain Name'), subtypes => [ new EBox::Types::Select( fieldName => 'ownerDomain', printableName => __('This domain'), foreignModel => \&_hostnameModel, foreignField => 'hostname', editable => 1, ), new EBox::Types::Text( fieldName => 'custom', printableName => __('Custom'), editable => 1, ), ], ), ); my $dataTable = { tableName => 'Services', printableTableName => __('Services'), automaticRemove => 1, modelDomain => 'DNS', defaultActions => ['add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __('It manages the SRV records for this domain. ' . 'They are useful to select a host based on the priority ' . 'for a service.'), printableRowName => __x('{srv} record', srv => 'SRV'), }; return $dataTable; } # Group: Private methods # Get the hostname model from DNS module sub _hostnameModel { my ($type) = @_; # FIXME: We cannot use API until the bug in parent deep recursion is fixed # my $parentRow = $type->model()->parentRow(); # if ( defined($parentRow) ) { # return $parentRow->subModel('hostnames'); # } else { # Bug in initialisation code of ModelManager my $model = EBox::Global->modInstance('dns')->model('HostnameTable'); my $dir = $type->model()->directory(); $dir =~ s:srv:hostnames:g; $model->setDirectory($dir); return $model; # } } sub _protocols { my @options = ( { value => 'tcp', printableValue => 'TCP', }, { value => 'udp', printableValue => 'UDP', }, ); return \@options; } sub services { my ($self) = @_; unless (defined $self->{services}) { $self->{services} = $self->_loadServices(); } return $self->{services}; } sub _loadServices { my ($self) = @_; my $services = []; my @lines = File::Slurp::read_file(SERVICE_FILE); foreach my $line (@lines) { next if ($line =~ m:^#:); my @fields = split(/\s+/, $line); if (defined ($fields[0]) and defined ($fields[1])) { if ($fields[0] =~ m:[a-z\-]+: and $fields[1] =~ m:\d+/\w+:) { my ($name, $port, $protocol) = ($fields[0], $fields[1] =~ m:(\d+)/(\w+):); if (defined ($name) and defined ($port) and defined ($protocol)) { push (@{$services}, { name => $name, port => $port, protocol => $protocol }); foreach my $field (@fields[ 2 .. $#fields ]) { last if ($field =~ m:^#:); push (@{$services}, { name => $field, port => $port, protocol => $protocol }); } } } } } return $services; } sub checkService { my ($self, $changedFields, $allFields) = @_; my $services = $self->services(); if (exists $changedFields->{service_name} or exists $changedFields->{protocol} or exists $changedFields->{port} ) { my $nMatch = grep { ($_->{name} eq $allFields->{service_name}->value()) and ($_->{protocol} eq $allFields->{protocol}->value()) } @{$services}; if ($nMatch < 1) { throw EBox::Exceptions::External( __x('The chosen service is not in {file}', file => SERVICE_FILE)); } } } sub checkHostname { my ($self, $changedFields, $allFields) = @_; if (exists $changedFields->{hostName}) { if ($changedFields->{hostName}->selectedType() eq 'custom') { my $val = $changedFields->{hostName}->value(); my @parts = split(/\./, $val); unless (@parts > 1) { throw EBox::Exceptions::External( __x('The given host name is not a fully qualified domain ' . 'name (FQDN). Do you mean {srv}.{name}?', srv => $allFields->{service_name}->value(), name => $val)); } # Check the given custom nameserver is a CNAME record from the # same zone my $zoneRow = $self->parentRow(); my $zone = $zoneRow->valueByName('domain'); my $customZone = join('.', @parts[1 .. $#parts]); if ($zone eq $customZone) { # Use ownerDomain to set the mail exchanger throw EBox::Exceptions::External(__('A custom host name cannot be ' . 'set from the same domain. ' . 'Use "This domain" option ' . 'instead')); } } } } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/DomainTable.pm0000664000000000000000000005215212017140137017661 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::DomainTable # # This class inherits from and represents # the object table which basically contains domains names, the IP # address for the domain and a reference to a member # # package EBox::DNS::Model::DomainTable; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Exceptions::DataExists; use EBox::Types::Boolean; use EBox::Types::DomainName; use EBox::Types::HasMany; use EBox::Types::HostIP; use EBox::Types::Text; use EBox::Model::Manager; use EBox::DNS::View::DomainTableCustomizer; # Dependencies use Crypt::OpenSSL::Random; use MIME::Base64; use strict; use warnings; use base 'EBox::Model::DataTable'; # Group: Public methods sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless ($self, $class); return $self; } # Method: addDomain # # Add a domain to the domains table. Note this method must exist # because we must provide an easy way to migrate old dns module # to this new one. # # Parameters: # # domain_name - String domain's name # ipAddresses - (optional) Array ref with ipAddresses for the domain # hostnames - (optional) Array ref containing host information with the # same format than addHost method # type - (optional) Domain type (static, dynamic or dlz) # readOnly - (optional) # # Example: # # domain_name => 'subdom.foo.com', # readOnly => 0, # hostnames => [ # { name => 'bar', # ipAddresses => ['192.168.1.254', '192.168.2.254'], # aliases => ['bar', 'b4r'], # readonly => 0 # } # ] # sub addDomain { my ($self, $params) = @_; my $domainName = $params->{domain_name}; unless (defined ($domainName)) { throw EBox::Exceptions::MissingArgument('domain_name'); } unless (defined $params->{type}) { $params->{type} = EBox::DNS::STATIC_ZONE(); } EBox::debug("Adding DNS domain $domainName"); my $id = $self->addRow(domain => $domainName, type => $params->{type}, readOnly => $params->{readOnly}); unless (defined ($id)) { throw EBox::Exceptions::Internal("Couldn't add domain's name: $domainName"); } if (exists $params->{ipAddresses}) { my $domainRow = $self->_getDomainRow($domainName); my $ipModel = $domainRow->subModel('ipAddresses'); foreach my $ip (@{$params->{ipAddresses}}) { $ipModel->addRow(ip => $ip); } } # Add the hosts to the domain if (exists $params->{hostnames}) { foreach my $host (@{$params->{hostnames}}) { $self->addHost($domainName, $host); } } } # Method: addHost # # Adds a new host to the domain # # Parameters: # # domain - The domain where the host will be added # host - A hash ref containing: # name - The name # ipAddresses - Array ref containing the ips # aliases - (optional) Array ref containing the aliases # readOnly - (optional) # sub addHost { my ($self, $domain, $host) = @_; unless (defined $domain) { throw EBox::Exceptions::MissingArgument('domain'); } unless ($host->{name}) { throw EBox::Exceptions::MissingArgument('name'); } unless (defined $host->{ipAddresses} and scalar @{$host->{ipAddresses}} > 0) { throw EBox::Exceptions::MissingArgument('ipAddresses'); } EBox::debug('Adding host record'); my $domainRow = $self->_getDomainRow($domain); my $hostModel = $domainRow->subModel('hostnames'); my $hostRowId = $hostModel->addRow(hostname => $host->{name}, readOnly => $host->{readOnly}); my $hostRow = $hostModel->row($hostRowId); my $ipModel = $hostRow->subModel('ipAddresses'); foreach my $ip (@{$host->{ipAddresses}}) { EBox::debug('Adding host ip'); $ipModel->addRow(ip => $ip); } my $aliasModel = $hostRow->subModel('alias'); foreach my $alias (@{$host->{aliases}}) { EBox::debug('Adding host alias'); $aliasModel->addRow(alias => $alias); } } # Method: delHost # # Deletes a host from the domain # # Parameters: # # domain - The domain where lookup the host # name - The host name to delete # sub delHost { my ($self, $domain, $name) = @_; unless (defined $domain) { throw EBox::Exceptions::MissingArgument('domain'); } unless (defined $name) { throw EBox::Exceptions::MissingArgument('name'); } my $domainRow = $self->_getDomainRow($domain); my $hostsModel = $domainRow->subModel('hostnames'); my $hostRow = $hostsModel->find(hostname => $name); if (defined $hostRow) { my $rowId = $hostRow->id(); EBox::debug("Deleting host '$name' from domain '$domain'"); $hostsModel->removeRow($rowId); } else { throw EBox::Exceptions::DataNotFound(data => $name, value => $name); } } # Method: addHostAlias # # Parameters: # - domain # - hostname # - alias : can be a string or a list of string to add more then one alias # # Warning: # alias is added to the first found matching hostname sub addHostAlias { my ($self, $domain, $hostname, $alias) = @_; $domain or throw EBox::Exceptions::MissingArgument('domain'); $hostname or throw EBox::Exceptions::MissingArgument('hostname'); $alias or throw EBox::Exceptions::MissingArgument('alias'); my $domainRow = $self->_getDomainRow($domain); my $hostsModel = $domainRow->subModel('hostnames'); my $hostRow = $hostsModel->find(hostname => $hostname); if (not $hostRow) { throw EBox::Exceptions::DataNotFound(data => $hostname, value => $hostname); } my $aliasModel = $hostRow->subModel('alias'); my @aliases = ref $alias eq 'ARRAY' ? @{ $alias } : ($alias); foreach my $alias (@aliases) { EBox::debug('Adding host alias $alias'); $aliasModel->addRow(alias => $alias); } } # Method: addService # # Add a new SRV record to the domain # # Parameters: # # domain - The domain where the record will be added # service - A hash ref containing: # service - The name of the service, must match a name in /etc/services # protocol - 'tcp' or 'udp' # port - (port number) # target_type - custom or hostDomain # target - The name of a host domain or a FQDN # priority - (optional) # weight - (optional) # readOnly - (optional) # sub addService { my ($self, $domain, $service) = @_; unless (defined ($domain)) { throw EBox::Exceptions::MissingArgument('domain'); } unless (defined ($service->{priority})) { $service->{priority} = 0; } unless (defined ($service->{weight})) { $service->{weight} = 0; } my $domainRow = $self->_getDomainRow($domain); my $model = $domainRow->subModel('srv'); my %params = (service_name => $service->{service}, protocol => $service->{protocol}, priority => $service->{priority}, weight => $service->{weight}, port => $service->{port}); if ($service->{target_type} eq 'domainHost' ) { $params{hostName_selected} = 'ownerDomain'; my $hostsModel = $domainRow->subModel('hostnames'); my $ids = $hostsModel->ids(); foreach my $id (@{$ids}) { my $row = $hostsModel->row($id); my $rowHostName = $row->valueByName('hostname'); if ($rowHostName eq $service->{target}) { $params{ownerDomain} = $id; last; } } unless (defined $params{ownerDomain}) { throw EBox::Exceptions::DataNotFound( data => 'hostname', value => $service->{target}); } } elsif ($service->{target_type} eq 'custom' ) { $params{hostName_selected} = 'custom'; $params{custom} = $service->{target}; } else { throw EBox::Exceptions::MissingArgument('target_type'); } EBox::debug('Adding SRV record'); $model->addRow(%params, readOnly => $service->{readOnly}); } # Method: delService # # Deletes a SRV record from the domain # # Parameters: # # domain - The domain name where lookup the record to delete # service - A hash ref containing the attributes to check for deletion: # service_name # protocol # priority # weitht # port # sub delService { my ($self, $domain, $service) = @_; if (not defined ($service->{service})) { throw EBox::Exceptions::MissingArgument('service'); } my $rowId = undef; my $domainRow = $self->_getDomainRow($domain); my $model = $domainRow->subModel('srv'); foreach my $id (@{$model->ids()}) { my $row = $model->row($id); my $rowService = $row->valueByName('service_name'); my $rowProtocol = $row->valueByName('protocol'); my $rowPriority = $row->valueByName('priority'); my $rowWeight = $row->valueByName('weight'); my $rowPort = $row->valueByName('port'); if ((not defined ($service->{service}) or $rowService eq $service->{service}) and (not defined ($service->{protocol}) or $rowProtocol eq $service->{protocol}) and (not defined ($service->{priority}) or $rowPriority eq $service->{priority}) and (not defined ($service->{weight}) or $rowWeight eq $service->{weight}) and (not defined ($service->{port}) or $rowPort eq $service->{port})) { $rowId = $id; last; } } if (defined ($rowId)) { EBox::debug('Removing SRV record'); $model->removeRow($rowId); } else { throw EBox::Exceptions::DataNotFound(data => 'service_name', value => $service->{service}); } } # Method: addText # # Add a new TXT record to the domain # # Parameters: # # domain - The domain name where the record will be added # txt - A hash ref containing: # name - # data - # readOnly - (optional) # sub addText { my ($self, $domain, $txt) = @_; unless (defined ($domain)) { throw EBox::Exceptions::MissingArgument('domain'); } my $domainRow = $self->_getDomainRow($domain); my $model = $domainRow->subModel('txt'); my $id = $model->findRow(hostName => $txt->{name}, txt_data => $txt->{data}); unless ($id) { my %params = ( hostName_selected => 'custom', custom => $txt->{name}, txt_data => $txt->{data} ); EBox::debug('Adding TXT record'); $model->addRow( %params, readOnly => $txt->{readOnly}); } } # Method: delText # # Deletes a TXT record from the domain # # Parameters: # # domain - The domain name where lookup the record to delete # txt - A hash ref containing the values to check for delete # name - The record name # data - The record value # sub delText { my ($self, $domain, $txt) = @_; unless (defined ($domain)) { throw EBox::Exceptions::MissingArgument('domain'); } unless (defined $txt->{name}) { throw EBox::Exceptions::MissingArgument('name'); } my $rowId = undef; my $domainRow = $self->_getDomainRow($domain); my $model = $domainRow->subModel('txt'); foreach my $id (@{$model->ids()}) { my $row = $model->row($id); my $rowName = $row->valueByName('hostName'); my $rowData = $row->valueByName('txt_data'); if ((not defined ($txt->{name}) or $rowName eq $txt->{name}) and (not defined ($txt->{data}) or $rowData eq $txt->{data})) { $rowId = $id; last; } } if (defined ($rowId)) { EBox::debug('Removing TXT record'); $model->removeRow($rowId); } else { throw EBox::Exceptions::DataNotFound(data => 'hostname', value => $txt->{name}); } } # Method: addedRowNotify # # Override to: # - Add the NS and A records # - Generate the shared key. It is always generated but # only used by dynamic zones # # Overrides: # # # sub addedRowNotify { my ($self, $newRow) = @_; # Generate the TSIG key my $secret = $self->_generateSecret(); $newRow->elementByName('tsigKey')->setValue($secret); $newRow->store(); # Add the domain IP addresses my $network = EBox::Global->modInstance('network'); my $internalIpAddresses = $network->internalIpAddresses(); my $ipModel = $newRow->subModel('ipAddresses'); foreach my $ip (@{$internalIpAddresses}) { EBox::debug('Adding domain IP'); $ipModel->addRow(ip => $ip); } # Generate the NS record and its A record my $nsHost = $self->parentModule()->NameserverHost(); my $hostModel = $newRow->subModel('hostnames'); my $hostRowId = $hostModel->addRow(hostname => $nsHost); my $hostRow = $hostModel->row($hostRowId); $ipModel = $hostRow->subModel('ipAddresses'); foreach my $ip (@{$internalIpAddresses}) { EBox::debug('Adding host IP'); $ipModel->addRow(ip => $ip); } EBox::debug('Adding name server'); my $nsModel = $newRow->subModel('nameServers'); $nsModel->add(hostName => { ownerDomain => $nsHost } ); my $addrs = join(', ', @{$internalIpAddresses}); $self->setMessage(__x('Domain added. The host name {nshost} has been added to this domain with ' . 'these IP addresses {ips}, this host name has been also set as ' . 'nameserver record. Moreover, the same IP addresses have been assigned ' . 'to this new domain. You can always rename it or create alias for it.', nshost => $nsHost, ips => $addrs)); } # Method: viewCustomizer # # Use our own customizer to hide dynamic field in add form # # Overrides: # # # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::DNS::View::DomainTableCustomizer(); $customizer->setModel($self); return $customizer; } # Group: Protected methods sub _table { my @tableHead = ( new EBox::Types::DomainName ( 'fieldName' => 'domain', 'printableName' => __('Domain'), 'size' => '20', 'unique' => 1, 'editable' => 1 ), new EBox::Types::HasMany ( 'fieldName' => 'ipAddresses', 'printableName' => __("Domain IP Addresses"), 'foreignModel' => 'DomainIpTable', 'view' => '/DNS/View/DomainIpTable', 'backView' => '/DNS/View/DomainTable', 'size' => '1', ), new EBox::Types::HasMany ( 'fieldName' => 'hostnames', 'printableName' => __('Hostnames'), 'foreignModel' => 'HostnameTable', 'view' => '/DNS/View/HostnameTable', 'backView' => '/DNS/View/DomainTable', 'size' => '1', ), new EBox::Types::HasMany ( 'fieldName' => 'mailExchangers', 'printableName' => __('Mail Exchangers'), 'foreignModel' => 'MailExchanger', 'view' => '/DNS/View/MailExchanger', 'backView' => '/DNS/View/DomainTable', ), new EBox::Types::HasMany ( 'fieldName' => 'nameServers', 'printableName' => __('Name Servers'), 'foreignModel' => 'NameServer', 'view' => '/DNS/View/NameServer', 'backView' => '/DNS/View/DomainTable', ), new EBox::Types::HasMany ( 'fieldName' => 'txt', 'printableName' => __x('{txt} records', txt => 'TXT'), 'foreignModel' => 'Text', 'view' => '/DNS/View/Text', 'backView' => '/DNS/View/Text', ), new EBox::Types::HasMany ( 'fieldName' => 'srv', 'printableName' => __x('Services'), 'foreignModel' => 'Services', 'view' => '/DNS/View/Services', 'backView' => '/DNS/View/Services', ), new EBox::Types::Text( # This field indicates if the domain is static, dynamic or dlz # Not editable from interface 'fieldName' => 'type', 'printableName' => __('Dynamic domain'), 'editable' => 0, #'hiddenOnViewer' => 0, #'hiddenOnSetter' => 1, defaultValue => EBox::DNS::STATIC_ZONE(), 'HTMLViewer' => '/dns/ajax/viewer/domainTypeViewer.mas', ), new EBox::Types::Text( # This field is filled when the zone is dynamic and # indicates the TSIG key for the direct mapping and # the reversed zones for this domain hosts 'fieldName' => 'tsigKey', 'editable' => 0, 'optional' => 1, 'hidden' => 1, ), new EBox::Types::Text( fieldName => 'dlzDbPath', printableName => __('DLZ database path'), editable => 0, optional => 1, hidden => 1, ), ); my $dataTable = { 'tableName' => 'DomainTable', 'printableTableName' => __('Domains'), 'automaticRemove' => 1, 'defaultController' => '/Dns/Controller/DomainTable', 'HTTPUrlView'=> 'DNS/Composite/Global', 'defaultActions' => ['add', 'del', 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'class' => 'dataTable', 'printableRowName' => __('domain'), 'sortedBy' => 'domain', 'help' => __('Here you can add the domains for this DNS server. ' . 'Each domain can have different hostnames with aliases ' . ' (A and CNAME) and other special records (MX, NS, TXT and SRV).'), }; return $dataTable; } # Group: Private methods # Generate the secret key using HMAC-MD5 algorithm sub _generateSecret { my ($self) = @_; Crypt::OpenSSL::Random::random_seed(time() . rand(2**512)); Crypt::OpenSSL::Random::random_egd('/dev/urandom'); # Generate a key of 512 bits = 64Bytes return MIME::Base64::encode(Crypt::OpenSSL::Random::random_bytes(64), ''); } # Method: _getDomainRow # # Return the row for the specified domain name # # Throws: # # DataNotFoundException # sub _getDomainRow { my ($self, $domain) = @_; my $domainRow = undef; foreach my $id (@{$self->ids()}) { my $row = $self->row($id); my $rowDomain = $row->valueByName('domain'); if ($rowDomain eq $domain) { $domainRow = $row; last; } } unless (defined ($domainRow)) { throw EBox::Exceptions::DataNotFound(data => 'domain', value => $domain); } return $domainRow; } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/MailExchanger.pm0000664000000000000000000001751112017140137020211 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # EBox::DNS::Model::MailExchanger # # This class inherits from and represents # the object table which contains the mail exchangers for a domain # with its preference value. A member of # # package EBox::DNS::Model::MailExchanger; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Exceptions::DataExists; use EBox::Types::DomainName; use EBox::Types::Int; use EBox::Types::Select; use EBox::Types::Union; use EBox::Model::Manager; use constant { MIN_PREFERENCE_NUM => 0, MAX_PREFERENCE_NUM => 65535, }; # Group: Public methods # Constructor: new # # Create a new MailExchanger model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } # Method: validateTypedRow # # Check the preference number is a valid one # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; if ( exists $changedFields->{preference} ) { my $prefVal = $changedFields->{preference}->value(); unless ( $prefVal > MIN_PREFERENCE_NUM and $prefVal < MAX_PREFERENCE_NUM ) { throw EBox::Exceptions::External(__x('Invalid preference number. Allowed range: ({min}, {max})', min => MIN_PREFERENCE_NUM, max => MAX_PREFERENCE_NUM)); } } if ( exists $changedFields->{hostName} ) { if ( $changedFields->{hostName}->selectedType() eq 'custom' ) { my $val = $changedFields->{hostName}->value(); my @parts = split(/\./, $val); unless ( @parts > 2 ) { throw EBox::Exceptions::External(__x('The given host name ' . 'is not a fully qualified domain name (FQDN). ' . 'Do you mean mx.{name}?', name => $val)); } # Check the given custom nameserver is a CNAME record from the # same zone my $zoneRow = $self->parentRow(); my $zone = $zoneRow->valueByName('domain'); my $customZone = join('.', @parts[1 .. $#parts]); if ( $zone eq $customZone ) { # Use ownerDomain to set the mail exchanger throw EBox::Exceptions::External(__('A custom host name cannot be ' . 'set from the same domain. ' . 'Use "This domain" option ' . 'instead')); } } } } # Method: precondition # # Overrides: # # # sub precondition { my ($self) = @_; if ( $self->parentRow()->readOnly() ) { return 0; } return 1; } # Method: preconditionFailMsg # # Overrides: # # # sub preconditionFailMsg { return __('The domain is set as read only. You cannot add mail exchangers'); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::Union( fieldName => 'hostName', printableName => __('Host name'), editable => 1, unique => 1, help => __('If you choose "Custom", ' . 'it should be a Fully Qualified Domain Name'), subtypes => [ new EBox::Types::Select( fieldName => 'ownerDomain', printableName => __('This domain'), foreignModel => \&_hostnameModel, foreignField => 'hostname', editable => 1, unique => 1, ), new EBox::Types::DomainName( fieldName => 'custom', printableName => __('Custom'), editable => 1, unique => 1, ), ], ), new EBox::Types::Int( fieldName => 'preference', printableName => __('Preference'), editable => 1, defaultValue => 10, ), ); my $dataTable = { tableName => 'MailExchanger', printableTableName => __('Mail exchangers'), automaticRemove => 1, modelDomain => 'DNS', defaultActions => ['add', 'del', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __x('The smallest preference number has the highest priority ' . ' and is the first server to be tried when a remote client ' . '(typically another mail server) does an MX lookup for the ' . 'domain name. Allowed preference number interval = ({min}, {max})', min => MIN_PREFERENCE_NUM, max => MAX_PREFERENCE_NUM), printableRowName => __('Mail exchanger record'), sortedBy => 'preference', }; return $dataTable; } # Method: pageTitle # # Overrides # to show the name of the domain sub pageTitle { my ($self) = @_; return $self->parentRow()->printableValueByName('domain'); } # Group: Private methods # Get the hostname model from DNS module sub _hostnameModel { my ($type) = @_; # FIXME: We cannot use API until the bug in parent deep recursion is fixed # my $parentRow = $type->model()->parentRow(); # if ( defined($parentRow) ) { # return $parentRow->subModel('hostnames'); # } else { # Bug in initialisation code of ModelManager my $model = EBox::Global->modInstance('dns')->model('HostnameTable'); my $dir = $type->model()->directory(); $dir =~ s:mailExchangers:hostnames:g; $model->setDirectory($dir); return $model; # } } 1; zentyal-dns-2.3.10+quantal1/src/EBox/Model/Forwarder.pm0000664000000000000000000000470412017140137017435 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: # # # # This class inherits from and represents # the object table which consists of forwarders to forwards those # queries whose asked zone the server is not authorised. The single # field available is: # # - forwarder # package EBox::DNS::Model::Forwarder; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Global; use EBox::Gettext; use EBox::Types::HostIP; # Group: Public methods # Constructor: new # # Create a new Text model instance # # Returns: # # - the newly created model # instance # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::HostIP( fieldName => 'forwarder', printableName => __('Forwarder'), editable => 1, unique => 1, ), ); my $dataTable = { tableName => 'Forwarder', printableTableName => __('Forwarders'), modelDomain => 'DNS', defaultActions => ['add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __('The server will send the queries to the forwarders first, ' . 'and if not answered it will attempt to answer the query.'), printableRowName => __('forwarder'), order => 1, insertPosition => 'back', }; return $dataTable; } 1; zentyal-dns-2.3.10+quantal1/stubs/0000775000000000000000000000000012017140137013613 5ustar zentyal-dns-2.3.10+quantal1/stubs/dbrev.mas0000664000000000000000000000120212017140137015412 0ustar <%args> $groupip $rdata <%init> my @time = localtime(); my $date = sprintf("%04d%02d%02d%02d",$time[5]+1900,$time[4]+1,$time[3],$time[2]); $TTL 3D $ORIGIN <% $groupip %>.in-addr.arpa. @ IN SOA <% $rdata->{soa} %>.<% $rdata->{domain} %>. hostmaster.<% $rdata->{domain} %>. ( <% $date %> ;serial number 8H ;refresh 2H ;retry 4W ;expiration 1D ) ; ; % foreach my $ns (@{$rdata->{'ns'}}) { NS <% $ns %>.<% $rdata->{'domain'} %>. % } ; % foreach my $host (@{$rdata->{'hosts'}}) { % my $prefix = $host->{name} ? "$host->{name}." : ''; <% $host->{'ip'} %> PTR <% $prefix . $rdata->{'domain'} %>. % } zentyal-dns-2.3.10+quantal1/stubs/named.conf.options.mas0000664000000000000000000000174612017140137020027 0ustar <%args> @forwarders $keytabPath => undef options { directory "/var/cache/bind"; // If there is a firewall between you and nameservers you want // to talk to, you might need to uncomment the query-source // directive below. Previous versions of BIND always asked // questions using port 53, but BIND 8.1 and later use an unprivileged // port by default. //query-source address * port 53; //transfer-source * port 53; //notify-source * port 53; % if ( @forwarders > 0 ) { // If your ISP provided one or more IP addresses for stable // nameservers, you probably want to use them as forwarders. forward first; forwarders { % foreach my $forwarder (@forwarders) { <% $forwarder %>; % } }; % } % if (defined $keytabPath) { tkey-gssapi-keytab "<% $keytabPath %>"; % } auth-nxdomain no; # conform to RFC1035 allow-query { any; }; allow-recursion { trusted; }; allow-query-cache { trusted; }; }; zentyal-dns-2.3.10+quantal1/stubs/named.conf.mas0000664000000000000000000000112212017140137016321 0ustar include "/etc/bind/named.conf.options"; include "/etc/bind/keys"; // prime the server with knowledge of the root servers zone "." { type hint; file "/etc/bind/db.root"; }; // be authoritative for the localhost forward and reverse zones, and for // broadcast zones as per RFC 1912 zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127"; }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; include "/etc/bind/named.conf.local"; zentyal-dns-2.3.10+quantal1/stubs/db.mas0000664000000000000000000000571112017140137014706 0ustar <%doc> Stub template file to dump the configuration file for a domain zone Parameters: domain - hash ref containing the following information: name - String the domain's name hosts - Array ref containing hash refs with the following elements: name - String the host's name ip - Array ref containing the host ip addresses aliases - Array ref containing the host aliases mailExchangers - Array ref containing hash refs with the following elements: hostName - String the host's name which is a mail exchanger preference - Int the preference number for that MX record nameServers - Array ref containing the name servers for this domain txt - Array ref containing hash refs with the following elements: hostName - String the host's name which the TXT record belongs to. It could be the zone txt_dat - String the arbitrary data srv - Array ref containing hash refs with the following elements: service_name - String the service's name protocol - String the protocol name - The domain name for which this record is valid priority - Int the priority weight - Int the weight target_port - Int the target port target_host - Int the target host name primariNameServer - The primary nameserver of the domain ipAddresses - Array ref containing the domain ip addresses <%args> $domain <%init> my @time = localtime(); my $date = sprintf("%04d%02d%02d%02d",$time[5]+1900,$time[4]+1,$time[3],$time[2]); my @nsRRs = @{$domain->{nameServers}}; my @domainIps = @{$domain->{ipAddresses}}; my @hostRRs = @{$domain->{hosts}}; my @mxRRs = @{$domain->{mailExchangers}}; my @txtRRs = @{$domain->{txt}}; my @srvRRs = @{$domain->{srv}}; $ORIGIN <% $domain->{name} %>. $TTL 3D @ IN SOA <% $domain->{primaryNameServer} %> hostmaster ( <% $date %> ;serial number 8H ;refresh 2H ;retry 4W ;expiration 1D ) ;minimum ; % foreach my $ns (@nsRRs) { @ IN NS <% $ns %> % } % foreach my $ip (@domainIps) { @ IN A <% $ip %> % } ; % foreach my $host (@hostRRs) { % foreach my $ip (@{$host->{ip}}) { <% $host->{name} %> IN A <% $ip %> % } % foreach my $alias (@{$host->{aliases}}) { <% $alias %> IN CNAME <% $host->{name} %> % } % } % foreach my $mxRR (@mxRRs) { @ IN MX <% $mxRR->{preference} %> <% $mxRR->{hostName} %> % } % foreach my $txtRR (@txtRRs) { <% $txtRR->{hostName} %> IN TXT <% $txtRR->{txt_data} %> % } % foreach my $srvRR (@srvRRs) { _<% $srvRR->{service_name} %>._<% $srvRR->{protocol} %> IN SRV <% $srvRR->{priority} %> <% $srvRR->{weight} %> <% $srvRR->{target_port} %> <% $srvRR->{target_host} %> % } zentyal-dns-2.3.10+quantal1/stubs/keys.mas0000664000000000000000000000061712017140137015274 0ustar <%doc> Template to write down the TSIG keys for zones whose update is done dynamically using external programs Parameters: keys - Hash indexed by key name, stores the TSIG secret <%args> %keys # Symmetric TSIG keys to update dynamic zones % foreach my $keyName (keys(%keys)) { key "<% $keyName %>." { algorithm HMAC-MD5; secret "<% $keys{$keyName} %>"; }; % } zentyal-dns-2.3.10+quantal1/stubs/named.conf.local.mas0000664000000000000000000000276312017140137017426 0ustar <%args> @domains @inaddrs @intnets $confDir $dynamicConfDir // Generated by Zentyal acl "trusted" { % foreach my $intnet (@intnets) { <% $intnet %>; % } localhost; localnets; }; % foreach my $dom (@domains) { % if ($dom->{type} eq EBox::DNS::DLZ_ZONE) { dlz "<% $dom->{name} %>" { database "dlopen <% $dom->{dlzDbPath} %>"; }; % } else { zone "<% $dom->{name} %>." IN { type master; % if ($dom->{type} eq EBox::DNS::DYNAMIC_ZONE) { file "<% $dynamicConfDir %>/db.<% $dom->{'name'} %>"; % } else { file "<% $confDir %>/db.<% $dom->{'name'} %>"; % } // we need to use check-names ignore so _msdcs A records can be created check-names ignore; % if ($dom->{type} eq EBox::DNS::DYNAMIC_ZONE) { update-policy { // The only allowed dynamic updates are A records grant <% $dom->{'name'} %>. subdomain <% $dom->{'name'} %>. A TXT; // Grant from localhost grant local-ddns zonesub any; }; % } }; % } % } % foreach my $inaddr (@inaddrs) { zone "<% $inaddr->{'ip'} %>.in-addr.arpa" { type master; file "<% $inaddr->{'file'} %>"; update-policy { // The only allowed dynamic updates are PTR records % foreach my $keyName (@{$inaddr->{'keyNames'}}) { grant <% $keyName %>. subdomain <% $inaddr->{'ip'} %>.in-addr.arpa. PTR TXT; % } // Grant from localhost grant local-ddns zonesub any; }; }; % } include "/etc/bind/zones.rfc1918"; zentyal-dns-2.3.10+quantal1/stubs/apparmor-named.local.mas0000664000000000000000000000124612017140137020314 0ustar # Site-specific additions and overrides for usr.sbin.named. # For more details, please see /etc/apparmor.d/local/README. # This profile has been modified by Zentyal Server to provide # allow samba4 dns updates /var/lib/samba/private/* rw, /var/lib/samba/private/dns/* rw, # Access to kerberos keytab /var/lib/samba/private/dns.keytab kr, # Access to kerberos ticket /var/tmp/** rw, # Access to samba AD DLZ zone /var/lib/samba/private/dns/sam.ldb k, /var/lib/samba/private/dns/sam.ldb.d/* krw, /usr/lib/i386-linux-gnu/samba/ldb/*.so m, /usr/lib/i386-linux-gnu/samba/bind9/*.so m, /usr/lib/i386-linux-gnu/samba/gensec/*.so m, /usr/lib/i386-linux-gnu/ldb/modules/ldb/*.so m, zentyal-dns-2.3.10+quantal1/ChangeLog0000664000000000000000000001572212017140137014234 0ustar HEAD + Write keys file with read access only to bind group 2.3.10 + Remove subdomain fields from hostnames and services models after DLZ zones support. The samba records are no longer created in the models but loaded from the DLZ zone. + Add support for DLZ zones to load the Samba4 DNS zones stored in LDB. + samba is not longer a restore dependency + Fixed some errors with array references + Added modeldepends to yaml schema 2.3.9 + Fixed help strings + Add method to set the domain's dynamic flag + Read and apply the samba domain update policy + Added message when a domain is added to clarify concepts 2.3.8 + Adapted DHCP ranges to reverse ip fix in Net::IP + Fixed and improved facade method for management of domains, hostname and alias + Added foreign declarations in module schema 2.3.7 + Use FirewallObserver instead of deprecated addOutputRule + Adapted to new Model management framework 2.3.6 + Add new field subdomain to hostnames and services model, needed to create some samba records + API to add/delete A, SRV and TXT records to a domain + Change the primary nameserver record from 'ns' to the hostname + Change the IP address field on domain hosts to hasmany type. This is needed by samba to add the global catalog server record + Change the domain IP address to a hasmay type. This is needed if the server has multiple internal networks attached. + Server does not leak to the internet queries for unused rfc1918 zones 2.3.5 + Create tables with MyISAM engine by default 2.3.4 + Packaging fixes for precise 2.3.3 + Updated Standards-Version to 3.9.2 2.3.1 + Service name in uppercase and description is now translatable + Fixed executable permissions in src/scripts 2.3 + Replaced autotools with zbuildtools + Bugfix: Delete TXT record on a dynamic domain works again 2.2.1 + Do not set reverse resolution for domain if any hostname does already has it + Do not set reverse resolution for aliases + Change main URL for breadcrumbs for Domains + Set always five subdomains to reverse zones to avoid problems with some networks like 10.0.0.0/24 + Adapted alias table and methods to multiple hostnames + Use proper paths for PID files to be resilient on reboots in upstart pre-script 2.1.6 + Prevent start of bind9 daemon after module is disabled 2.1.5 + Removed /zentyal prefix from URLs + Avoid duplicated restart during postinst 2.1.4 + Workaround for parent deep-recursion problem + Combine all models in the DNS menu entry and added missing help 2.1.3 + Give support for Round-Robin records, that is, the same name points to different IP addresses + Add transparent cache DNS when firewall module is enabled + Add forwarders manual configuration + Add wildcard for hostnames default value + Add TXT records + Add SRV records 2.1.2 + Use public API to get the Hostname model in NameServer and MailExchanger models 2.1.1 + Set as hostmaster@domain the email address to report problems and responsible for that domain + Do not allow set custom NS or MX records to point CNAME records in the same domain + Do not allow to remove last NS record as it is mandatory + Add a default NS record and A record when creating a domain + Just one PTR record is written per IP address to avoid problems in reverse resolution + Remove no longer used zone files + Give support to mix static direct resolution with dynamic one + Give support to mix static reverse resolution with dynamic one + Start init script using -f flag to send the named log to daemon.log file + Give support for dynamic DNS reverse resolution under /var/lib/bind/ directory 2.1 + Use new standard enable-module script + Replace migrations with initialSetup + Replace /etc/ebox/80dns.conf with /etc/zentyal/dns.conf 2.0.1 + Bugfix: Comply apparmor profile by setting the updated dynamic zones under /var/lib/bind 1.5.1 + BP: Set @ to all domain-wide records (A, NS) to avoid issues regarding to order in the configuration file + Added support for internal networks allowed to recurse the caching server. + Add support for topdomain record in addDomain method. + Add TCP/53 to dns service 1.3.14 + Added migration script for configured modules + Remove migration scripts 0001_import_to_data_table_model.pl 0002_fix_active_to_enabled.pl + Move 0003_add_dns_service.pl to 0001_add_dns_service.pl 1.3.13 + Added support for dynamic zones to be updated using a shared secret key available at `/etc/bind/keys`. This feature is mainly used by dhcp module to implement dynamic DNS updates. + Fixed structure of menu on language change 1.3.12 + Add breadcrumbs to UI 1.3.11 + Added report support 1.3.10 + Added support for NS records + Check for FQDN in custom MX records 1.3.4 + Reversed record for domain IP address added + Fixed bug when removing hostnames 1.3.1 + Comment out default configuration of source ports operations to stick to the defaults provided by the Ubuntu package. 1.1.10 + New release 1.1 + Use new row() and ids() API 0.12.101 + Check two hostnames or alias are equal using type method to do so 0.12.100 + Added optional IP address for domains + Bugfix: Show correct message when editing a hostname 0.12.99 + New release 0.12.1 + Bugfix. Remove mail exchangers that reference a deleted host name. 0.12 + Use the new EBox::Model::Row api + Load module capability in pre-start just like the bind9 init script does + Don't add static entry `ns` to localhost if user has defined another IP address for the `ns` name0.11.102 + Check aliases are not nameserver records as well 0.11.101 + Added Mail Exchanger model to introduce MX records in domains. + Added mail exchanger model related methods to the exposed API. + Check consistencies among alias and hostnames within the same domain + Updated remainder models to use lastest types HostIP and DomainName + Added 'changeName', 'getHostNameByName', 'getHostNameByIP' and 'findAlias' to improve DNS API to Perl scripts and SOAP clients 0.11.100 + add isRunning and enableService to set firewall properly + onInstall() functionality moved to migration script + Do not remove bind9 rc links + Stop bind9 in pre-start in upstart script 0.11.99 + Added `getHostname` to the exposed API to interact with webserver module + Now tables are shown sorted by 'name' attribute (domain, hostname and alias respectively) 0.11 + New release 0.10.99 + Expose methods in module's API + Fix bug in migration pre0.9.100 installations 0.10 + New release 0.9.100 + Add reverse resolution + Use new model/view framework. UI uses Ajax 0.9.99 + New release 0.9.3 + New release 0.9.2 + New release 0.9.1 + New release 0.9 + Added Polish translation + Added Aragonese translation + Added German translation 0.8.99 * Add DNS server functionality 0.7.1 * Allow TCP queries * Use of ebox-sudoers-friendly 0.7 * First public release 0.6 * API documented using naturaldocs * Update install and depends 0.5.2 * Fix some packaging issues 0.5.1 * Convert module to new menu system 0.5 * Initial release zentyal-dns-2.3.10+quantal1/AUTHORS0000664000000000000000000000024012017140137013517 0ustar Copyright (C) 2004-2012 eBox Technologies S.L. For an updated list of the current and past developers please visit: http://trac.zentyal.org/wiki/Contributors zentyal-dns-2.3.10+quantal1/schemas/0000775000000000000000000000000012017140137014076 5ustar zentyal-dns-2.3.10+quantal1/schemas/dns.yaml0000664000000000000000000000130212017140137015542 0ustar class: 'EBox::DNS' depends: - network - samba - users models: - DomainTable - HostIpTable - DomainIpTable - HostnameTable - AliasTable - MailExchanger - NameServer - Text - Services - Forwarder - Settings composites: Global: [Settings, Forwarder, DomainTable] modeldepends: MailExchanger: dns/HostnameTable: [ownerDomain] NameServer: dns/HostnameTable: [ownerDomain] Services: dns/HostnameTable: [ownerDomain] Text: dns/HostnameTable: [ownerDomain] foreign: HostnameTable: [HostIpTable, AliasTable] DomainTable: [DomainIpTable, HostnameTable, MailExchanger, NameServer, Text, Services] zentyal-dns-2.3.10+quantal1/schemas/sql/0000775000000000000000000000000012017140137014675 5ustar zentyal-dns-2.3.10+quantal1/schemas/sql/dns_domains.sql0000664000000000000000000000017312017140137017715 0ustar CREATE TABLE IF NOT EXISTS dns_domains ( timestamp TIMESTAMP, domains INT, INDEX(timestamp) ) ENGINE = MyISAM; zentyal-dns-2.3.10+quantal1/schemas/sql/dns_domains_report.sql0000664000000000000000000000014212017140137021304 0ustar CREATE TABLE IF NOT EXISTS dns_domains_report ( date DATE, domains INT ) ENGINE = MyISAM;