Merge remote-tracking branch 'stevee/core-90-ddnsctrl' into next

This commit is contained in:
Michael Tremer
2015-04-29 11:26:20 +02:00
12 changed files with 178 additions and 113 deletions

View File

@@ -3,6 +3,7 @@ usr/local/bin/addonctrl
usr/local/bin/backupctrl
#usr/local/bin/clamavctrl
usr/local/bin/collectdctrl
usr/local/bin/ddnsctrl
usr/local/bin/dhcpctrl
usr/local/bin/dnsmasqctrl
usr/local/bin/extrahdctrl

View File

@@ -0,0 +1 @@
../../../common/ddns

View File

@@ -6,6 +6,7 @@ etc/rc.d/init.d/networking/functions.network
etc/rc.d/init.d/networking/red.up/99-geoip-database
etc/rc.d/rcsysinit.d/S90network-trigger
srv/web/ipfire/cgi-bin/country.cgi
srv/web/ipfire/cgi-bin/ddns.cgi
srv/web/ipfire/cgi-bin/firewall.cgi
srv/web/ipfire/cgi-bin/fwhosts.cgi
srv/web/ipfire/cgi-bin/geoip-block.cgi
@@ -19,6 +20,7 @@ srv/web/ipfire/html/themes/maniac/include/style.css
usr/lib/firewall/firewall-lib.pl
usr/lib/firewall/rules.pl
usr/local/bin/backupiso
usr/local/bin/ddnsctrl
usr/local/bin/xt_geoip_build
usr/local/bin/xt_geoip_update
var/ipfire/general-functions.pl

View File

@@ -192,6 +192,8 @@ EOF
fcrontab -z &>/dev/null
# Generate ddns configuration file
sudo -u nobody /srv/web/ipfire/cgi-bin/ddns.cgi
# Update Language cache
perl -e "require '/var/ipfire/lang.pl'; &Lang::BuildCacheLang"

View File

@@ -44,10 +44,8 @@ my $settingsfile = "${General::swroot}/ddns/settings";
# Config file to store the configured ddns providers.
my $datafile = "${General::swroot}/ddns/config";
# Dynamic ddns programm call.
my @ddnsprog = ("/usr/bin/ddns", "--config",
"/var/ipfire/ddns/ddns.conf",
"update-all");
# Call the ddnsctrl helper binary to perform the update.
my @ddnsprog = ("/usr/local/bin/ddnsctrl", "update-all");
my %settings=();
my $errormessage = '';

View File

@@ -71,6 +71,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/ddns/001-ddns-007-perform-lazy-database-init.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/ddns/002-ddns-007-also-open-database-for-search-operations.patch
cd $(DIR_APP) && [ -x "configure" ] || sh ./autogen.sh
cd $(DIR_APP) && ./configure \
--prefix=/usr \

View File

@@ -31,7 +31,7 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \
redctrl syslogdctrl extrahdctrl sambactrl upnpctrl tripwirectrl \
smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
getconntracktable wirelessclient dnsmasqctrl torctrl
getconntracktable wirelessclient dnsmasqctrl torctrl ddnsctrl
SUID_UPDX = updxsetperms
OBJS = $(patsubst %,%.o,$(PROGS) $(SUID_PROGS))

37
src/misc-progs/ddnsctrl.c Normal file
View File

@@ -0,0 +1,37 @@
/* This file is part of the IPFire Firewall.
*
* This program is distributed under the terms of the GNU General Public
* Licence. See the file COPYING for details.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "setuid.h"
const char *conffile = "/var/ipfire/ddns/ddns.conf";
int main(int argc, char *argv[]) {
char cmd[STRING_SIZE];
if (!(initsetuid()))
exit(1);
if (argc < 2) {
fprintf(stderr, "\nNo argument given.\n\nddnsctrl (update-all)\n\n");
exit(1);
}
if (strcmp(argv[1], "update-all") == 0) {
snprintf(cmd, sizeof(cmd), "/usr/bin/ddns --config %s update-all >/dev/null 2>&1", conffile);
safe_system(cmd);
} else {
fprintf(stderr, "\nBad argument given.\n\nddnsctrl (update-all)\n\n");
exit(1);
}
return 0;
}

View File

@@ -0,0 +1,89 @@
commit 63e16feedea3639ef1f21fecbff9ed2ae256728b
Author: Michael Tremer <michael.tremer@ipfire.org>
Date: Sat Apr 25 13:18:07 2015 +0200
Perform lazy initialization of the database
The database will only be initialized when it is actually
needed. That makes starting up ddns a bit faster and allows
us to execute it as non-root for simple commands like
"list-providers".
If the database path is not writable at all, the database
feature is disable and an error message is logged. This
will hopefully help us to perform the DNS update even when
there is a local misconfiguration.
diff --git a/src/ddns/database.py b/src/ddns/database.py
index 5d4ffc9..42c3433 100644
--- a/src/ddns/database.py
+++ b/src/ddns/database.py
@@ -20,7 +20,7 @@
###############################################################################
import datetime
-import os.path
+import os
import sqlite3
# Initialize the logger.
@@ -31,9 +31,11 @@ logger.propagate = 1
class DDNSDatabase(object):
def __init__(self, core, path):
self.core = core
+ self.path = path
- # Open the database file
- self._db = self._open_database(path)
+ # We won't open the connection to the database directly
+ # so that we do not do it unnecessarily.
+ self._db = None
def __del__(self):
self._close_database()
@@ -46,7 +48,7 @@ class DDNSDatabase(object):
conn = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.isolation_level = None
- if not exists:
+ if not exists and self.is_writable():
logger.debug("Initialising database layout")
c = conn.cursor()
c.executescript("""
@@ -68,12 +70,25 @@ class DDNSDatabase(object):
return conn
+ def is_writable(self):
+ # Check if the database file exists and is writable.
+ ret = os.access(self.path, os.W_OK)
+ if ret:
+ return True
+
+ # If not, we check if we are able to write to the directory.
+ # In that case the database file will be created in _open_database().
+ return os.access(os.path.dirname(self.path), os.W_OK)
+
def _close_database(self):
if self._db:
self._db_close()
self._db = None
def _execute(self, query, *parameters):
+ if self._db is None:
+ self._db = self._open_database(self.path)
+
c = self._db.cursor()
try:
c.execute(query, parameters)
@@ -81,6 +96,10 @@ class DDNSDatabase(object):
c.close()
def add_update(self, hostname, status, message=None):
+ if not self.is_writable():
+ logger.warning("Could not log any updates because the database is not writable")
+ return
+
self._execute("INSERT INTO updates(hostname, status, message, timestamp) \
VALUES(?, ?, ?, ?)", hostname, status, message, datetime.datetime.utcnow())

View File

@@ -0,0 +1,40 @@
commit f62fa5baffe2d225604460ecd03b8159b987df8f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date: Sun Apr 26 20:15:33 2015 +0200
database: Open database for the search operations, too
diff --git a/src/ddns/database.py b/src/ddns/database.py
index 42c3433..70a7363 100644
--- a/src/ddns/database.py
+++ b/src/ddns/database.py
@@ -122,6 +122,9 @@ class DDNSDatabase(object):
"""
Returns the timestamp of the last update (with the given status code).
"""
+ if self._db is None:
+ self._db = self._open_database(self.path)
+
c = self._db.cursor()
try:
@@ -141,6 +144,9 @@ class DDNSDatabase(object):
"""
Returns the update status of the last update.
"""
+ if self._db is None:
+ self._db = self._open_database(self.path)
+
c = self._db.cursor()
try:
@@ -156,6 +162,9 @@ class DDNSDatabase(object):
"""
Returns the reason string for the last failed update (if any).
"""
+ if self._db is None:
+ self._db = self._open_database(self.path)
+
c = self._db.cursor()
try:

View File

@@ -1,85 +0,0 @@
commit 78046ffe2187d91c61d6c2f910249b8a5be71b08
Author: Stefan Schantl <stefan.schantl@ipfire.org>
Date: Wed Oct 22 21:39:09 2014 +0200
Add changeip.com as new provider.
Fixes #10639.
diff --git a/README b/README
index 5944102..6a06f4b 100644
--- a/README
+++ b/README
@@ -49,6 +49,7 @@ INSTALLATION:
SUPPORTED PROVIDERS:
all-inkl.com
+ changeip.com
dhs.org
dns.lightningwirelabs.com
dnspark.com
diff --git a/ddns.conf.sample b/ddns.conf.sample
index d3ac53f..0048a46 100644
--- a/ddns.conf.sample
+++ b/ddns.conf.sample
@@ -30,6 +30,11 @@
# secret = XYZ
# ttl = 60
+# [test.changeip.com]
+# provider = changeip.com
+# username = user
+# password = pass
+
# [test.dhs.org]
# provider = dhs.org
# username = user
diff --git a/src/ddns/providers.py b/src/ddns/providers.py
index 1e88995..587d5ff 100644
--- a/src/ddns/providers.py
+++ b/src/ddns/providers.py
@@ -539,6 +539,44 @@ class DDNSProviderBindNsupdate(DDNSProvider):
return "\n".join(scriptlet)
+class DDNSProviderChangeIP(DDNSProvider):
+ handle = "changeip.com"
+ name = "ChangeIP.com"
+ website = "https://changeip.com"
+ protocols = ("ipv4",)
+
+ # Detailed information about the update api can be found here.
+ # http://www.changeip.com/accounts/knowledgebase.php?action=displayarticle&id=34
+
+ url = "https://nic.changeip.com/nic/update"
+ can_remove_records = False
+
+ def update_protocol(self, proto):
+ data = {
+ "hostname" : self.hostname,
+ "myip" : self.get_address(proto),
+ }
+
+ # Send update to the server.
+ try:
+ response = self.send_request(self.url, username=self.username, password=self.password,
+ data=data)
+
+ # Handle error codes.
+ except urllib2.HTTPError, e:
+ if e.code == 422:
+ raise DDNSRequestError(_("Domain not found."))
+
+ raise
+
+ # Handle success message.
+ if response.code == 200:
+ return
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError(_("Server response: %s") % output)
+
+
class DDNSProviderDHS(DDNSProvider):
handle = "dhs.org"
name = "DHS International"

View File

@@ -1,23 +0,0 @@
commit 25f39b4e437627bd1a49393280271d59ad28b86e
Author: Stefan Schantl <stefan.schantl@ipfire.org>
Date: Mon Jan 5 21:37:55 2015 +0100
spdns.de: Fix authentication.
There was a simple copy and paste issue which prevents a
correct authentication with username and password against the
providers API.
diff --git a/src/ddns/providers.py b/src/ddns/providers.py
index 587d5ff..bcfb088 100644
--- a/src/ddns/providers.py
+++ b/src/ddns/providers.py
@@ -1271,7 +1271,7 @@ class DDNSProviderSPDNS(DDNSProtocolDynDNS2, DDNSProvider):
@property
def password(self):
- return self.get("username") or self.token
+ return self.get("password") or self.token
class DDNSProviderStrato(DDNSProtocolDynDNS2, DDNSProvider):