# HG changeset patch # User rejo # Date 1176244843 0 # Node ID 58094faf794dbc2da49a939d0d8d8c9a1d193c53 # Parent 2cd8c1649ba9f6207ecbf5b00efae34dc762b2eb [feladat @ 2] Creation of initial working branch. diff -r 2cd8c1649ba9 -r 58094faf794d add_record.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/add_record.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,56 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: add_record.php,v 1.6 2003/02/05 15:25:01 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); +if ($_POST["commit"]) { + $ret = add_record($_POST["zoneid"], $_POST["name"], $_POST["type"], $_POST["content"], $_POST["ttl"], $_POST["prio"]); + if ($ret != '1') { + die("$ret"); + } + clean_page("edit.php?id=".$_POST["zoneid"]); +} +include_once("inc/header.inc.php"); +?> +

Add record to zone ""

+
DNS Admin >> "> >> Add record

+ +
+"> + + + +
Name TypePriorityContentTimeToLive
.IN
+
+
+ + diff -r 2cd8c1649ba9 -r 58094faf794d delete_domain.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/delete_domain.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,50 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: delete_domain.php,v 1.6 2002/12/18 01:13:10 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +if (!level(5)) +{ + error(ERR_LEVEL_5); + +} + +if ($_GET["id"]) { + if ($_GET["confirm"] == '0') { + clean_page("index.php"); + } elseif ($_GET["confirm"] == '1') { + delete_domain($_GET["id"]); + clean_page("index.php"); + } + include_once("inc/header.inc.php"); + $info = get_domain_info_from_id($_GET["id"]); + ?>

Delete domain ""

+ Owner:
+ Number of records in zone:

+ Are you sure?

+ &confirm=1'" VALUE="Yes"> &confirm=0'" VALUE="No"> + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: delete_record.php,v 1.5 2002/12/10 01:29:47 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +if ($_GET["id"]) { + if ($_GET["confirm"] == '0') { + clean_page("edit.php?id=".$_GET["domain"]); + } elseif ($_GET["confirm"] == '1') { + delete_record($_GET["id"]); + clean_page("edit.php?id=".$_GET["domain"]); + } + include_once("inc/header.inc.php"); + ?>

Delete record ""

You are trying to delete a record that is needed for this zone to work.
"; + } + ?>
Are you sure?

+ &confirm=1'" VALUE="Yes"> &confirm=0'" VALUE="No"> + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: delete_user.php,v 1.9 2003/01/01 22:33:46 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +$id = ($_POST["id"]) ? $_POST["id"] : $_GET["id"]; + +if(isset($id)) +{ + if($_POST["confirm"] == '1') + { + $domain = is_array($_POST["domain"]) ? $_POST["domain"] : $domain = array(); + $delete = is_array($_POST["delete"]) ? $_POST["delete"] : $delete = array(); + + if(count($domain) > 0) + { + foreach ($domain as $dom => $newowner) + { + if (!in_array($dom, $delete)) + { + add_owner($dom, $newowner); + } + } + } + if(count($delete) > 0) + { + foreach ($delete as $del) + { + delete_domain($del); + } + } + + delete_user($id); + clean_page($BASE_URL . $BASE_PATH . "users.php"); + } + include_once("inc/header.inc.php"); + ?>

Delete user ""

+
+ 0) + { + ?>This user has access to the following domain(s):
+ + +
DeleteNameNew owner
"> NAME="delete[]" VALUE="">
getOne("select count(id) from zones where owner=$id")) != 0) + { + $message .= " This user has access to $numrows domain(s), by deleting him you will also delete these domains"; + } + + ?> +


+ + +
+ + 6 was left out. Broken + +2003-02-24 00:32 azurazu + + * inc/record.inc.php: SOA Fixed + +2003-02-23 22:32 azurazu + + * edit.php: Removed the add or remove users gimmics for level1 + users + +2003-02-23 22:31 azurazu + + * inc/dns.inc.php: MX Fixme + +2003-02-23 22:30 azurazu + + * inc/record.inc.php: SOA fix + +2003-02-23 22:29 azurazu + + * inc/toolkit.inc.php: Email check had an error.. long live .museum + tld's + +2003-02-14 23:58 azurazu + + * seq_update.php: hit me please. + +2003-02-14 23:11 azurazu + + * seq_update.php: fixed the _seq table problem + +2003-02-14 23:01 azurazu + + * inc/dns.inc.php: dmnd noticed some bugs with SOA, thanks a lot :) + +2003-02-06 00:23 azurazu + + * inc/header.inc.php: removed some blank lines + +2003-02-06 00:22 azurazu + + * users.php: removed header error after adding users + +2003-02-05 23:24 azurazu + + * inc/dns.inc.php: Allowed '-' in urls useful for cgi-bin or so:) + +2003-02-05 23:22 azurazu + + * index.php: operator && should be || on line 67.. + +2003-02-05 16:25 azurazu + + * add_record.php: Dynamically updating of TTL or DEFAULT_TTL was + borked + +2003-01-13 23:08 azurazu + + * inc/auth.inc.php: DOS Format.. + +2003-01-13 00:03 azurazu + + * users.php: Cosmetics, moved the active to the middle + +2003-01-12 23:43 azurazu + + * edit.php, index.php: Added the MASTER/SLAVE information and + cleaned up code + +2003-01-12 23:42 azurazu + + * inc/config-block.inc.php: New toggle + +2003-01-12 23:39 azurazu + + * inc/record.inc.php: A lot of changes, it might really screw up :/ + +2003-01-12 21:20 azurazu + + * style/style.css.php: New style added to override the table + +2003-01-10 00:26 azurazu + + * index.php, seq_update.php, users.php: Added navigation and + navigation checks, also changed layout here and there a tiny bit + +2003-01-10 00:25 azurazu + + * inc/footer.inc.php: New version, new footer :) + +2003-01-10 00:24 azurazu + + * inc/record.inc.php: Added search_record function to support the + search of records or domains + +2003-01-10 00:23 azurazu + + * search.php: search.php, to allow you too search through your + files, thanks to DeViCeD + +2003-01-09 17:23 azurazu + + * docs/ChangeLog: Changes, as usual :) + +2003-01-09 17:15 azurazu + + * edit.php: Fixed two stupid bugs in edit.php, you couldnt add + users + +2003-01-08 01:40 azurazu + + * test_setup.php: Kicked out the nice binary stuff, ah well.. hehe + and changed ti to a variable array, just as handy I would say, also + removed the _seq table checks which arent needed if this is ran the + first time or alike, thanks to our bug reporters + +2003-01-08 00:46 azurazu + + * migrator.php-pa: Heavily modified, build in check so that if your + domains tablei s filled already it will nicely work etc. + +2003-01-08 00:41 lyon + + * inc/: footer.inc.php, toolkit.inc.php: added a check for + install.php and migrator .php. error if the exist( security) added + a little "$db is actually an object" check in the footer + +2003-01-08 00:29 lyon + + * install.php: added a config check + +2003-01-08 00:20 lyon + + * install.php: Did some addslashes/stripslashes magic. made the + warning to delete the install.php a bit clearer. Fixed the error + function (first commit by me, w00t) + +2003-01-02 00:13 azurazu + + * inc/footer.inc.php: New version + +2003-01-01 23:39 azurazu + + * docs/TODO: removed some issues + +2003-01-01 23:36 azurazu + + * edit.php, edit_record.php, index.php, inc/header.inc.php: Made + w3c happier :) + +2003-01-01 23:34 azurazu + + * users.php: Added some features on the TODO (Name validation etc.) + +2003-01-01 23:33 azurazu + + * delete_user.php, inc/users.inc.php: Fixed the deletion of users + and cleaned up the source + +2002-12-31 18:35 azurazu + + * users.php: Added that password, fullname, email and username MUST + BE filled in + +2002-12-31 04:23 azurazu + + * install.php: New installer + +2002-12-31 04:13 azurazu + + * inc/toolkit.inc.php: Small bug in xs, thanks neetmans + +2002-12-31 02:17 azurazu + + * docs/: CHANGELOG, ChangeLog: Updated the ChangeLog + +2002-12-31 01:59 azurazu + + * migrator.php-pa: Added the migrator tool + +2002-12-31 01:56 azurazu + + * index.php: Build in security check to see if a database is + converted or not + +2002-12-31 01:55 azurazu + + * seq_update.php: Removed a newbie string + +2002-12-31 01:53 azurazu + + * docs/README-Sequence: Sequence updater documentation + +2002-12-31 01:53 azurazu + + * docs/README: Changes for 1.2 + +2002-12-31 01:47 azurazu + + * migrator.php-pa: migration tool + +2002-12-30 20:06 azurazu + + * install.php: Changed it for the new version + +2002-12-27 03:48 azurazu + + * delete_user.php: Function rename + +2002-12-27 03:48 azurazu + + * edit.php: Fixed it so you can assign owners to a domain and also + delete them + +2002-12-27 03:47 azurazu + + * seq_update.php: Removed an echo, sloppy + +2002-12-27 03:45 azurazu + + * inc/auth.inc.php: Added some functions to make error reporting + happier + +2002-12-27 03:45 azurazu + + * inc/database.inc.php: Some formatting probs + +2002-12-27 03:41 azurazu + + * inc/footer.inc.php: This will be version 1.2 not 1.1.3 + +2002-12-27 03:40 azurazu + + * inc/record.inc.php: added delete_owner and changed change_owner + to add_owner to support multi ownage features and domains table + +2002-12-27 03:16 azurazu + + * inc/toolkit.inc.php: Error handling in xs removed + +2002-12-24 21:33 azurazu + + * edit.php, users.php: Inserted domains table + +2002-12-24 20:46 azurazu + + * inc/: db.inc.php, record.inc.php: File is totally deprecated + +2002-12-21 01:50 azurazu + + * seq_update.php: It was one big bug! How the heck could this + happen + +2002-12-20 20:17 azurazu + + * inc/auth.inc.php: Dirty QUERY_STRING bug + +2002-12-18 02:13 azurazu + + * delete_domain.php: Quickly added a ERROR define + +2002-12-18 02:09 azurazu + + * index.php, seq_update.php: Added sequene number updater. Fixed + your database in case you do manual inserts + +2002-12-18 02:08 azurazu + + * test_setup.php: Build a better test_setup + +2002-12-18 01:37 azurazu + + * style/style.css.php: Added two style definitions: message and + messagetable + +2002-12-18 01:36 azurazu + + * inc/toolkit.inc.php: Added message function + +2002-12-17 16:20 sjeemz + + * inc/footer.inc.php: Changed our website (again) + +2002-12-17 16:17 sjeemz + + * inc/footer.inc.php: Changed our website + +2002-12-17 16:16 azurazu + + * docs/README: Added a story about PEAR + +2002-12-17 00:16 azurazu + + * inc/footer.inc.php: CVS version + +2002-12-17 00:01 azurazu + + * inc/dns.inc.php: MAJOR, really MAJOR regexp changes + +2002-12-16 01:42 azurazu + + * inc/toolkit.inc.php: Added footer to error + +2002-12-16 01:38 azurazu + + * docs/ChangeLog: GNU Style ChangeLog + +2002-12-16 01:26 azurazu + + * edit_record.php: Fixed TTL bug + +2002-12-16 01:20 azurazu + + * inc/toolkit.inc.php: Fixed a cough small cough is_valid_email + return bug + +2002-12-16 01:09 azurazu + + * inc/dns.inc.php: Geez dumb bug, left a var_dump + +2002-12-16 00:43 azurazu + + * install.php: Small bug, thanks l0ngb0ng + +2002-12-14 17:32 azurazu + + * inc/dns.inc.php: Typo.. + +2002-12-14 17:26 azurazu + + * inc/dns.inc.php: Added wildcard records functionality, thanks + oscar + +2002-12-14 02:27 azurazu + + * docs/REDHAT-README: Dirty Fix + BUG Description for RedHat 8.0 + +2002-12-14 02:26 azurazu + + * inc/dns.inc.php: is_valid_mx was borking with prio modifications, + thanks to oscar + +2002-12-14 01:52 azurazu + + * install.php: RedHat BUG + +2002-12-14 01:07 azurazu + + * install.php: Newline error? + +2002-12-10 02:30 azurazu + + * style/style.css.php: Headers etc + +2002-12-10 02:28 azurazu + + * test_setup.php: Changed it for PEAR, headers added aswell + +2002-12-10 02:27 azurazu + + * users.php, add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, install.php: And made an error, DOH + +2002-12-10 02:26 azurazu + + * add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, install.php, users.php: And added ID + +2002-12-10 02:24 azurazu + + * add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, install.php: Added license and headers + +2002-12-10 01:55 azurazu + + * inc/: auth.inc.php, database.inc.php, dns.inc.php, error.inc.php, + footer.inc.php, header.inc.php, record.inc.php, toolkit.inc.php, + users.inc.php: Added license information and headers + +2002-12-10 01:45 azurazu + + * inc/auth.inc.php: Added fancy header (test:P) + +2002-12-10 01:31 azurazu + + * inc/error.inc.php: Added errors + +2002-12-10 01:31 azurazu + + * inc/dns.inc.php: Changed is_valid_hostname and is_valid_soa + +2002-12-09 23:52 azurazu + + * inc/dns.inc.php: DNS Function enhancements (return values) + +2002-12-09 23:51 azurazu + + * inc/error.inc.php: Added errors + +2002-12-09 22:19 azurazu + + * inc/users.inc.php: Typo + +2002-12-04 02:51 azurazu + + * install.php: Modifications all over... the script was weak in + general. Added some sort of support for pgsql but its not + implemented, just queries are there + +2002-12-03 23:12 azurazu + + * docs/TODO: Changed the layout and added a few things + +2002-12-03 23:11 azurazu + + * inc/users.inc.php: Removed is_valid_email and changed + implementation + +2002-12-03 23:11 azurazu + + * inc/dns.inc.php: changed the function order and added some + comments + +2002-12-03 23:10 azurazu + + * inc/toolkit.inc.php: moved is_valid_email to toolkit + +2002-12-03 01:04 azurazu + + * inc/dns.inc.php: Finalized a big part of the checking. + +2002-12-03 01:03 azurazu + + * inc/users.inc.php: Build is_valid_email functionality + +2002-12-02 22:05 azurazu + + * inc/config-block.inc.php: Added fancy records toggle + +2002-12-02 21:41 azurazu + + * docs/TODO: Changes + +2002-11-30 02:16 azurazu + + * inc/toolkit.inc.php: Another newline bug.. bah + +2002-11-30 00:11 azurazu + + * inc/dns.inc.php: Newline problems and NS validation added + +2002-11-29 23:32 azurazu + + * inc/dns.inc.php: Splitted up and worked stuff out not bug free + yet I think + +2002-11-29 23:18 azurazu + + * inc/record.inc.php: Bug Fix + +2002-11-26 01:09 azurazu + + * users.php: Added ERR_LEVEL_10 + +2002-11-26 01:05 azurazu + + * inc/dns.inc.php: Removed a bug + +2002-11-26 01:05 azurazu + + * inc/footer.inc.php: Added URL + +2002-11-26 01:04 azurazu + + * inc/record.inc.php: Removed two bugs + +2002-11-26 01:02 azurazu + + * inc/config-block.inc.php: Added 3 fields and removed deprecated + stuff + +2002-11-25 22:01 azurazu + + * delete_user.php, edit_user.php: Changed the name of + get_name_from_userid to get_fullname_from_userid + +2002-11-25 22:00 azurazu + + * inc/error.inc.php: Fixed a DUMB error in error.. d'oh and added + some more + +2002-11-25 21:59 azurazu + + * inc/users.inc.php: Implemented comments and error handling in + users.inc.php + +2002-11-25 21:11 azurazu + + * inc/: error.inc.php, toolkit.inc.php: Added error define + functionality + +2002-11-25 21:09 azurazu + + * inc/record.inc.php: Added documentation for each function and + changed the error processing to a file called error.inc.php + +2002-11-25 19:16 azurazu + + * docs/TODO: [no log message] + +2002-11-25 18:35 azurazu + + * inc/dns.inc.php: Allow the notation of + 12.8/123.123.123.123.in-addr.arpa in the validators. Thanks to mijo + for reporting this bug + +2002-11-25 18:30 azurazu + + * inc/: record.inc.php, users.inc.php: Major modifications and bug + fixes. Also added comments + +2002-11-21 23:40 azurazu + + * inc/record.inc.php: Removed some comment crap + +2002-11-21 23:39 azurazu + + * inc/dns.inc.php: Fixed some prio bugs + +2002-11-21 23:26 azurazu + + * inc/: dns.inc.php, record.inc.php: Build in basic record + validation, not totally done yet. Moved the validation function to + dns.inc.php + +2002-11-05 00:57 azurazu + + * inc/record.inc.php: I dont get the errors (one e ok) but the rest + is just stupid Windows probly :/ + +2002-11-05 00:38 azurazu + + * delete_user.php, index.php: Small bug fixes and enhancements + +2002-11-05 00:35 azurazu + + * inc/record.inc.php: Heavy modifications and _STUPID_ bugfixes, + really checkout the CVS + +2002-11-03 16:07 azurazu + + * inc/dns.inc.php: Fixed a nasty bug in is_valid_hostname + +2002-10-30 01:04 azurazu + + * inc/: dns.inc.php, record.inc.php: A lot of changes for + validation. Has to be split up still but testing purposes first. + Not done yet + +2002-10-28 13:45 sjeemz + + * docs/TODO: modified TODO file + +2002-10-28 02:57 azurazu + + * inc/record.inc.php: Fixed several small bugs + +2002-10-28 02:56 azurazu + + * inc/dns.inc.php: Fixed even better ipv4 check (oneliner) and + added function validate_record + +2002-10-27 23:00 azurazu + + * docs/TODO: Removed database changes - see changelog + +2002-10-27 20:22 azurazu + + * add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, users.php: Changing because of db.inc.php to + toolkit.inc.php + +2002-10-27 20:20 azurazu + + * inc/footer.inc.php: Changed closing database system + +2002-10-27 20:19 azurazu + + * inc/: auth.inc.php, dns.inc.php, record.inc.php, toolkit.inc.php, + users.inc.php: Clean up of db.inc.php + +2002-10-27 20:18 azurazu + + * inc/: dal.inc.php, database.inc.php: Database Abstraction Layer + and implementation + +2002-10-27 20:17 azurazu + + * inc/config-block.inc.php: Changed mysql fields to db fields + +2002-10-27 20:12 azurazu + + * docs/CHANGELOG: Changed a few things + +2002-10-26 23:38 azurazu + + * docs/TODO: Added 2 remarks + +2002-10-25 22:20 azurazu + + * add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, install.php, test_setup.php, users.php, docs/CHANGELOG, + docs/README, docs/TODO, images/background.jpg, images/delete.gif, + images/edit.gif, inc/config-block.inc.php, inc/db.inc.php, + inc/footer.inc.php, inc/header.inc.php, style/style.css.php: + PowerAdmin initial source code submit + +2002-10-25 22:20 azurazu + + * add_record.php, delete_domain.php, delete_record.php, + delete_user.php, edit.php, edit_record.php, edit_user.php, + index.php, install.php, test_setup.php, users.php, docs/CHANGELOG, + docs/README, docs/TODO, images/background.jpg, images/delete.gif, + images/edit.gif, inc/config-block.inc.php, inc/db.inc.php, + inc/footer.inc.php, inc/header.inc.php, style/style.css.php: + Initial revision + diff -r 2cd8c1649ba9 -r 58094faf794d docs/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/README Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,178 @@ +1. What is PowerAdmin +------------------------------ + +PowerAdmin is a non commercial front-end for the PowerDNS (www.powerdns.com) nameserver. +The goal of PowerAdmin is to manage the (MySQL) database behind PowerDNS, which contains +the DNS records. + +There have been some changes in this release, both of major and minor importance. +Please read the following document to familiarize yourself with them. You are also +requested to report any bugs should you encounter them. + + + +2. Where to get PowerAdmin +------------------------------ + +The main location of PowerAdmin is http://www.poweradmin.org + + + +3. Notes +------------------------------ + + +3.1 Migrating +------------------------------ + +If you are running a stone-age version of PowerAdmin read the following information! + +Due to some major changes in this release the current version of PowerAdmin +supports gmysql backend. You are strongly advised to backup your data before running the +migrator.php tool in your poweradmin directory. This is to protect you against any data +loss should anything go wrong. We assume it all works properly, but due to a limited +number of betatesters we cannot guarantee our tool is 100% bug free. + +!! Please be sure you have a working backup of your data !! + +Do the following to migrate: +- rename the file migrator.php-pa in your webdir to migrator.php. +- Go here to migrate it. +It is recommended to synchronize your database aswell after the update + + +3.2 DB Information +------------------------------ + +For now on PowerAdmin supports PowerDNS' MySQL back-end only. If there is demand for other +database layers support will be added in the near future. Of course, since the code is opensource, +everyone who cannot wait is encouraged to plug in their own database layer (and if you dare, send the +code to us so we can evaluate it and maybe integrate it with the current PowerAdmin). +We are still busy with PostGreSQL, but the experience needs a bit more tweaking for us. +Time will release it, we cannot yet. + +By using PEAR::DB we are bound to have some way to keep track of indexes. This is done by using seperate +tables called users_seq and zones_seq. Also records_seq will be there. This means that if you manually +insert a record, chances are 90% that you will have corrupted workings of PowerAdmin (because the ID is +not in order.) The problem can be solved by running the Synchronize Database tool (select it or use the +seq_update.php url). This will let you resynch your indexes. It is also useful if you are migrating +from 1.0 to 1.1 or higher. + +Read more about this in README-Sequence + + +4. Documentation +------------------------------ + +PowerAdmin has the following core features: + +- User Level dependant editing of domains. For example an administrator + can edit all domains, while a user can for example only edit the domain(s) + owned by him/her. + +- Simple administration of users that can access PowerAdmin. + +- Easy creating of domains. Next of that, the proper assignment of rights + is simply and done within a few clicks. + +- Ability to apply a record-template when creating domains. For now, the template + can only be configured in the config file, but this will be moved to a nice + database-table soon. + +- Editting records in existing zones. + + +5. Installation +------------------------------ + +!! If you are updating, you should necessarily read paragraph 3 !! + +What you need: +- PowerDNS (Duh!) (Versions 2.1 through 2.6 have been tested, others might work aswell) + http://www.powerdns.com/ +- MySQL + http://www.mysql.com/ +- An (Apache) webserver that supports php4 and php4-mysql. The PHP version must be at least 4.2.1. + http://www.apache.org/ + http://www.php.net/ + +First of all, install PowerDNS with it's MySQL Generic back-end. + +Next to the MySQL user you created for PowerDNS, you need a MySQL user for PowerAdmin that can do +the following actions on the PowerDNS database you created: SELECT, INSERT, DELETE, UPDATE, CREATE. + +Untar/gzip poweradmin-VERSION.tar.gz in your webdir. This will create a directory called +poweradmin-VERSION. + +In the 'inc' subdirectory of your newly created directory, you'll find a file called +config-block.inc.php. Edit this file to suit your environment. Then rename it to +config.inc.php to be able to load the site. The website will not work properly without a config, +so pay attention to your configuration! + +Next, go to http://www.yourdomain.com/poweradmin-VERSION/install.php + +Fill in the required information to make an administrator login for your +PowerAdmin. If all goes well, the user is made, and you can log in using that username. +WARNING! Be sure to remove install.php from the webdir! + +After you are done, run http://www.yourdomain.com/poweradmin-VERSION/test_setup.php to see if +everything is set up well. +This test also includes the functionality testing of your PowerDNS records (whether you +have read/write access or not) + + +6. User levels explained +------------------------------ +User levels explained: + +[x] = yes +[ ] = no + +User Permission to Permission to Permission to Permission to +Level change own change other create domains add/modify + domain(s) domain(s) users + + 1 [x] [ ] [ ] [ ] + 5 [x] [x] [x] [ ] + 10 [x] [x] [x] [x] + + +7. Further Info && Bugs +------------------------------ + +The latest contact information can always be found at http://www.poweradmin.org . + + +8. Links and more information +------------------------------ + +http://www.poweradmin.org Our main site +http://www.powerdns.com PowerDNS +http://www.ietf.org Information about DNS +http://poweradmin.sf.net PowerAdmin @ SourceForge +http://www.apache.org/ The Apache Webserver +http://www.php.net/ PHP programming language +http://www.mysql.com/ MySQL database server + +9. Changes +------------------------------ + +Changes for this version are: +- Many many many bug fixes! +- Enhanced sequence updater that is now smarter. +- SOA Fields fixed. +- Automatically SOA serial updating after each change in the DNS. +- MASTER/SLAVE Functionality but that stays untested at the moment of writing. + Use the toggles with care, see the config-block.inc.php for more information. +- Search abilities added thanks to DeViCeD +- A lot of other stuff and minor details not worth mentioning that much. + + +-------------------------------------------------------------------------- +Enjoy! + +There are some major changes, we would like feedback! +See paragraph 7 for contact information. + +Regards, +The PowerAdmin Team diff -r 2cd8c1649ba9 -r 58094faf794d docs/README-Sequence --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/README-Sequence Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,60 @@ +1. What is the Sequence Updater +------------------------------- + +The Sequence updater is written to synchronize your PowerAdmin/DNS database +after you have manually inserted records into it. + +2. Why do I need that? +------------------------------- + +Because PowerAdmin uses the php-PEAR::DB library it is using sequence numbers. +A sequence number simply tells the application what will be the next ID +for insertion. Some of the mysql users are now shouting auto_increment. +Yes auto_increment, but we cant use this here because we plan to use +PostGreSQL or Other db's that dont have auto_increment so we are stuck to +using sequence numbers. + +3. What does this mean? +------------------------------- + +This means that if you dont run this tool after you have been manually adding +records, your database might be corrupted and PowerAdmin might be kicking +you back with a lot of errors. + +4. Ok, I got it, now what? +------------------------------- + +Put this file in your PowerAdmin directory. Login into PowerAdmin using the normal +system. Now go to the url where you put it and done, the sequence numbers are +updated. + +5. Future versions +------------------------------- + +In all versions higher than 1.1.2 this function will be automatically there for +administrators. + +6. Contact + +6. Further Info && Bugs +------------------------------ + +To contact us we refer you to http://www.poweradmin.org/ for the latest +contact information. + +7. Links and more information +------------------------------ + +http://www.poweradmin.org l Our main site +http://www.powerdns.com PowerDNS +http://www.ietf.org Information about DNS +http://poweradmin.sf.net PowerAdmin @ SourceForge +http://www.apache.org/ The Apache Webserver +http://www.php.net/ PHP programming language +http://www.mysql.com/ MySQL database server + +-------------------------------------------------------------------------- + +Regards, +The PowerAdmin Team + diff -r 2cd8c1649ba9 -r 58094faf794d docs/REDHAT-README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/REDHAT-README Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,88 @@ +RedHat 8.0 BUG and howto 'fix' + +Ok it seems to be that there is some bug in PowerAdmin (for now we assume so). +It is currently reported all on RedHat 8.0 machines. + +The bug seems to be appear when Apache 2.0 is being used with the default +installed PHP RPM on the platform. New shapshots might remove this bug. We havent +tested this yet. If you have any more insights on this bug please email us +at info@poweradmin.sjeemz.nl + +We kindly refer you to http://bugs.php.net/bug.php?id=18648 +We havent tested this out fully yet! Not even the fix since we arent native +RedHat users. + +Quick dirty fix. We just avoid the bug by not using php :) + +NOTE: THIS IS A MYSQL FIX! + +Ok what to do: + +- Login to mysql using the poweradmin account information. +- Issue the following queries: + + +/**************** + * USER TABLE * + ***************/ + +CREATE TABLE users ( +id int(11) NOT NULL, +username varchar(16) NOT NULL default '', +password varchar(255) NOT NULL default '', +fullname varchar(255) NOT NULL default '', +email varchar(255) NOT NULL default '', +description text NOT NULL, +level tinyint(4) NOT NULL default '0', +active tinyint(4) NOT NULL default '0', +PRIMARY KEY (id) +) TYPE=MyISAM; + +/**************** + * ZONES TABLE * + ***************/ + +CREATE TABLE zones ( +id int(11) NOT NULL, +name varchar(255) NOT NULL default '', +owner int(11) NOT NULL default '0', +comment text NOT NULL, +PRIMARY KEY (id) +) TYPE=MyISAM; + + + +/************************ + * INSTALL YOURSELF * + ***********************/ + +- $login == your prefered login +- $full == your fullname +- $pass == your prefered password +- $email == your prefered email +- $desc == your prefered description + +INSERT INTO users VALUES (1,'$login',md5('$pass'),'$full','$email','$description',10,1) + +Example +INSERT INTO users VALUES (1,'trance',md5('test'),'me','trancer@nospam.trancer.nl','its me!',10,1); + +- Ok, now we have a problem. PowerAdmin uses PEAR. And to remain independent PEAR has +its own incrementation functions. For this there is a seperate table. We didnt use pear yet, therefore +the current setup is inconsistent with what pear is thinking (you are one id behind). +We now have to setup a users_seq table for this. + + +CREATE TABLE users_seq ( + id int(10) unsigned NOT NULL auto_increment, + PRIMARY KEY (id) +) TYPE=MyISAM; + +INSERT INTO users_seq VALUES (1); + + +Done! It should now work. If you encounter any problems feel free to email us, also monitor the website +bugfixes might come available. + +Roeland, PowerAdmin Team + diff -r 2cd8c1649ba9 -r 58094faf794d docs/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/TODO Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,26 @@ +The TODO isnt much atm, to be fixed in the feature using a bug tracker. +The documentation has to be converted to docbook or a similar format. + +Legenda: + + = useful option, or not too hard to implement, should be implemented in time. + - = might be useful but time consuming and maybe a bit overkill. Nice if we have time left :) + * = being worked on + + +- Add some more webbased support for those who dont know DNS. + -- disable priority when adding IN A (JavaScript) + +- put the template(s) in database. + -- Multilanguage support is an option? + +- logging functionality + +- accept email/url when adding new domains. + +- add support for more pdns backends + *- Move error codes to defined file. + -- a little checkbox that would state: create corresponding PTR record + -- change the listing order (Ian's remark) +Priority: + +- slave master functionality, also includes issue below + +- mijo requested a function so that SOA records serials would be auto incremented. This in combination with bind + backends that require so + +- fix multidatabase install.php + +- Document security issues on mysql level. + + diff -r 2cd8c1649ba9 -r 58094faf794d edit.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edit.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,279 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: edit.php,v 1.12 2003/05/10 20:10:47 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +// Assigning records to user: Check for records owned by user + +if (isset($_POST["action"]) && $_POST["action"]=="record-user") { + foreach ($_POST["rowid"] as $x_user => $x_value){ + $x_userid = $db->getOne("SELECT id FROM record_owners WHERE user_id = '".$_POST["userid"]."' AND record_id='".$x_value."'"); + if (empty($x_userid)) { + $db->query("INSERT INTO record_owners SET user_id = '".$_POST["userid"]."',record_id='".$x_value."'"); + } + } +} + +$server_types = array("MASTER", "SLAVE", "NATIVE"); + +if(isset($_POST['type_change']) && in_array($_POST['newtype'], $server_types)) +{ + change_domain_type($_POST['newtype'], $_GET['id']); +} +if(isset($_POST["newowner"]) && is_numeric($_POST["domain"]) && is_numeric($_POST["newowner"])) +{ + add_owner($_POST["domain"], $_POST["newowner"]); +} + +if(isset($_POST["del_user"]) && is_numeric($_POST["del_user"]) && level(5)) +{ + delete_owner($_GET["id"], $_POST["del_user"]); +} + +include_once("inc/header.inc.php"); +?> +

Edit domain ""

+ +

This domain isnt owned by anyone yet, please assign someone

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Add an owner: + "> + + + +
 
+ Current listed owners: +
+ + + "> + +
 
Type of this domain:
Change type: + + + +
+
+ +DNS Admin >> + +

Number of records: + + + +

+ +
?id=" method="post"> + + + + + + + Sub-Owners"; } ?> + + + + + + + + + + + + + + + + + + +
 NameTypeContentPriorityTTL
+ ">[ edit record ] + ">[ delete record ] + + + + + +query("SELECT r.user_id,u.username FROM record_owners as r, users as u WHERE r.record_id='".$r['id']."' AND u.id=r.user_id"); +echo ""; +?> +
No records for this domain
+ + +
+ +arrow + + + +
+ + +

+ + +'" VALUE="Add record"> + + +  '" VALUE="Delete zone"> diff -r 2cd8c1649ba9 -r 58094faf794d edit_record.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edit_record.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,123 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: edit_record.php,v 1.9 2003/05/14 22:48:13 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +if (isset($_GET["delid"])) { + $db->query("DELETE FROM record_owners WHERE id='".$_GET["delid"]."'"); +} + +$xsid = (isset($_GET['id'])) ? $_GET['id'] : $_POST['recordid']; + +if(!xs(recid_to_domid($xsid))) +{ + error(ERR_RECORD_ACCESS_DENIED); +} + +/* +if($_SESSION["partial_".get_domain_name_from_id($_GET["domain"])] == 1 && !isset($_POST["recordid"])) +{ + $checkPartial = $db->getOne("SELECT id FROM record_owners WHERE record_id='".$_GET["id"]."' AND user_id='".$_SESSION["userid"]."' LIMIT 1"); + if (empty($checkPartial)) { + error(ERR_RECORD_ACCESS_DENIED); + } +} +*/ + +if ($_POST["commit"]) +{ + edit_record($_POST["recordid"], $_POST["domainid"], $_POST["name"], $_POST["type"], $_POST["content"], $_POST["ttl"], $_POST["prio"]); + clean_page("edit.php?id=".$_POST["domainid"]); +} elseif($_SESSION["partial_".get_domain_name_from_id($_GET["domain"])] == 1) +{ + $checkPartial = $db->getOne("SELECT id FROM record_owners WHERE record_id='".$_GET["id"]."' AND user_id='".$_SESSION["userid"]."' LIMIT 1"); + if (empty($checkPartial)) { + error(ERR_RECORD_ACCESS_DENIED); + } +} + + +include_once("inc/header.inc.php"); + +?> +

Edit record in zone ""

+
DNS Admin >> "> >> Edit record

+ +
+"> +"> + + + + + + +
Name TypePriorityContentTimeToLive
+ + + +" CLASS="input"> + + + +" CLASS="input"> + +.IN" CLASS="sinput">" CLASS="input">" CLASS="sinput">
+
   +
+ + + + +query("SELECT r.id,u.username FROM record_owners as r, users as u WHERE r.record_id='".$_GET['id']."' AND u.id=r.user_id"); +while ($x_r = $x_result->fetchRow()) { + echo ""; +} +?> +
Sub-users
".$x_r["username"].""; + echo ""; + echo "\"trash\"
+ diff -r 2cd8c1649ba9 -r 58094faf794d edit_user.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edit_user.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,84 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: edit_user.php,v 1.6 2002/12/10 01:29:47 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +if($_POST["commit"]) +{ + if($_POST["username"] && $_POST["level"] && $_POST["fullname"]) + { + if(!isset($_POST["active"])) + { + $active = 0; + } + else + { + $active = 1; + } + if(edit_user($_POST["number"], $_POST["username"], $_POST["fullname"], $_POST["email"], $_POST["level"], $_POST["description"], $active, $_POST["password"])) + { + clean_page($BASE_URL . $BASE_PATH . "users.php"); + } + else + { + error("Error editting user!"); + } + } +} + +include_once("inc/header.inc.php"); + +if (!level(10)) +{ + error("You need user level 10 to view this page... How did you get here, anyway?"); +} + +?> +

Edit user ""

+ +
User Admin >> Edit User


+ +
+ + + + + + + + + +"> +
User name:">
Full name:">
Password:
E-mail:">
User level:
Description:
Active:CHECKED>
 
+
+ diff -r 2cd8c1649ba9 -r 58094faf794d images/arrow.png Binary file images/arrow.png has changed diff -r 2cd8c1649ba9 -r 58094faf794d images/background.jpg Binary file images/background.jpg has changed diff -r 2cd8c1649ba9 -r 58094faf794d images/delete.gif Binary file images/delete.gif has changed diff -r 2cd8c1649ba9 -r 58094faf794d images/edit.gif Binary file images/edit.gif has changed diff -r 2cd8c1649ba9 -r 58094faf794d inc/BAKrecord.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/BAKrecord.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,1084 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: record.inc.php +// Startdate: 26-10-2002 +// This file is ought to edit the records in the database. +// Records are domains aswell, they also belong here. +// All database functions are associative. +// use nextID first to get a new id. Then insert it into the database. +// do not rely on auto_increment (see above). +// use dns.inc.php for validation functions. +// +// $Id: record.inc.php,v 1.21 2003/05/10 20:21:01 azurazu Exp $ +// + + +function update_soa_serial($domain_id) +{ + global $db; + /* + * THIS CODE ISNT TESTED THROUGH MUCH YET! + * !!!!!!! BETACODE !!!!!!!!!! + * Code committed by DeViCeD, Thanks a lot! + * Heavily hax0red by Trancer/azurazu + * + * First we have to check, wheather current searial number + * was already updated on the other nameservers. + * If field 'notified_serial' is NULL, then I guess domain is + * NATIVE and we don't have any secondary nameservers for this domain. + * NOTICE: Serial number *will* be RFC1912 compilant after update + * NOTICE: This function will allow only 100 DNS zone transfers ;-) + * YYYYMMDDnn + */ + + $sqlq = "SELECT `notified_serial` FROM `domains` WHERE `id` = '".$domain_id."'"; + $notified_serial = $db->getOne($sqlq); + + $sqlq = "SELECT `content` FROM `records` WHERE `type` = 'SOA' AND `domain_id` = '".$domain_id."'"; + $content = $db->getOne($sqlq); + $need_to_update = false; + + // Getting the serial field. + $soa = explode(" ", $content); + + if(empty($notified_serial)) + { + // Ok native replication, so we have to update. + $need_to_update = true; + } + elseif($notified_serial >= $soa[2]) + { + $need_to_update = true; + } + elseif(strlen($soa[2]) != 10) + { + $need_to_update = true; + } + else + { + $need_to_update = false; + } + if($need_to_update) + { + // Ok so we have to update it seems. + $current_serial = $soa[2]; + + /* + * What we need here (for RFC1912) is YEAR, MONTH and DAY + * so let's get it ... + */ + $new_serial = date('Ymd'); // we will add revision number later + + if(strncmp($new_serial, $current_serial, 8) === 0) + { + /* + * Ok, so we already made updates tonight + * let's just increase the revision number + */ + $revision_number = (int) substr($current_serial, -2); + if ($revision_number == 99) return false; // ok, we cannot update anymore tonight + ++$revision_number; + // here it is ... same date, new revision + $new_serial .= str_pad($revision_number, 2, "0", STR_PAD_LEFT); + } + else + { + /* + * Current serial is not RFC1912 compilant, so let's make a new one + */ + $new_serial .= '00'; + } + $soa[2] = $new_serial; // change serial in SOA array + $new_soa = ""; + // build new soa and update SQL after that + for ($i = 0; $i < count($soa); $i++) + { + $new_soa .= $soa[$i] . " "; + } + $sqlq = "UPDATE `records` SET `content` = '".$new_soa."' WHERE `domain_id` = '".$domain_id."' AND `type` = 'SOA' LIMIT 1"; + $db->Query($sqlq); + return true; + } +} + +/* + * Edit a record. + * This function validates it if correct it inserts it into the database. + * return values: true if succesful. + */ +function edit_record($recordid, $zoneid, $name, $type, $content, $ttl, $prio) +{ + global $db; + if($content == "") + { + error(ERR_RECORD_EMPTY_CONTENT); + } + // Edits the given record (validates specific stuff first) + if (!xs(recid_to_domid($recordid))) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($zoneid)) + { + validate_input($recordid, $zoneid, $type, $content, $name, $prio, $ttl); + $change = time(); + $db->query("UPDATE records set name='$name', type='$type', content='$content', ttl='$ttl', prio='$prio', change_date='$change' WHERE id=$recordid"); + + /* + * Added by DeViCeD - Update SOA Serial number + * There should be more checks + */ + if ($type != 'SOA') + { + update_soa_serial($zoneid); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "edit_record", "no zoneid given")); + } + +} + + +/* + * Adds a record. + * This function validates it if correct it inserts it into the database. + * return values: true if succesful. + */ +function add_record($zoneid, $name, $type, $content, $ttl, $prio) +{ + global $db; + if (!xs($zoneid)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($zoneid)) + { + + // Get the Insert ID, we can not rely on auto_increment + $idrecords = $db->nextID('records'); + + // Check the user input. + validate_input($idrecords, $zoneid, $type, $content, $name, $prio, $ttl); + + // Generate new timestamp for the Daemon + $change = time(); + + // Execute query. + $db->query("INSERT INTO records (id, domain_id, name, type, content, ttl, prio, change_date) VALUES ($idrecords, $zoneid, '$name', '$type', '$content', $ttl, '$prio', $change)"); + if ($type != 'SOA') + { + update_soa_serial($zoneid); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARG, "add_record")); + } +} + + +/* + * Delete a record by a given id. + * return values: true, this function is always succesful. + */ +function delete_record($id) +{ + global $db; + + // Check if the user has access. + if (!xs(recid_to_domid($id))) + { + error(ERR_RECORD_ACCESS_DENIED); + } + + // Retrieve the type of record to see if we can actually remove it. + $recordtype = get_recordtype_from_id($id); + + // If the record type is NS and the user tries to delete it while ALLOW_NS_EDIT is set to 0 + // OR + // check if the name of the record isnt the domain name (if so it should delete all records) + // OR + // check if we are dealing with a SOA field (same story as NS) + if (($recordtype == "NS" && $GLOBALS["ALLOW_NS_EDIT"] != 1 && (get_name_from_record_id($id) == get_domain_name_from_id(recid_to_domid($id)))) || ($recordtype == "SOA" && $GLOBALS["ALLOW_SOA_EDIT"] != 1)) + { + error(sprintf(ERR_RECORD_DELETE_TYPE_DENIED, $recordtype)); + + } + if (is_numeric($id)) + { + $did = recid_to_domid($id); + $db->query('DELETE FROM records WHERE id=' . $id . ' LIMIT 1'); + if ($type != 'SOA') + { + update_soa_serial($did); + } + // $id doesnt exist in database anymore so its deleted or just not there which means "true" + return true; + } + else + { + error(sprintf(ERR_INV_ARG, "delete_record")); + } +} + + +/* + * Add a domain to the database. + * A domain is name obligatory, so is an owner. + * return values: true when succesful. + * Empty means templates dont have to be applied. + * -------------------------------------------------------------------------- + * This functions eats a template and by that it inserts various records. + * first we start checking if something in an arpa record + * remember to request nextID's from the database to be able to insert record. + * if anything is invalid the function will error + */ +function add_domain($domain, $owner, $webip, $mailip, $empty, $type) +{ + + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + // If domain, owner and mailip are given + // OR + // empty is given and owner and domain + // OR + // the domain is an arpa record and owner is given + // THAN + // Continue this function + if (($domain && $owner && $webip && $mailip) || ($empty && $owner && $domain) || (eregi('in-addr.arpa', $domain) && $owner)) + { + // Retrieve next zones id. + $idzones = $db->nextID('zones'); + $iddomains = $db->nextID('domains'); + + $db->query("INSERT INTO zones (id, domain_id, owner) VALUES ('$idzones', '$iddomains', $owner)"); + + /* + * TODO : NATIVE OPERATION ONLY FOR NOW + */ + + $db->query("INSERT INTO domains (id, name, type) VALUES ('$iddomains', '$domain', '$type')"); + + // Generate new timestamp. We need this one anyhow. + $now = time(); + + if ($empty && $iddomains) + { + // If we come into this if statement we dont want to apply templates. + // Retrieve configuration settings. + $ns1 = $GLOBALS["NS1"]; + $hm = $GLOBALS["HOSTMASTER"]; + $ttl = $GLOBALS["DEFAULT_TTL"]; + + // Retrieve next records id + $idrecords = $db->nextID('records'); + + // Build and execute query + $sql = "INSERT INTO records (id, domain_id, name, content, type, ttl, prio, change_date) VALUES ('$idrecords', '$iddomains', '$domain', '$ns1 $hm 1', 'SOA', $ttl, '', '$now')"; + $db->query($sql); + + // Done + return true; + } + elseif ($iddomains) + { + // If we are here we want to apply templates. + global $template; + + // Iterate over the template and apply it for each field. + foreach ($template as $r) + { + // Same type of if statement as previous. + if ((eregi('in-addr.arpa', $domain) && ($r["type"] == "NS" || $r["type"] == "SOA")) || (!eregi('in-addr.arpa', $domain))) + { + // Parse the template. + $name = parse_template_value($r["name"], $domain, $webip, $mailip); + $type = $r["type"]; + $content = parse_template_value($r["content"], $domain, $webip, $mailip); + $ttl = $r["ttl"]; + $prio = $r["prio"]; + + // If no ttl is given, use the default. + if (!$ttl) + { + $ttl = $GLOBALS["DEFAULT_TTL"]; + } + + // Retrieve new record id; + $idrecords = $db->nextID('records'); + $sql = "INSERT INTO records (id, domain_id, name, content, type, ttl, prio, change_date) VALUES ('$idrecords', '$iddomains', '$name','$content','$type','$ttl','$prio','$now')"; + $db->query($sql); + } + } + // All done. + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "add_domain", "could not create zone")); + } + } + else + { + error(sprintf(ERR_INV_ARG, "add_domain")); + } +} + + +/* + * Deletes a domain by a given id. + * Function always succeeds. If the field is not found in the database, thats what we want anyway. + */ +function delete_domain($id) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + // See if the ID is numeric. + if (is_numeric($id)) + { + $db->query("DELETE FROM zones WHERE domain_id=$id"); + $db->query("DELETE FROM domains WHERE id=$id"); + $db->query("DELETE FROM records WHERE domain_id=$id"); + // Nothing in the database. If the delete deleted 0 records it means the id is just not there. + // therefore the is no need to check the affectedRows values. + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "delete_domain", "id must be a number")); + } +} + + +/* + * Gets the id of the domain by a given record id. + * return values: the domain id that was requested. + */ +function recid_to_domid($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT domain_id FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["domain_id"]; + } + else + { + error(sprintf(ERR_INV_ARGC, "recid_to_domid", "id must be a number")); + } +} + + +/* + * Sorts a zone by records. + * return values: the sorted zone. + */ +function sort_zone($records) +{ + $ar_so = array(); + $ar_ns = array(); + $ar_mx = array(); + $ar_mb = array(); + $ar_ur = array(); + $ar_ov = array(); + foreach ($records as $c) + { + switch(strtoupper($c['type'])) + { + case "SOA": + $ar_so[] = $c; + break; + case "NS": + $ar_ns[] = $c; + break; + case "MX": + $ar_mx[] = $c; + break; + case "MBOXFW": + $ar_mb[] = $c; + break; + case "URL": + $ar_ur[] = $c; + break; + default: + $ar_ov[] = $c; + break; + } + } + + $res = array_merge($ar_so, $ar_ns, $ar_mx, $ar_mb, $ar_ur, $ar_ov); + + if (count($records) == count($res)) + { + $records = $res; + } + else + { + error(sprintf(ERR_INV_ARGC, "sort_zone", "records sorting failed!")); + } + return $records; +} + + +/* + * Change owner of a domain. + * Function should actually be in users.inc.php. But its more of a record modification than a user modification + * return values: true when succesful. + */ +function add_owner($domain, $newowner) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + if (is_numeric($domain) && is_numeric($newowner) && is_valid_user($newowner)) + { + $iid = $db->nextID('zones'); + if($db->getOne("SELECT COUNT(id) FROM zones WHERE owner=$newowner AND domain_id=$domain") == 0) + { + $db->query("INSERT INTO zones(id, domain_id, owner) VALUES($iid, $domain, $newowner)"); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "change_owner", "$domain / $newowner")); + } +} + + +function delete_owner($domain, $owner) +{ + global $db; + if($db->getOne("SELECT COUNT(id) FROM zones WHERE owner=$owner AND domain_id=$domain") != 0) + { + $db->query("DELETE FROM zones WHERE owner=$owner AND domain_id=$domain"); + } + return true; +} + +/* + * Retrieves all supported dns record types + * This function might be deprecated. + * return values: array of types in string form. + */ +function get_record_types() +{ + global $rtypes; + return $rtypes; +} + + +/* + * Retrieve all records by a given type and domain id. + * Example: get all records that are of type A from domain id 1 + * return values: a DB class result object + */ +function get_records_by_type_from_domid($type, $recid) +{ + global $rtypes; + global $db; + + // Does this type exist? + if(!in_array(strtoupper($type), $rtypes)) + { + error(sprintf(ERR_INV_ARGC, "get_records_from_type", "this is not a supported record")); + } + + // Get the domain id. + $domid = recid_to_domid($recid); + + $result = $db->query("select id, type from records where domain_id=$recid and type='$type'"); + return $result; +} + + +/* + * Retrieves the type of a record from a given id. + * return values: the type of the record (one of the records types in $rtypes assumable). + */ +function get_recordtype_from_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT type FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["type"]; + } + else + { + error(sprintf(ERR_INV_ARG, "get_recordtype_from_id")); + } +} + + +/* + * Retrieves the name (e.g. bla.test.com) of a record by a given id. + * return values: the name associated with the id. + */ +function get_name_from_record_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT name FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["name"]; + } + else + { + error(sprintf(ERR_INV_ARG, "get_name_from_record_id")); + } +} + + +/* + * Get all the domains from a database of which the user is the owner. + * return values: an array with the id of the domain and its name. + */ +function get_domains_from_userid($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT domains.id AS domain_id, domains.name AS name FROM domains LEFT JOIN zones ON domains.id=zones.domain_id WHERE owner=$id"); + + $ret = array(); + + // Put all the information in a big array. + while ($r = $result->fetchRow()) + { + $ret[] = array( + "id" => $r["domain_id"], + "name" => $r["name"] + ); + } + return $ret; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domains_from_userid", "This is not a valid userid: $id")); + } +} + + +/* + * Get domain name from a given id + * return values: the name of the domain associated with the id. + */ +function get_domain_name_from_id($id) +{ + global $db; + if (!xs($id)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($id)) + { + $result = $db->query("SELECT name FROM domains WHERE id=$id"); + if ($result->numRows() == 1) + { + $r = $result->fetchRow(); + return $r["name"]; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_name_from_id", "more than one domain found?! whaaa! BAD! BAD! Contact admin!")); + } + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_name_from_id", "Not a valid domainid: $id")); + } +} + + +/* + * Get information about a domain name from a given domain id. + * the function looks up the domainname, the owner of the domain and the number of records in it. + * return values: an array containing the information. + */ +function get_domain_info_from_id($id) +{ + global $db; + if (!xs($id)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($id)) + { + + if ($_SESSION[$id."_ispartial"] == 1) { + + $sqlq = "SELECT domains.name AS name, + users.fullname AS owner, + count(record_owners.id) AS aantal + FROM domains, users, record_owners, records + + WHERE record_owners.user_id = ".$_SESSION["userid"]." + AND record_owners.record_id = records.id + AND records.domain_id = ".$id." + + GROUP BY name, owner, users.fullname + ORDER BY name"; + + $result = $db->getRow($sqlq); + + $ret = array( + "name" => $result["name"], + "ownerid" => $_SESSION["userid"], + "owner" => $result["owner"], + "numrec" => $result["aantal"] + ); + + return $ret; + + } else{ + + // Query that retrieves the information we need. + $sqlq = "SELECT domains.name AS name, + min(zones.owner) AS ownerid, + users.fullname AS owner, + count(records.domain_id) AS aantal + FROM domains + LEFT JOIN records ON domains.id=records.domain_id + LEFT JOIN zones ON domains.id=zones.domain_id + LEFT JOIN users ON zones.owner=users.id + WHERE domains.id=$id + GROUP BY name, owner, users.fullname + ORDER BY zones.id"; + + // Put the first occurence in an array and return it. + $result = $db->getRow($sqlq); + + //$result["ownerid"] = ($result["ownerid"] == NULL) ? $db->getOne("select min(id) from users where users.level=10") : $result["ownerid"]; + + $ret = array( + "name" => $result["name"], + "ownerid" => $result["ownerid"], + "owner" => $result["owner"], + "numrec" => $result["aantal"] + ); + return $ret; + } + + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_num_records_from_id", "This is not a valid domainid: $id")); + } +} + + +/* + * Check if a domain is already existing. + * return values: true if existing, false if it doesnt exist. + */ +function domain_exists($domain) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + if (is_valid_domain($domain)) + { + $result = $db->query("SELECT id FROM domains WHERE name='$domain'"); + if ($result->numRows() == 0) + { + return false; + } + elseif ($result->numRows() >= 1) + { + return true; + } + } + else + { + error(ERR_DOMAIN_INVALID); + } +} + + +/* + * Get all domains from the database. + * This function gets all the domains from the database unless a user id is below 5. + * if a user id is below 5 this function will only retrieve records for that user. + * return values: the array of domains or -1 if nothing is found. + */ +function get_domains($userid=true,$letterstart=all,$rowstart=0,$rowamount=999999) +{ + global $db; + if((!level(5) || !$userid) && !level(10) && !level(5)) + { + $add = " AND zones.owner=".$_SESSION["userid"]; + } + else + { + $add = ""; + } + + $sqlq = "SELECT domains.id AS domain_id, + min(zones.owner) AS owner, + count(DISTINCT records.id) AS aantal, + domains.name AS domainname + FROM domains + LEFT JOIN zones ON domains.id=zones.domain_id + LEFT JOIN records ON records.domain_id=domains.id + WHERE 1 $add "; + if ($letterstart!=all && $letterstart!=1) { + $sqlq.=" AND domains.name LIKE '".$letterstart."%' "; + } elseif ($letterstart==1) { + $sqlq.=" AND "; + for ($i=0;$i<=9;$i++) { + $sqlq.="domains.name LIKE '".$i."%'"; + if ($i!=9) $sqlq.=" OR "; + } + } + $sqlq.=" GROUP BY domainname, domain_id + ORDER BY domainname + LIMIT $rowstart,$rowamount"; + + $result = $db->query($sqlq); + $result2 = $db->query($sqlq); + + $andnot=""; + while($r = $result2->fetchRow()) { + $andnot.=" AND domains.id!= '".$r["domain_id"]."' "; + } + + $sqlq = "SELECT domains.id AS domain_id, + count(DISTINCT record_owners.record_id) AS aantal, + domains.name AS domainname + FROM domains, record_owners,records, zones + WHERE record_owners.user_id = '".$_SESSION["userid"]."' + AND (records.id = record_owners.record_id + AND domains.id = records.domain_id) + $andnot "; + + if ($letterstart!=all && $letterstart!=1) { + $sqlq.=" AND domains.name LIKE '".$letterstart."%' "; + } // elseif ($letterstart==1) { +/* + $sqlq.=" AND "; + for ($i=0;$i<=9;$i++) { + $sqlq.="domains.name LIKE '".$i."%'"; + if ($i!=9) $sqlq.=" OR "; + } + } +*/ + + $sqlq.= " AND (zones.domain_id != records.domain_id AND zones.owner!='".$_SESSION["userid"]."') + GROUP BY domainname, domain_id + ORDER BY domainname"; + + $result_extra = $db->query($sqlq); + + if ($result->numRows() == 0) + { + // Nothing found. + return -1; + } + + while($r = $result->fetchRow()) + { + $r["owner"] = ($r["owner"] == NULL) ? $db->getOne("select min(id) from users where users.level=10") : $r["owner"]; + $ret[$r["domainname"]] = array( + "name" => $r["domainname"], + "id" => $r["domain_id"], + "owner" => $r["owner"], + "numrec" => $r["aantal"] + ); + } + + while($r = $result_extra->fetchRow()) + { + $ret[$r["domainname"]] = array( + "name" => $r["domainname"]."*", + "id" => $r["domain_id"], + "owner" => $_SESSION["userid"], + "numrec" => $r["aantal"] + ); + } + + sort($ret); + + return $ret; +} + + +/* + * Get a record from an id. + * Retrieve all fields of the record and send it back to the function caller. + * return values: the array with information, or -1 is nothing is found. + */ +function get_record_from_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT id, domain_id, name, type, content, ttl, prio, change_date FROM records WHERE id=$id"); + if($result->numRows() == 0) + { + return -1; + } + elseif ($result->numRows() == 1) + { + $r = $result->fetchRow(); + $ret = array( + "id" => $r["id"], + "domain_id" => $r["domain_id"], + "name" => $r["name"], + "type" => $r["type"], + "content" => $r["content"], + "ttl" => $r["ttl"], + "prio" => $r["prio"], + "change_date" => $r["change_date"] + ); + return $ret; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_record_from_id", "More than one row returned! This is bad!")); + } + } + else + { + error(sprintf(ERR_INV_ARG, "get_record_from_id")); + } +} + + +/* + * Get all records from a domain id. + * Retrieve all fields of the records and send it back to the function caller. + * return values: the array with information, or -1 is nothing is found. + */ +function get_records_from_domain_id($id,$rowstart=0,$rowamount=999999) +{ + global $db; + if (is_numeric($id)) + { + if ($_SESSION[$id."_ispartial"] == 1) { + + $result = $db->query("SELECT record_owners.record_id as id + FROM record_owners,domains,records + WHERE record_owners.user_id = ".$_SESSION["userid"]." + AND record_owners.record_id = records.id + AND records.domain_id = ".$id." + GROUP bY record_owners.record_id + LIMIT $rowstart,$rowamount"); + + $ret = array(); + if($result->numRows() == 0) + { + return -1; + } + else + { + $ret[] = array(); + $retcount = 0; + while($r = $result->fetchRow()) + { + // Call get_record_from_id for each row. + $ret[$retcount] = get_record_from_id($r["id"]); + $retcount++; + } + return $ret; + } + + } else { + + $result = $db->query("SELECT id FROM records WHERE domain_id=$id LIMIT $rowstart,$rowamount"); + $ret = array(); + if($result->numRows() == 0) + { + return -1; + } + else + { + $ret[] = array(); + $retcount = 0; + while($r = $result->fetchRow()) + { + // Call get_record_from_id for each row. + $ret[$retcount] = get_record_from_id($r["id"]); + $retcount++; + } + return $ret; + } + + } + } + else + { + error(sprintf(ERR_INV_ARG, "get_records_from_domain_id")); + } +} + + +function get_users_from_domain_id($id) +{ + global $db; + $result = $db->getCol("SELECT owner FROM zones WHERE domain_id=$id"); + $ret = array(); + foreach($result as $uid) + { + $fullname = $db->getOne("SELECT fullname FROM users WHERE id=$uid"); + $ret[] = array( + "id" => $uid, + "fullname" => $fullname + ); + } + return $ret; +} + +function search_record($question) +{ + global $db; + $question = trim($question); + if (empty($question)) + { + $S_INPUT_TYPE = -1; + } + + /* now for some input-type searching */ + if (is_valid_ip($question) || is_valid_ip6($question)) + { + $S_INPUT_TYPE = 0; + } + elseif(is_valid_domain($question) || + is_valid_hostname($question) || + is_valid_mboxfw($question)) // I guess this one can appear in records table too (content?!) + { + $S_INPUT_TYPE = 1; + } + else + { + $S_INPUT_TYPE = -1; + } + switch($S_INPUT_TYPE) + { + case '0': + $sqlq = "SELECT * FROM `records` WHERE `content` = '".$question."' ORDER BY `type` DESC"; + $result = $db->query($sqlq); + $ret_r = array(); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_r[] = array( + 'id' => $r['id'], + 'domain_id' => $r['domain_id'], + 'name' => $r['name'], + 'type' => $r['type'], + 'content' => $r['content'], + 'ttl' => $r['ttl'], + 'prio' => $r['prio'], + 'change_date' => $r['change_date'] + ); + } + } + break; + + case '1' : + $sqlq = "SELECT `domains`.*, count(`records`.`id`) AS `numrec`, `zones`.`owner` + FROM `domains`, `records`, `zones` + WHERE `domains`.`id` = `records`.`domain_id` + AND `zones`.`domain_id` = `domains`.`id` + AND `domains`.`name` = '".$question."' + GROUP BY (`domains`.`id`)"; + + $result = $db->query($sqlq); + $ret_d = array(); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_d[] = array( + 'id' => $r['id'], + 'name' => $r['name'], + 'numrec' => $r['numrec'], + 'owner' => $r['owner'] + ); + } + } + + $sqlq = "SELECT * FROM `records` WHERE `name` = '".$question."' OR `content` = '".$question."' ORDER BY `type` DESC"; + $result = $db->query($sqlq); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_r[] = array( + 'id' => $r['id'], + 'domain_id' => $r['domain_id'], + 'name' => $r['name'], + 'type' => $r['type'], + 'content' => $r['content'], + 'ttl' => $r['ttl'], + 'prio' => $r['prio'], + ); + } + } + break; + } + if($S_INPUT_TYPE == 1) + { + return array('domains' => $ret_d, 'records' => $ret_r); + } + return array('records' => $ret_r); +} + +function get_domain_type($id) +{ + global $db; + $type = $db->getOne("SELECT `type` FROM `domains` WHERE `id` = '".$id."'"); + if($type == "") + { + $type = "NATIVE"; + } + return $type; + +} + +function change_domain_type($type, $id) +{ + global $db; + $result = $db->query("UPDATE `domains` SET `type` = '" .$type. "' WHERE `id` = '".$id."'"); +} +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/auth.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/auth.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,118 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: auth.inc.php +// Startdate: 26-10-2002 +// Description: file is supposed to validate users and check whether they are authorized. +// If they are authorized this code handles that they can access stuff. +// +// $Id: auth.inc.php,v 1.6 2003/01/13 22:08:52 azurazu Exp $ +// + +session_start(); + +if (isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] == "logout") +{ + logout(); +} + +// If a user had just entered his/her login && password, store them in our session. +if(isset($_POST["authenticate"])) +{ + $_SESSION["userpwd"] = $_POST["password"]; + $_SESSION["userlogin"] = $_POST["username"]; +} + +// Check if the session hasnt expired yet. +if ((isset($_SESSION["userid"])) && ($_SESSION["lastmod"] != "") && ((time() - $_SESSION["lastmod"]) > $EXPIRE)) +{ + logout("Session expired, please login again."); +} + +// If the session hasn't expired yet, give our session a fresh new timestamp. +$_SESSION["lastmod"] = time(); + +if(isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) +{ + //Username and password are set, lets try to authenticate. + $result = $db->query("SELECT id, fullname, level FROM users WHERE username='". $_SESSION["userlogin"] ."' AND password='". md5($_SESSION["userpwd"]) ."' AND active=1"); + if($result->numRows() == 1) + { + $rowObj = $result->fetchRow(); + $_SESSION["userid"] = $rowObj["id"]; + $_SESSION["name"] = $rowObj["fullname"]; + $_SESSION["level"] = $rowObj["level"]; + if($_POST["authenticate"]) + { + //If a user has just authenticated, redirect him to index with timestamp, so post-data gets lost. + session_write_close(); + clean_page("index.php"); + exit; + } + } + else + { + //Authentication failed, retry. + auth("Authentication failed!"); + } +} +else +{ + //No username and password set, show auth form (again). + auth(); +} + +/* + * Print the login form. + */ + +function auth($msg="") +{ + include_once('inc/header.inc.php'); + ?> +

PowerAdmin for PowerDNS

Please login:

+ $msg\n"; + + } + ?> +
"> + + + + +
Login:
Password:
 
+ diff -r 2cd8c1649ba9 -r 58094faf794d inc/config.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/config.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,178 @@ + "##DOMAIN##", + "type" => "SOA", + "content" => "$NS1 $HOSTMASTER 1", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "##DOMAIN##", + "type" => "NS", + "content" => "$NS1", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "##DOMAIN##", + "type" => "NS", + "content" => "$NS2", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "www.##DOMAIN##", + "type" => "A", + "content" => "##WEBIP##", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "##DOMAIN##", + "type" => "A", + "content" => "##WEBIP##", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "mail.##DOMAIN##", + "type" => "A", + "content" => "##MAILIP##", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "localhost.##DOMAIN##", + "type" => "A", + "content" => "127.0.0.1", + "ttl" => "$DEFAULT_TTL", + "prio" => "" + ), + array( + "name" => "##DOMAIN##", + "type" => "MX", + "content" => "mail.##DOMAIN##", + "ttl" => "$DEFAULT_TTL", + "prio" => "10" + ) +); +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/dal.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/dal.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,860 @@ + | +// | Tomas V.V.Cox | +// +----------------------------------------------------------------------+ +// +// $Id: dal.inc.php,v 1.1 2002/10/27 19:18:42 azurazu Exp $ +// +// Database independent query interface. +// + +require_once "PEAR.php"; + +/* + * The method mapErrorCode in each DB_dbtype implementation maps + * native error codes to one of these. + * + * If you add an error code here, make sure you also add a textual + * version of it in DB::errorMessage(). + */ + +define("DB_OK", 1); +define("DB_ERROR", -1); +define("DB_ERROR_SYNTAX", -2); +define("DB_ERROR_CONSTRAINT", -3); +define("DB_ERROR_NOT_FOUND", -4); +define("DB_ERROR_ALREADY_EXISTS", -5); +define("DB_ERROR_UNSUPPORTED", -6); +define("DB_ERROR_MISMATCH", -7); +define("DB_ERROR_INVALID", -8); +define("DB_ERROR_NOT_CAPABLE", -9); +define("DB_ERROR_TRUNCATED", -10); +define("DB_ERROR_INVALID_NUMBER", -11); +define("DB_ERROR_INVALID_DATE", -12); +define("DB_ERROR_DIVZERO", -13); +define("DB_ERROR_NODBSELECTED", -14); +define("DB_ERROR_CANNOT_CREATE", -15); +define("DB_ERROR_CANNOT_DELETE", -16); +define("DB_ERROR_CANNOT_DROP", -17); +define("DB_ERROR_NOSUCHTABLE", -18); +define("DB_ERROR_NOSUCHFIELD", -19); +define("DB_ERROR_NEED_MORE_DATA", -20); +define("DB_ERROR_NOT_LOCKED", -21); +define("DB_ERROR_VALUE_COUNT_ON_ROW", -22); +define("DB_ERROR_INVALID_DSN", -23); +define("DB_ERROR_CONNECT_FAILED", -24); +define("DB_ERROR_EXTENSION_NOT_FOUND",-25); +define("DB_ERROR_ACCESS_VIOLATION", -26); +define("DB_ERROR_NOSUCHDB", -27); + +/* + * Warnings are not detected as errors by DB::isError(), and are not + * fatal. You can detect whether an error is in fact a warning with + * DB::isWarning(). + * + * @deprecated + */ + +define('DB_WARNING', -1000); +define('DB_WARNING_READ_ONLY', -1001); + +/* + * These constants are used when storing information about prepared + * statements (using the "prepare" method in DB_dbtype). + * + * The prepare/execute model in DB is mostly borrowed from the ODBC + * extension, in a query the "?" character means a scalar parameter. + * There are two extensions though, a "&" character means an opaque + * parameter. An opaque parameter is simply a file name, the real + * data are in that file (useful for putting uploaded files into your + * database and such). The "!" char means a parameter that must be + * left as it is. + * They modify the quote behavoir: + * DB_PARAM_SCALAR (?) => 'original string quoted' + * DB_PARAM_OPAQUE (&) => 'string from file quoted' + * DB_PARAM_MISC (!) => original string + */ + +define('DB_PARAM_SCALAR', 1); +define('DB_PARAM_OPAQUE', 2); +define('DB_PARAM_MISC', 3); + +/* + * These constants define different ways of returning binary data + * from queries. Again, this model has been borrowed from the ODBC + * extension. + * + * DB_BINMODE_PASSTHRU sends the data directly through to the browser + * when data is fetched from the database. + * DB_BINMODE_RETURN lets you return data as usual. + * DB_BINMODE_CONVERT returns data as well, only it is converted to + * hex format, for example the string "123" would become "313233". + */ + +define('DB_BINMODE_PASSTHRU', 1); +define('DB_BINMODE_RETURN', 2); +define('DB_BINMODE_CONVERT', 3); + +/** + * This is a special constant that tells DB the user hasn't specified + * any particular get mode, so the default should be used. + */ + +define('DB_FETCHMODE_DEFAULT', 0); + +/** + * Column data indexed by numbers, ordered from 0 and up + */ + +define('DB_FETCHMODE_ORDERED', 1); + +/** + * Column data indexed by column names + */ + +define('DB_FETCHMODE_ASSOC', 2); + +/** + * Column data as object properties + */ + +define('DB_FETCHMODE_OBJECT', 3); + +/** + * For multi-dimensional results: normally the first level of arrays + * is the row number, and the second level indexed by column number or name. + * DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays + * is the column name, and the second level the row number. + */ + +define('DB_FETCHMODE_FLIPPED', 4); + +/* for compatibility */ + +define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); +define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); +define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); + +/** + * these are constants for the tableInfo-function + * they are bitwised or'ed. so if there are more constants to be defined + * in the future, adjust DB_TABLEINFO_FULL accordingly + */ + +define('DB_TABLEINFO_ORDER', 1); +define('DB_TABLEINFO_ORDERTABLE', 2); +define('DB_TABLEINFO_FULL', 3); + +/* + * Used by autoPrepare() + */ +define('DB_AUTOQUERY_INSERT', 1); +define('DB_AUTOQUERY_UPDATE', 2); + + +/** + * The main "DB" class is simply a container class with some static + * methods for creating DB objects as well as some utility functions + * common to all parts of DB. + * + * The object model of DB is as follows (indentation means inheritance): + * + * DB The main DB class. This is simply a utility class + * with some "static" methods for creating DB objects as + * well as common utility functions for other DB classes. + * + * DB_common The base for each DB implementation. Provides default + * | implementations (in OO lingo virtual methods) for + * | the actual DB implementations as well as a bunch of + * | query utility functions. + * | + * +-DB_mysql The DB implementation for MySQL. Inherits DB_common. + * When calling DB::factory or DB::connect for MySQL + * connections, the object returned is an instance of this + * class. + * + * @package DB + * @author Stig Bakken + * @since PHP 4.0 + */ + +class DB +{ + /** + * Create a new DB connection object for the specified database + * type + * + * @param string $type database type, for example "mysql" + * + * @return mixed a newly created DB object, or a DB error code on + * error + * + * access public + */ + + function &factory($type) + { + @include_once("DB/${type}.php"); + + $classname = "DB_${type}"; + + if (!class_exists($classname)) { + return PEAR::raiseError(null, DB_ERROR_NOT_FOUND, + null, null, null, 'DB_Error', true); + } + + @$obj =& new $classname; + + return $obj; + } + + /** + * Create a new DB connection object and connect to the specified + * database + * + * @param mixed $dsn "data source name", see the DB::parseDSN + * method for a description of the dsn format. Can also be + * specified as an array of the format returned by DB::parseDSN. + * + * @param mixed $options An associative array of option names and + * their values. For backwards compatibility, this parameter may + * also be a boolean that tells whether the connection should be + * persistent. See DB_common::setOption for more information on + * connection options. + * + * @return mixed a newly created DB connection object, or a DB + * error object on error + * + * @see DB::parseDSN + * @see DB::isError + * @see DB_common::setOption + */ + function &connect($dsn, $options = false) + { + if (is_array($dsn)) { + $dsninfo = $dsn; + } else { + $dsninfo = DB::parseDSN($dsn); + } + $type = $dsninfo["phptype"]; + + if (is_array($options) && isset($options["debug"]) && + $options["debug"] >= 2) { + // expose php errors with sufficient debug level + include_once "DB/${type}.php"; + } else { + @include_once "DB/${type}.php"; + } + + $classname = "DB_${type}"; + if (!class_exists($classname)) { + return PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, + "Unable to include the DB/{$type}.php file for `$dsn'", + 'DB_Error', true); + } + + @$obj =& new $classname; + + if (is_array($options)) { + foreach ($options as $option => $value) { + $test = $obj->setOption($option, $value); + if (DB::isError($test)) { + return $test; + } + } + } else { + $obj->setOption('persistent', $options); + } + $err = $obj->connect($dsninfo, $obj->getOption('persistent')); + if (DB::isError($err)) { + $err->addUserInfo($dsn); + return $err; + } + + return $obj; + } + + /** + * Return the DB API version + * + * @return int the DB API version number + * + * @access public + */ + function apiVersion() + { + return 2; + } + + /** + * Tell whether a result code from a DB method is an error + * + * @param int $value result code + * + * @return bool whether $value is an error + * + * @access public + */ + function isError($value) + { + return (is_object($value) && + (get_class($value) == 'db_error' || + is_subclass_of($value, 'db_error'))); + } + + /** + * Tell whether a value is a DB connection + * + * @param mixed $value value to test + * + * @return bool whether $value is a DB connection + * + * @access public + */ + function isConnection($value) + { + return (is_object($value) && + is_subclass_of($value, 'db_common') && + method_exists($value, 'simpleQuery')); + } + + /** + * Tell whether a query is a data manipulation query (insert, + * update or delete) or a data definition query (create, drop, + * alter, grant, revoke). + * + * @access public + * + * @param string $query the query + * + * @return boolean whether $query is a data manipulation query + */ + function isManip($query) + { + $manips = 'INSERT|UPDATE|DELETE|'.'REPLACE|CREATE|DROP|'. + 'ALTER|GRANT|REVOKE|'.'LOCK|UNLOCK'; + if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) { + return true; + } + return false; + } + + /** + * Return a textual error message for a DB error code + * + * @param integer $value error code + * + * @return string error message, or false if the error code was + * not recognized + */ + function errorMessage($value) + { + static $errorMessages; + if (!isset($errorMessages)) { + $errorMessages = array( + DB_ERROR => 'unknown error', + DB_ERROR_ALREADY_EXISTS => 'already exists', + DB_ERROR_CANNOT_CREATE => 'can not create', + DB_ERROR_CANNOT_DELETE => 'can not delete', + DB_ERROR_CANNOT_DROP => 'can not drop', + DB_ERROR_CONSTRAINT => 'constraint violation', + DB_ERROR_DIVZERO => 'division by zero', + DB_ERROR_INVALID => 'invalid', + DB_ERROR_INVALID_DATE => 'invalid date or time', + DB_ERROR_INVALID_NUMBER => 'invalid number', + DB_ERROR_MISMATCH => 'mismatch', + DB_ERROR_NODBSELECTED => 'no database selected', + DB_ERROR_NOSUCHFIELD => 'no such field', + DB_ERROR_NOSUCHTABLE => 'no such table', + DB_ERROR_NOT_CAPABLE => 'DB backend not capable', + DB_ERROR_NOT_FOUND => 'not found', + DB_ERROR_NOT_LOCKED => 'not locked', + DB_ERROR_SYNTAX => 'syntax error', + DB_ERROR_UNSUPPORTED => 'not supported', + DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', + DB_ERROR_INVALID_DSN => 'invalid DSN', + DB_ERROR_CONNECT_FAILED => 'connect failed', + DB_OK => 'no error', + DB_WARNING => 'unknown warning', + DB_WARNING_READ_ONLY => 'read only', + DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', + DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', + DB_ERROR_NOSUCHDB => 'no such database', + DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions' + ); + } + + if (DB::isError($value)) { + $value = $value->getCode(); + } + + return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR]; + } + + /** + * Parse a data source name + * + * A array with the following keys will be returned: + * phptype: Database backend used in PHP (mysql, odbc etc.) + * dbsyntax: Database used with regards to SQL syntax etc. + * protocol: Communication protocol to use (tcp, unix etc.) + * hostspec: Host specification (hostname[:port]) + * database: Database to use on the DBMS server + * username: User name for login + * password: Password for login + * + * The format of the supplied DSN is in its fullest form: + * + * phptype(dbsyntax)://username:password@protocol+hostspec/database + * + * Most variations are allowed: + * + * phptype://username:password@protocol+hostspec:110//usr/db_file.db + * phptype://username:password@hostspec/database_name + * phptype://username:password@hostspec + * phptype://username@hostspec + * phptype://hostspec/database + * phptype://hostspec + * phptype(dbsyntax) + * phptype + * + * @param string $dsn Data Source Name to be parsed + * + * @return array an associative array + * + * @author Tomas V.V.Cox + */ + function parseDSN($dsn) + { + if (is_array($dsn)) { + return $dsn; + } + + $parsed = array( + 'phptype' => false, + 'dbsyntax' => false, + 'username' => false, + 'password' => false, + 'protocol' => false, + 'hostspec' => false, + 'port' => false, + 'socket' => false, + 'database' => false + ); + + // Find phptype and dbsyntax + if (($pos = strpos($dsn, '://')) !== false) { + $str = substr($dsn, 0, $pos); + $dsn = substr($dsn, $pos + 3); + } else { + $str = $dsn; + $dsn = NULL; + } + + // Get phptype and dbsyntax + // $str => phptype(dbsyntax) + if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { + $parsed['phptype'] = $arr[1]; + $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2]; + } else { + $parsed['phptype'] = $str; + $parsed['dbsyntax'] = $str; + } + + if (empty($dsn)) { + return $parsed; + } + + // Get (if found): username and password + // $dsn => username:password@protocol+hostspec/database + if (($at = strrpos($dsn,'@')) !== false) { + $str = substr($dsn, 0, $at); + $dsn = substr($dsn, $at + 1); + if (($pos = strpos($str, ':')) !== false) { + $parsed['username'] = urldecode(substr($str, 0, $pos)); + $parsed['password'] = urldecode(substr($str, $pos + 1)); + } else { + $parsed['username'] = urldecode($str); + } + } + + // Find protocol and hostspec + + // $dsn => proto(proto_opts)/database + if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { + $proto = $match[1]; + $proto_opts = (!empty($match[2])) ? $match[2] : false; + $dsn = $match[3]; + + // $dsn => protocol+hostspec/database (old format) + } else { + if (strpos($dsn, '+') !== false) { + list($proto, $dsn) = explode('+', $dsn, 2); + } + if (strpos($dsn, '/') !== false) { + list($proto_opts, $dsn) = explode('/', $dsn, 2); + } else { + $proto_opts = $dsn; + $dsn = null; + } + } + + // process the different protocol options + $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; + $proto_opts = urldecode($proto_opts); + if ($parsed['protocol'] == 'tcp') { + if (strpos($proto_opts, ':') !== false) { + list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts); + } else { + $parsed['hostspec'] = $proto_opts; + } + } elseif ($parsed['protocol'] == 'unix') { + $parsed['socket'] = $proto_opts; + } + + // Get dabase if any + // $dsn => database + if (!empty($dsn)) { + // /database + if (($pos = strpos($dsn, '?')) === false) { + $parsed['database'] = $dsn; + // /database?param1=value1¶m2=value2 + } else { + $parsed['database'] = substr($dsn, 0, $pos); + $dsn = substr($dsn, $pos + 1); + if (strpos($dsn, '&') !== false) { + $opts = explode('&', $dsn); + } else { // database?param1=value1 + $opts = array($dsn); + } + foreach ($opts as $opt) { + list($key, $value) = explode('=', $opt); + if (!isset($parsed[$key])) { // don't allow params overwrite + $parsed[$key] = urldecode($value); + } + } + } + } + + return $parsed; + } + + /** + * Load a PHP database extension if it is not loaded already. + * + * @access public + * + * @param string $name the base name of the extension (without the .so or + * .dll suffix) + * + * @return boolean true if the extension was already or successfully + * loaded, false if it could not be loaded + */ + function assertExtension($name) + { + if (!extension_loaded($name)) { + $dlext = OS_WINDOWS ? '.dll' : '.so'; + @dl($name . $dlext); + return extension_loaded($name); + } + return true; + } +} + +/** + * DB_Error implements a class for reporting portable database error + * messages. + * + * @package DB + * @author Stig Bakken + */ +class DB_Error extends PEAR_Error +{ + /** + * DB_Error constructor. + * + * @param mixed $code DB error code, or string with error message. + * @param integer $mode what "error mode" to operate in + * @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER + * @param mixed $debuginfo additional debug info, such as the last query + * + * @access public + * + * @see PEAR_Error + */ + + function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, + $level = E_USER_NOTICE, $debuginfo = null) + { + if (is_int($code)) { + $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo); + } else { + $this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo); + } + } +} + +/** + * This class implements a wrapper for a DB result set. + * A new instance of this class will be returned by the DB implementation + * after processing a query that returns data. + * + * @package DB + * @author Stig Bakken + */ + +class DB_result +{ + var $dbh; + var $result; + var $row_counter = null; + /** + * for limit queries, the row to start fetching + * @var integer + */ + var $limit_from = null; + + /** + * for limit queries, the number of rows to fetch + * @var integer + */ + var $limit_count = null; + + /** + * DB_result constructor. + * @param resource &$dbh DB object reference + * @param resource $result result resource id + */ + + function DB_result(&$dbh, $result, $options = array()) + { + $this->dbh = &$dbh; + $this->result = $result; + $this->limit_from = isset($options['limit_from']) ? $options['limit_from'] : null; + $this->limit_count = isset($options['limit_count']) ? $options['limit_count'] : null; + $this->limit_type = $dbh->features['limit']; + $this->autofree = $dbh->options['autofree']; + $this->fetchmode = $dbh->fetchmode; + $this->fetchmode_object_class = $dbh->fetchmode_object_class; + } + + /** + * Fetch and return a row of data (it uses driver->fetchInto for that) + * @param int $fetchmode format of fetched row + * @param int $rownum the row number to fetch + * + * @return array a row of data, NULL on no more rows or PEAR_Error on error + * + * @access public + */ + function fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) + { + if ($fetchmode === DB_FETCHMODE_DEFAULT) { + $fetchmode = $this->fetchmode; + } + if ($fetchmode === DB_FETCHMODE_OBJECT) { + $fetchmode = DB_FETCHMODE_ASSOC; + $object_class = $this->fetchmode_object_class; + } + if ($this->limit_from !== null) { + if ($this->row_counter === null) { + $this->row_counter = $this->limit_from; + // Skip rows + if ($this->limit_type == false) { + $i = 0; + while ($i++ < $this->limit_from) { + $this->dbh->fetchInto($this->result, $arr, $fetchmode); + } + } + } + if ($this->row_counter >= ( + $this->limit_from + $this->limit_count)) + { + return null; + } + if ($this->limit_type == 'emulate') { + $rownum = $this->row_counter; + } + + $this->row_counter++; + } + $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); + if ($res !== DB_OK) { + if ($res == null && $this->autofree) { + $this->free(); + } + return $res; + } + if (isset($object_class)) { + // default mode specified in DB_common::fetchmode_object_class property + if ($object_class == 'stdClass') { + $ret = (object) $arr; + } else { + $ret =& new $object_class($arr); + } + return $ret; + } + return $arr; + } + + /** + * Fetch a row of data into an existing variable. + * + * @param mixed &$arr reference to data containing the row + * @param integer $fetchmod format of fetched row + * @param integer $rownum the row number to fetch + * + * @return mixed DB_OK on success, NULL on no more rows or + * a DB_Error object on error + * + * @access public + */ + function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) + { + if ($fetchmode === DB_FETCHMODE_DEFAULT) { + $fetchmode = $this->fetchmode; + } + if ($fetchmode === DB_FETCHMODE_OBJECT) { + $fetchmode = DB_FETCHMODE_ASSOC; + $object_class = $this->fetchmode_object_class; + } + if ($this->limit_from !== null) { + if ($this->row_counter === null) { + $this->row_counter = $this->limit_from; + // Skip rows + if ($this->limit_type == false) { + $i = 0; + while ($i++ < $this->limit_from) { + $this->dbh->fetchInto($this->result, $arr, $fetchmode); + } + } + } + if ($this->row_counter >= ( + $this->limit_from + $this->limit_count)) + { + return null; + } + if ($this->limit_type == 'emulate') { + $rownum = $this->row_counter; + } + + $this->row_counter++; + } + $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); + if (($res === DB_OK) && isset($object_class)) { + // default mode specified in DB_common::fetchmode_object_class property + if ($object_class == 'stdClass') { + $arr = (object) $arr; + } else { + $arr = new $object_class($arr); + } + } elseif ($res == null && $this->autofree) { + $this->free(); + } + return $res; + } + + /** + * Get the the number of columns in a result set. + * + * @return int the number of columns, or a DB error + * + * @access public + */ + function numCols() + { + return $this->dbh->numCols($this->result); + } + + /** + * Get the number of rows in a result set. + * + * @return int the number of rows, or a DB error + * + * @access public + */ + function numRows() + { + return $this->dbh->numRows($this->result); + } + + /** + * Get the next result if a batch of queries was executed. + * + * @return bool true if a new result is available or false if not. + * + * @access public + */ + function nextResult() + { + return $this->dbh->nextResult($this->result); + } + + /** + * Frees the resources allocated for this result set. + * @return int error code + * + * @access public + */ + function free() + { + $err = $this->dbh->freeResult($this->result); + if(DB::isError($err)) { + return $err; + } + $this->result = false; + return true; + } + + /** + * @deprecated + */ + function tableInfo($mode = null) + { + return $this->dbh->tableInfo($this->result, $mode); + } + + /** + * returns the actual row number + * @return integer + */ + function getRowCounter() + { + return $this->row_counter; + } +} + +/** +* Pear DB Row Object +* @see DB_common::setFetchMode() +*/ +class DB_row +{ + /** + * constructor + * + * @param resource row data as array + */ + function DB_row(&$arr) + { + for (reset($arr); $key = key($arr); next($arr)) { + $this->$key = &$arr[$key]; + } + } +} + +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/database.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/database.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,59 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: auth.inc.php +// Startdate: 26-10-2002 +// Description: Constructs the database class. +// +// $Id: database.inc.php,v 1.3 2002/12/27 02:45:08 azurazu Exp $ +// + +require_once("dal.inc.php"); + +function dbError($msg) +{ + // General function for printing critical errors. + include_once("header.inc.php"); + ?> +

Oops! An error occured!

+
+ getDebugInfo(); ?>

<< back

+ getMessage()); +} + +// Do an ASSOC fetch. Gives us the ability to use ["id"] fields. +$db->setFetchMode(DB_FETCHMODE_ASSOC); + + +/* erase info */ +$mysql_pass = $dsn = ''; + + +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/dns.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/dns.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,531 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: dns.inc.php +// Startdate: 26-10-2002 +// Description: checks whether a given content is valid. +// A lot of DNS Record features are found to be here and also are to be placed here. +// If they are authorized this code handles that they can access stuff. +// +// $Id: dns.inc.php,v 1.23 2003/02/23 21:31:13 azurazu Exp $ +// + + +/* + * Validates an IPv4 IP. + * returns true if valid. + */ +function validate_input($recordid, $zoneid, $type, &$content, &$name, &$prio, &$ttl) +{ + global $db; + + // Has to validate content first then it can do the rest + // Since if content is invalid already it can aswell be just removed + // Check first if content is IPv4, IPv6 or Hostname + // We accomplish this by just running all tests over it + // We start with IPv6 since its not able to have these ip's in domains. + // + // + // The nocheck has to move to the configuration file + // + // + $domain = get_domain_name_from_id($zoneid); + $nocheck = array('SOA', 'HINFO', 'NAPTR', 'URL', 'MBOXFW', 'TXT'); + $hostname = false; + $ip4 = false; + $ip6 = false; + + if(!in_array(strtoupper($type), $nocheck)) + { + + if(!is_valid_ip6($content)) + { + if(!is_valid_ip($content)) + { + if(!is_valid_hostname($content)) + { + error(ERR_DNS_CONTENT); + } + else + { + $hostname = true; + } + } + else + { + $ip4 = true; + } + } + else + { + $ip6 = true; + } + } + + // Prepare total hostname. + + if($name == '*') + { + $wildcard = true; + } + + if ($name=="0") { + $name=$name.".".$domain; + } else { + $name = ($name) ? $name.".".$domain : $domain; + } + + if (preg_match('!@\.!i', $name)) + { + $name = str_replace('@.', '@', $name); + } + + if(!$wildcard) + { + if(!is_valid_hostname($name)) + { + error(ERR_DNS_HOSTNAME); + } + } + + // Check record type (if it exists in our allowed list. + if (!in_array(strtoupper($type), get_record_types())) + { + error(ERR_DNS_RECORDTYPE); + } + + // Start handling the demands for the functions. + // Validation for IN A records. Can only have an IP. Nothing else. + if ($type == 'A' && !$ip4) + { + error(ERR_DNS_IPV4); + } + + if ($type == 'AAAA' && !$ip6) + { + error(ERR_DNS_IPV6); + } + + if ($type == 'CNAME' && $hostname) + { + if(!is_valid_cname($name)) + { + error(ERR_DNS_CNAME); + } + } + + if ($type == 'NS') + { + $status = is_valid_ns($content, $hostname); + if($status == -1) + { + error(ERR_DNS_NS_HNAME); + } + elseif($status == -2) + { + error(ERR_DNS_NS_CNAME); + } + // Otherwise its ok + } + + if ($type == 'SOA') + { + $status = is_valid_soa($content, $zoneid); + if($status == -1) + { + error(ERR_DNS_SOA_UNIQUE); + // Make nicer error + } + elseif($status == -2) + { + error(ERR_DNS_SOA_NUMERIC); + } + } + + // HINFO and TXT require no validation. + + if ($type == 'URL') + { + if(!is_valid_url($content)) + { + error(ERR_INV_URL); + } + } + if ($type == 'MBOXFW') + { + if(!is_valid_mboxfw($content)) + { + error(ERR_INV_EMAIL); + } + } + + // NAPTR has to be done. + // Do we want that? + // http://www.ietf.org/rfc/rfc2915.txt + // http://www.zvon.org/tmRFC/RFC2915/Output/chapter2.html + // http://www.zvon.org/tmRFC/RFC3403/Output/chapter4.html + + // See if the prio field is valid and if we have one. + // If we dont have one and the type is MX record, give it value '10' + if($type == 'NAPTR') + { + + } + + if($type == 'MX') + { + if($hostname) + { + $status = is_valid_mx($content, $prio); + if($status == -1) + { + error(ERR_DNS_MX_CNAME); + } + elseif($status == -2) + { + error(ERR_DNS_MX_PRIO); + } + } + else + { + error("If you specify an MX record it must be a hostname"); + } + } + else + { + $prio=''; + } + // Validate the TTL, it has to be numeric. + $ttl = (!isset($ttl) || !is_numeric($ttl)) ? $DEFAULT_TTL : $ttl; +} + + + + /**************************************** + * * + * RECORD VALIDATING PART. * + * CHANGES HERE SHOULD BE CONSIDERED * + * THEY REQUIRE KNOWLEDGE ABOUT THE * + * DNS SPECIFICATIONS * + * * + ***************************************/ + + +/* + * Validatis a CNAME record by the name it will have and its destination + * + */ +function is_valid_cname($dest) +{ + /* + * This is really EVIL. + * If the new record (a CNAME) record is being pointed to by a MX record or NS record we have to bork. + * this is the idea. + * + * MX record: blaat.nl MX mail.blaat.nl + * Now we look what mail.blaat.nl is + * We discover the following: + * mail.blaat.nl CNAME bork.blaat.nl + * This is NOT allowed! mail.onthanet.nl can not be a CNAME! + * The same goes for NS. mail.blaat.nl must have a normal IN A record. + * It MAY point to a CNAME record but its not wished. Lets not support it. + */ + + global $db; + + // Check if there are other records with this information of the following types. + // P.S. we might add CNAME to block CNAME recursion and chains. + $blockedtypes = " AND (type='MX' OR type='NS')"; + + $cnamec = "SELECT type, content FROM records WHERE content='$dest'" . $blockedtypes; + $result = $db->query($cnamec); + + if($result->numRows() > 0) + { + return false; + // Lets inform the user he is doing something EVIL. + // Ok we found a record that has our content field in their content field. + } + return true; +} + + +/* + * Checks if something is a valid domain. + * Checks for domainname with the allowed characters and - and _. + * This part must be followed by a 2 to 4 character TLD. + */ +function is_valid_domain($domain) +{ + if ((eregi("^[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$", $domain)) && (strlen($domain) <= 128)) + { + return true; + } + return false; +} + + +/* + * Validates if given hostname is allowed. + * returns true if allowed. + */ +function is_valid_hostname($host) +{ + if(count(explode(".", $host)) == 1) + { + return false; + } + + // Its not perfect (in_addr.int is allowed) but works for now. + + if(preg_match('!(ip6|in-addr).(arpa|int)$!i', $host)) + { + if(preg_match('!^(([A-Z\d]|[A-Z\d][A-Z\d-]*[A-Z\d])\.)*[A-Z\d]+$!i', $host)) + { + return true; + } + return false; + } + + // Validate further. + return (preg_match('!^(([A-Z\d]|[A-Z\d][A-Z\d-]*[A-Z\d])\.)*[A-Z\d]+$!i', $host)) ? true : false; +} + + +/* + * Validates an IPv4 IP. + * returns true if valid. + */ +function is_valid_ip($ip) +{ + // Stop reading at this point. Scroll down to the next function... + // Ok... you didn't stop reading... now you have to rewrite the whole function! enjoy ;-) + // Trance unborked it. Twice even! + return ($ip == long2ip(ip2long($ip))) ? true : false; + +} + + +/* + * Validates an IPv6 IP. + * returns true if valid. + */ +function is_valid_ip6($ip) +{ + // Validates if the given IP is truly an IPv6 address. + // Precondition: have a string + // Postcondition: false: Error in IP + // true: IP is correct + // Requires: String + // Date: 10-sep-2002 + if(preg_match('!^[A-F0-9:]{1,39}$!i', $ip) == true) + { + // Not 3 ":" or more. + $p = explode(':::', $ip); + if(sizeof($p) > 1) + { + return false; + } + // Find if there is only one occurence of "::". + $p = explode('::', $ip); + if(sizeof($p) > 2) + { + return false; + } + // Not more than 8 octects + $p = explode(':', $ip); + + if(sizeof($p) > 8) + { + return false; + } + + // Check octet length + foreach($p as $checkPart) + { + if(strlen($checkPart) > 4) + { + return false; + } + } + return true; + } + return false; +} + + +/* + * FANCY RECORD. + * Validates if the fancy record mboxfw is an actual email address. + */ +function is_valid_mboxfw($email) +{ + return is_valid_email($email); +} + + +/* + * Validates MX records. + * an MX record cant point to a CNAME record. This has to be checked. + * this function also sets a proper priority. + */ +function is_valid_mx($content, &$prio) +{ + global $db; + // See if the destination to which this MX is pointing is NOT a CNAME record. + // Check inside our dns server. + if($db->getOne("SELECT count(id) FROM records WHERE name='$content' AND type='CNAME'") > 0) + { + return -1; + } + else + { + // Fix the proper priority for the record. + // Bugfix, thanks Oscar :) + if(!isset($prio)) + { + $prio = 10; + } + if(!is_numeric($prio)) + { + if($prio == '') + { + $prio = 10; + } + else + { + return -2; + } + } + } + return 1; +} + +/* + * Validates NS records. + * an NS record cant point to a CNAME record. This has to be checked. + * $hostname directive means if its a hostname or not (this to avoid that NS records get ip fields) + * NS must have a hostname, it is not allowed to have an IP. + */ +function is_valid_ns($content, $hostname) +{ + global $db; + // Check if the field is a hostname, it MUST be a hostname. + if(!$hostname) + { + return -1; + // "an IN NS field must be a hostname." + } + + if($db->getOne("SELECT count(id) FROM records WHERE name='$content' AND type='CNAME'") > 0) + { + return -2; + // "You can not point a NS record to a CNAME record. Remove/rename the CNAME record first or take another name." + + } + return 1; +} + + +/* + * Function to check the validity of SOA records. + * return values: true if succesful + */ +function is_valid_soa(&$content, $zoneid) +{ + + /* + * SOA (start of authority) + * there is only _ONE_ SOA record allowed in every zone. + * Validate SOA record + * The Start of Authority record is one of the most complex available. It specifies a lot + * about a domain: the name of the master nameserver ('the primary'), the hostmaster and + * a set of numbers indicating how the data in this domain expires and how often it needs + * to be checked. Further more, it contains a serial number which should rise on each change + * of the domain. + 2002120902 28800 7200 604800 10800 + * The stored format is: primary hostmaster serial refresh retry expire default_ttl + * From the powerdns documentation. + */ + + + // Check if there already is an occurence of a SOA, if so see if its not the one we are currently changing + $return = get_records_by_type_from_domid("SOA", $zoneid); + if($return->numRows() > 1) + { + return -1; + } + + + $soacontent = explode(" ", $content); + // Field is at least one otherwise it wouldnt even get here. + if(is_valid_hostname($soacontent[0])) + { + $totalsoa = $soacontent[0]; + // It doesnt matter what field 2 contains, but lets check if its there + // We assume the 2nd field wont have numbers, otherwise its a TTL field + if(count($soacontent) > 1) + { + if(is_numeric($soacontent[1])) + { + // its a TTL field, or at least not hostmaster or alike + // Set final string to the default hostmaster addy + global $HOSTMASTER; + $totalsoa .= " ". $HOSTMASTER; + } + else + { + $totalsoa .= " ".$soacontent[1]; + } + // For loop to iterate over the numbers + $imax = count($soacontent); + for($i = 2; ($i < $imax) && ($i < 7); $i++) + { + if(!is_numeric($soacontent[$i])) + { + return -2; + } + else + { + $totalsoa .= " ".$soacontent[$i]; + } + } + if($i > 7) + { + error(ERR_DNS_SOA_NUMERIC_FIELDS); + } + } + } + else + { + error(ERR_DNS_SOA_HOSTNAME); + } + $content = $totalsoa; + return 1; +} + + +function is_valid_url($url) +{ + return preg_match('!^(http://)(([A-Z\d]|[A-Z\d][A-Z\d-]*[A-Z\d])\.)*[A-Z\d]+([//]([0-9a-z//~#%&\'_\-+=:?.]*))?$!i', $url); +} + + /**************************************** + * * + * END OF RECORD VALIDATING PART. * + * * + ***************************************/ +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/error.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/error.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,65 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: error.inc.php +// Startdate: 25-11-2002 +// Description: all error defines should be put in here. +// All errors have to use an ERR_ prefix to distinguish them from other constants. +// All errors should be placed in the appropriate group. +// +// $Id: error.inc.php,v 1.6 2003/05/04 21:38:37 azurazu Exp $ +// + +/* USER LEVELS */ +define("ERR_LEVEL_5", "You need user level 5 for this operation"); +define("ERR_LEVEL_10", "You need user level 10 for this operation"); + +/* RECORD STUFF */ +define("ERR_RECORD_EMPTY_CONTENT", "Your content field is empty"); +define("ERR_RECORD_ACCESS_DENIED", "Access denied, you do not have access to that record"); +define("ERR_RECORD_DELETE_TYPE_DENIED", "You are not allowed to delete %s records"); + +/* DOMAIN STUFF */ +define("ERR_DOMAIN_INVALID", "This is an invalid domain name"); + +/* USER STUFF */ +define("ERR_USER_EXIST", "Username exist already, please choose another one"); +define("ERR_USER_NOT_EXIST", "User doesnt exist"); +define("ERR_USER_WRONG_CURRENT_PASS", "You didnt enter the correct current password"); +define("ERR_USER_MATCH_NEW_PASS", "The two new password fields do not match"); +define("ERR_USER_EDIT", "Error editting user"); + +/* OTHER */ +define("ERR_INV_ARG", "Invalid argument(s) given to function %s"); +define("ERR_INV_ARGC", "Invalid argument(s) given to function %s %s"); +define("ERR_UNKNOWN", "unknown error"); +define("ERR_INV_EMAIL", "Enter a valid email address"); + +/* DNS */ +define("ERR_DNS_CONTENT", "Your content field doesnt have a legit value"); +define("ERR_DNS_HOSTNAME", "Invalid hostname"); +define("ERR_DNS_RECORDTYPE", "Invalid record type! You shouldnt even been able to get that here"); +define("ERR_DNS_IPV6", "This is not a valid IPv6 ip."); +define("ERR_DNS_IPV4", "This is not a valid IPv4 ip."); +define("ERR_DNS_CNAME", "This is not a valid CNAME. Did you assign an MX or NS record to the record?"); +define("ERR_DNS_NS_CNAME", "You can not point a NS record to a CNAME record. Remove/rename the CNAME record first or take another name."); +define("ERR_DNS_NS_HNAME", "IN NS fields must be a hostnames."); +define("ERR_DNS_MX_CNAME", "You can not point a MX record to a CNAME record. Remove/rename the CNAME record first or take another name."); +define("ERR_DNS_MX_PRIO", "A prio field should be numeric."); +define("ERR_DNS_SOA_NUMERIC", "One of your SOA data fields is not numeric!"); +define("ERR_DNS_SOA_NUMERIC_FIELDS", "You can only have 5 numeric fields"); +define("ERR_DNS_SOA_HOSTNAME", "The first part of your SOA record does not contain a valid hostname for a DNS Server"); +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/footer.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/footer.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,39 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: footer.inc.php +// Startdate: beginning. +// Description: simple page footer +// Closes the database connection. +// +// $Id: footer.inc.php,v 1.12 2003/05/14 22:49:56 azurazu Exp $ +// + + +global $db; +if(is_object($db)) +{ + $db->disconnect(); +} + +?> +

+[ logoutPowerAdmin v1.2.7 :: Copyright © + The PowerAdmin Team :: http://poweradmin.org + + + + diff -r 2cd8c1649ba9 -r 58094faf794d inc/header.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/header.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,31 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: error.inc.php +// Startdate: 25-11-2002 +// Description: simple header defining the page looks. +// +// $Id: header.inc.php,v 1.4 2003/02/05 23:23:53 azurazu Exp $ +// + +?> + + + +PowerAdmin + + + diff -r 2cd8c1649ba9 -r 58094faf794d inc/record.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/record.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,1122 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: record.inc.php +// Startdate: 26-10-2002 +// This file is ought to edit the records in the database. +// Records are domains aswell, they also belong here. +// All database functions are associative. +// use nextID first to get a new id. Then insert it into the database. +// do not rely on auto_increment (see above). +// use dns.inc.php for validation functions. +// +// $Id: record.inc.php,v 1.21 2003/05/10 20:21:01 azurazu Exp $ +// + + +function update_soa_serial($domain_id) +{ + global $db; + /* + * THIS CODE ISNT TESTED THROUGH MUCH YET! + * !!!!!!! BETACODE !!!!!!!!!! + * Code committed by DeViCeD, Thanks a lot! + * Heavily hax0red by Trancer/azurazu + * + * First we have to check, wheather current searial number + * was already updated on the other nameservers. + * If field 'notified_serial' is NULL, then I guess domain is + * NATIVE and we don't have any secondary nameservers for this domain. + * NOTICE: Serial number *will* be RFC1912 compilant after update + * NOTICE: This function will allow only 100 DNS zone transfers ;-) + * YYYYMMDDnn + */ + + $sqlq = "SELECT `notified_serial` FROM `domains` WHERE `id` = '".$domain_id."'"; + $notified_serial = $db->getOne($sqlq); + + $sqlq = "SELECT `content` FROM `records` WHERE `type` = 'SOA' AND `domain_id` = '".$domain_id."'"; + $content = $db->getOne($sqlq); + $need_to_update = false; + + // Getting the serial field. + $soa = explode(" ", $content); + + if(empty($notified_serial)) + { + // Ok native replication, so we have to update. + $need_to_update = true; + } + elseif($notified_serial >= $soa[2]) + { + $need_to_update = true; + } + elseif(strlen($soa[2]) != 10) + { + $need_to_update = true; + } + else + { + $need_to_update = false; + } + if($need_to_update) + { + // Ok so we have to update it seems. + $current_serial = $soa[2]; + + /* + * What we need here (for RFC1912) is YEAR, MONTH and DAY + * so let's get it ... + */ + $new_serial = date('Ymd'); // we will add revision number later + + if(strncmp($new_serial, $current_serial, 8) === 0) + { + /* + * Ok, so we already made updates tonight + * let's just increase the revision number + */ + $revision_number = (int) substr($current_serial, -2); + if ($revision_number == 99) return false; // ok, we cannot update anymore tonight + ++$revision_number; + // here it is ... same date, new revision + $new_serial .= str_pad($revision_number, 2, "0", STR_PAD_LEFT); + } + else + { + /* + * Current serial is not RFC1912 compilant, so let's make a new one + */ + $new_serial .= '00'; + } + $soa[2] = $new_serial; // change serial in SOA array + $new_soa = ""; + // build new soa and update SQL after that + for ($i = 0; $i < count($soa); $i++) + { + $new_soa .= $soa[$i] . " "; + } + $sqlq = "UPDATE `records` SET `content` = '".$new_soa."' WHERE `domain_id` = '".$domain_id."' AND `type` = 'SOA' LIMIT 1"; + $db->Query($sqlq); + return true; + } +} + +/* + * Edit a record. + * This function validates it if correct it inserts it into the database. + * return values: true if succesful. + */ +function edit_record($recordid, $zoneid, $name, $type, $content, $ttl, $prio) +{ + global $db; + if($content == "") + { + error(ERR_RECORD_EMPTY_CONTENT); + } + // Edits the given record (validates specific stuff first) + if (!xs(recid_to_domid($recordid))) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($zoneid)) + { + validate_input($recordid, $zoneid, $type, $content, $name, $prio, $ttl); + $change = time(); + $db->query("UPDATE records set name='$name', type='$type', content='$content', ttl='$ttl', prio='$prio', change_date='$change' WHERE id=$recordid"); + + /* + * Added by DeViCeD - Update SOA Serial number + * There should be more checks + */ + if ($type != 'SOA') + { + update_soa_serial($zoneid); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "edit_record", "no zoneid given")); + } + +} + + +/* + * Adds a record. + * This function validates it if correct it inserts it into the database. + * return values: true if succesful. + */ +function add_record($zoneid, $name, $type, $content, $ttl, $prio) +{ + + global $db; + if (!xs($zoneid)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($zoneid)) + { + + // Get the Insert ID, we can not rely on auto_increment + $idrecords = $db->nextID('records'); + + // Check the user input. + validate_input($idrecords, $zoneid, $type, $content, $name, $prio, $ttl); + + // Generate new timestamp for the Daemon + $change = time(); + // Execute query. + $db->query("INSERT INTO records (id, domain_id, name, type, content, ttl, prio, change_date) VALUES ($idrecords, $zoneid, '$name', '$type', '$content', $ttl, '$prio', $change)"); + if ($type != 'SOA') + { + update_soa_serial($zoneid); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARG, "add_record")); + } +} + + +/* + * Delete a record by a given id. + * return values: true, this function is always succesful. + */ +function delete_record($id) +{ + global $db; + + // Check if the user has access. + if (!xs(recid_to_domid($id))) + { + error(ERR_RECORD_ACCESS_DENIED); + } + + // Retrieve the type of record to see if we can actually remove it. + $recordtype = get_recordtype_from_id($id); + + // If the record type is NS and the user tries to delete it while ALLOW_NS_EDIT is set to 0 + // OR + // check if the name of the record isnt the domain name (if so it should delete all records) + // OR + // check if we are dealing with a SOA field (same story as NS) + if (($recordtype == "NS" && $GLOBALS["ALLOW_NS_EDIT"] != 1 && (get_name_from_record_id($id) == get_domain_name_from_id(recid_to_domid($id)))) || ($recordtype == "SOA" && $GLOBALS["ALLOW_SOA_EDIT"] != 1)) + { + error(sprintf(ERR_RECORD_DELETE_TYPE_DENIED, $recordtype)); + + } + if (is_numeric($id)) + { + $did = recid_to_domid($id); + $db->query('DELETE FROM records WHERE id=' . $id . ' LIMIT 1'); + if ($type != 'SOA') + { + update_soa_serial($did); + } + // $id doesnt exist in database anymore so its deleted or just not there which means "true" + return true; + } + else + { + error(sprintf(ERR_INV_ARG, "delete_record")); + } +} + + +/* + * Add a domain to the database. + * A domain is name obligatory, so is an owner. + * return values: true when succesful. + * Empty means templates dont have to be applied. + * -------------------------------------------------------------------------- + * This functions eats a template and by that it inserts various records. + * first we start checking if something in an arpa record + * remember to request nextID's from the database to be able to insert record. + * if anything is invalid the function will error + */ +function add_domain($domain, $owner, $webip, $mailip, $empty, $type) +{ + + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + // If domain, owner and mailip are given + // OR + // empty is given and owner and domain + // OR + // the domain is an arpa record and owner is given + // THAN + // Continue this function + if (($domain && $owner && $webip && $mailip) || ($empty && $owner && $domain) || (eregi('in-addr.arpa', $domain) && $owner)) + { + // Retrieve next zones id. + $idzones = $db->nextID('zones'); + $iddomains = $db->nextID('domains'); + + $db->query("INSERT INTO zones (id, domain_id, owner) VALUES ('$idzones', '$iddomains', $owner)"); + + /* + * TODO : NATIVE OPERATION ONLY FOR NOW + */ + + $db->query("INSERT INTO domains (id, name, type) VALUES ('$iddomains', '$domain', '$type')"); + + // Generate new timestamp. We need this one anyhow. + $now = time(); + + if ($empty && $iddomains) + { + // If we come into this if statement we dont want to apply templates. + // Retrieve configuration settings. + $ns1 = $GLOBALS["NS1"]; + $hm = $GLOBALS["HOSTMASTER"]; + $ttl = $GLOBALS["DEFAULT_TTL"]; + + // Retrieve next records id + $idrecords = $db->nextID('records'); + + // Build and execute query + $sql = "INSERT INTO records (id, domain_id, name, content, type, ttl, prio, change_date) VALUES ('$idrecords', '$iddomains', '$domain', '$ns1 $hm 1', 'SOA', $ttl, '', '$now')"; + $db->query($sql); + + // Done + return true; + } + elseif ($iddomains) + { + // If we are here we want to apply templates. + global $template; + + // Iterate over the template and apply it for each field. + foreach ($template as $r) + { + // Same type of if statement as previous. + if ((eregi('in-addr.arpa', $domain) && ($r["type"] == "NS" || $r["type"] == "SOA")) || (!eregi('in-addr.arpa', $domain))) + { + // Parse the template. + $name = parse_template_value($r["name"], $domain, $webip, $mailip); + $type = $r["type"]; + $content = parse_template_value($r["content"], $domain, $webip, $mailip); + $ttl = $r["ttl"]; + $prio = $r["prio"]; + + // If no ttl is given, use the default. + if (!$ttl) + { + $ttl = $GLOBALS["DEFAULT_TTL"]; + } + + // Retrieve new record id; + $idrecords = $db->nextID('records'); + $sql = "INSERT INTO records (id, domain_id, name, content, type, ttl, prio, change_date) VALUES ('$idrecords', '$iddomains', '$name','$content','$type','$ttl','$prio','$now')"; + $db->query($sql); + } + } + // All done. + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "add_domain", "could not create zone")); + } + } + else + { + error(sprintf(ERR_INV_ARG, "add_domain")); + } +} + + +/* + * Deletes a domain by a given id. + * Function always succeeds. If the field is not found in the database, thats what we want anyway. + */ +function delete_domain($id) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + // See if the ID is numeric. + if (is_numeric($id)) + { + $db->query("DELETE FROM zones WHERE domain_id=$id"); + $db->query("DELETE FROM domains WHERE id=$id"); + $db->query("DELETE FROM records WHERE domain_id=$id"); + // Nothing in the database. If the delete deleted 0 records it means the id is just not there. + // therefore the is no need to check the affectedRows values. + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "delete_domain", "id must be a number")); + } +} + + +/* + * Gets the id of the domain by a given record id. + * return values: the domain id that was requested. + */ +function recid_to_domid($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT domain_id FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["domain_id"]; + } + else + { + error(sprintf(ERR_INV_ARGC, "recid_to_domid", "id must be a number")); + } +} + + +/* + * Sorts a zone by records. + * return values: the sorted zone. + */ +function sort_zone($records) +{ + $ar_so = array(); + $ar_ns = array(); + $ar_mx = array(); + $ar_mb = array(); + $ar_ur = array(); + $ar_ov = array(); + foreach ($records as $c) + { + switch(strtoupper($c['type'])) + { + case "SOA": + $ar_so[] = $c; + break; + case "NS": + $ar_ns[] = $c; + break; + case "MX": + $ar_mx[] = $c; + break; + case "MBOXFW": + $ar_mb[] = $c; + break; + case "URL": + $ar_ur[] = $c; + break; + default: + $ar_ov[] = $c; + break; + } + } + + $res = array_merge($ar_so, $ar_ns, $ar_mx, $ar_mb, $ar_ur, $ar_ov); + + if (count($records) == count($res)) + { + $records = $res; + } + else + { + error(sprintf(ERR_INV_ARGC, "sort_zone", "records sorting failed!")); + } + return $records; +} + + +/* + * Change owner of a domain. + * Function should actually be in users.inc.php. But its more of a record modification than a user modification + * return values: true when succesful. + */ +function add_owner($domain, $newowner) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + + if (is_numeric($domain) && is_numeric($newowner) && is_valid_user($newowner)) + { + $iid = $db->nextID('zones'); + if($db->getOne("SELECT COUNT(id) FROM zones WHERE owner=$newowner AND domain_id=$domain") == 0) + { + $db->query("INSERT INTO zones(id, domain_id, owner) VALUES($iid, $domain, $newowner)"); + } + return true; + } + else + { + error(sprintf(ERR_INV_ARGC, "change_owner", "$domain / $newowner")); + } +} + + +function delete_owner($domain, $owner) +{ + global $db; + if($db->getOne("SELECT COUNT(id) FROM zones WHERE owner=$owner AND domain_id=$domain") != 0) + { + $db->query("DELETE FROM zones WHERE owner=$owner AND domain_id=$domain"); + } + return true; +} + +/* + * Retrieves all supported dns record types + * This function might be deprecated. + * return values: array of types in string form. + */ +function get_record_types() +{ + global $rtypes; + return $rtypes; +} + + +/* + * Retrieve all records by a given type and domain id. + * Example: get all records that are of type A from domain id 1 + * return values: a DB class result object + */ +function get_records_by_type_from_domid($type, $recid) +{ + global $rtypes; + global $db; + + // Does this type exist? + if(!in_array(strtoupper($type), $rtypes)) + { + error(sprintf(ERR_INV_ARGC, "get_records_from_type", "this is not a supported record")); + } + + // Get the domain id. + $domid = recid_to_domid($recid); + + $result = $db->query("select id, type from records where domain_id=$recid and type='$type'"); + return $result; +} + + +/* + * Retrieves the type of a record from a given id. + * return values: the type of the record (one of the records types in $rtypes assumable). + */ +function get_recordtype_from_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT type FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["type"]; + } + else + { + error(sprintf(ERR_INV_ARG, "get_recordtype_from_id")); + } +} + + +/* + * Retrieves the name (e.g. bla.test.com) of a record by a given id. + * return values: the name associated with the id. + */ +function get_name_from_record_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT name FROM records WHERE id=$id"); + $r = $result->fetchRow(); + return $r["name"]; + } + else + { + error(sprintf(ERR_INV_ARG, "get_name_from_record_id")); + } +} + + +/* + * Get all the domains from a database of which the user is the owner. + * return values: an array with the id of the domain and its name. + */ +function get_domains_from_userid($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT domains.id AS domain_id, domains.name AS name FROM domains LEFT JOIN zones ON domains.id=zones.domain_id WHERE owner=$id"); + + $ret = array(); + + // Put all the information in a big array. + while ($r = $result->fetchRow()) + { + $ret[] = array( + "id" => $r["domain_id"], + "name" => $r["name"] + ); + } + return $ret; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domains_from_userid", "This is not a valid userid: $id")); + } +} + + +/* + * Get domain name from a given id + * return values: the name of the domain associated with the id. + */ +function get_domain_name_from_id($id) +{ + global $db; + if (!xs($id)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($id)) + { + $result = $db->query("SELECT name FROM domains WHERE id=$id"); + if ($result->numRows() == 1) + { + $r = $result->fetchRow(); + return $r["name"]; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_name_from_id", "more than one domain found?! whaaa! BAD! BAD! Contact admin!")); + } + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_name_from_id", "Not a valid domainid: $id")); + } +} + + +/* + * Get information about a domain name from a given domain id. + * the function looks up the domainname, the owner of the domain and the number of records in it. + * return values: an array containing the information. + */ +function get_domain_info_from_id($id) +{ + global $db; + if (!xs($id)) + { + error(ERR_RECORD_ACCESS_DENIED); + } + if (is_numeric($id)) + { + + if ($_SESSION[$id."_ispartial"] == 1) { + + $sqlq = "SELECT domains.name AS name, + users.fullname AS owner, + count(record_owners.id) AS aantal + FROM domains, users, record_owners, records + + WHERE record_owners.user_id = ".$_SESSION["userid"]." + AND record_owners.record_id = records.id + AND records.domain_id = ".$id." + + GROUP BY name, owner, users.fullname + ORDER BY name"; + + $result = $db->getRow($sqlq); + + $ret = array( + "name" => $result["name"], + "ownerid" => $_SESSION["userid"], + "owner" => $result["owner"], + "numrec" => $result["aantal"] + ); + + return $ret; + + } else{ + + // Query that retrieves the information we need. + $sqlq = "SELECT domains.name AS name, + min(zones.owner) AS ownerid, + users.fullname AS owner, + count(records.domain_id) AS aantal + FROM domains + LEFT JOIN records ON domains.id=records.domain_id + LEFT JOIN zones ON domains.id=zones.domain_id + LEFT JOIN users ON zones.owner=users.id + WHERE domains.id=$id + GROUP BY name, owner, users.fullname + ORDER BY zones.id"; + + // Put the first occurence in an array and return it. + $result = $db->getRow($sqlq); + + //$result["ownerid"] = ($result["ownerid"] == NULL) ? $db->getOne("select min(id) from users where users.level=10") : $result["ownerid"]; + + $ret = array( + "name" => $result["name"], + "ownerid" => $result["ownerid"], + "owner" => $result["owner"], + "numrec" => $result["aantal"] + ); + return $ret; + } + + } + else + { + error(sprintf(ERR_INV_ARGC, "get_domain_num_records_from_id", "This is not a valid domainid: $id")); + } +} + + +/* + * Check if a domain is already existing. + * return values: true if existing, false if it doesnt exist. + */ +function domain_exists($domain) +{ + global $db; + + if (!level(5)) + { + error(ERR_LEVEL_5); + } + if (is_valid_domain($domain)) + { + $result = $db->query("SELECT id FROM domains WHERE name='$domain'"); + if ($result->numRows() == 0) + { + return false; + } + elseif ($result->numRows() >= 1) + { + return true; + } + } + else + { + error(ERR_DOMAIN_INVALID); + } +} + + +/* + * Get all domains from the database. + * This function gets all the domains from the database unless a user id is below 5. + * if a user id is below 5 this function will only retrieve records for that user. + * return values: the array of domains or -1 if nothing is found. + */ +function get_domains($userid=true,$letterstart=all,$rowstart=0,$rowamount=999999) +{ + global $db; + if((!level(5) || !$userid) && !level(10) && !level(5)) + { + $add = " AND zones.owner=".$_SESSION["userid"]; + } + else + { + $add = ""; + } + + $sqlq = "SELECT domains.id AS domain_id, + min(zones.owner) AS owner, + count(DISTINCT records.id) AS aantal, + domains.name AS domainname + FROM domains + LEFT JOIN zones ON domains.id=zones.domain_id + LEFT JOIN records ON records.domain_id=domains.id + WHERE 1 $add "; + if ($letterstart!=all && $letterstart!=1) { + $sqlq.=" AND domains.name LIKE '".$letterstart."%' "; + } elseif ($letterstart==1) { + $sqlq.=" AND "; + for ($i=0;$i<=9;$i++) { + $sqlq.="domains.name LIKE '".$i."%'"; + if ($i!=9) $sqlq.=" OR "; + } + } + $sqlq.=" GROUP BY domainname, domain_id + ORDER BY domainname + LIMIT $rowstart,$rowamount"; + + $result = $db->query($sqlq); + $result2 = $db->query($sqlq); + + $andnot=""; + while($r = $result2->fetchRow()) { + $andnot.=" AND domains.id!= '".$r["domain_id"]."' "; + } + +if ($letterstart!=all && $letterstart!=1) { + + $sqlq = "SELECT domains.id AS domain_id, + count(DISTINCT record_owners.record_id) AS aantal, + domains.name AS domainname + FROM domains, record_owners,records, zones + WHERE record_owners.user_id = '".$_SESSION["userid"]."' + AND (records.id = record_owners.record_id + AND domains.id = records.domain_id) + $andnot + AND domains.name LIKE '".$letterstart."%' + AND (zones.domain_id != records.domain_id AND zones.owner!='".$_SESSION["userid"]."') + GROUP BY domainname, domain_id + ORDER BY domainname"; + + $result_extra = $db->query($sqlq); + +} else { + + for ($i=0;$i<=9;$i++) { + $sqlq = "SELECT domains.id AS domain_id, + count(DISTINCT record_owners.record_id) AS aantal, + domains.name AS domainname + FROM domains, record_owners,records, zones + WHERE record_owners.user_id = '".$_SESSION["userid"]."' + AND (records.id = record_owners.record_id + AND domains.id = records.domain_id) + $andnot + AND domains.name LIKE '".$i."%' + AND (zones.domain_id != records.domain_id AND zones.owner!='".$_SESSION["userid"]."') + GROUP BY domainname, domain_id + ORDER BY domainname"; + + $result_extra[$i] = $db->query($sqlq); + } + +} + +/* + if ($result->numRows() == 0) + { + // Nothing found. + return -1; + } +*/ + + while($r = $result->fetchRow()) + { + $r["owner"] = ($r["owner"] == NULL) ? $db->getOne("select min(id) from users where users.level=10") : $r["owner"]; + $ret[$r["domainname"]] = array( + "name" => $r["domainname"], + "id" => $r["domain_id"], + "owner" => $r["owner"], + "numrec" => $r["aantal"] + ); + } + + +if ($letterstart!=all && $letterstart!=1) { + + while($r = $result_extra->fetchRow()) + { + $ret[$r["domainname"]] = array( + "name" => $r["domainname"]."*", + "id" => $r["domain_id"], + "owner" => $_SESSION["userid"], + "numrec" => $r["aantal"] + ); + $_SESSION["partial_".$r["domainname"]] = 1; + } + +} else { + + foreach ($result_extra as $result_e) { + while($r = $result_e->fetchRow()) + { + $ret[$r["domainname"]] = array( + "name" => $r["domainname"]."*", + "id" => $r["domain_id"], + "owner" => $_SESSION["userid"], + "numrec" => $r["aantal"] + ); + $_SESSION["partial_".$r["domainname"]] = 1; + } + } + +} + +if (empty($ret)) { + return -1; +} else { + sort($ret); + return $ret; +} + +} + + +/* + * Get a record from an id. + * Retrieve all fields of the record and send it back to the function caller. + * return values: the array with information, or -1 is nothing is found. + */ +function get_record_from_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT id, domain_id, name, type, content, ttl, prio, change_date FROM records WHERE id=$id"); + if($result->numRows() == 0) + { + return -1; + } + elseif ($result->numRows() == 1) + { + $r = $result->fetchRow(); + $ret = array( + "id" => $r["id"], + "domain_id" => $r["domain_id"], + "name" => $r["name"], + "type" => $r["type"], + "content" => $r["content"], + "ttl" => $r["ttl"], + "prio" => $r["prio"], + "change_date" => $r["change_date"] + ); + return $ret; + } + else + { + error(sprintf(ERR_INV_ARGC, "get_record_from_id", "More than one row returned! This is bad!")); + } + } + else + { + error(sprintf(ERR_INV_ARG, "get_record_from_id")); + } +} + + +/* + * Get all records from a domain id. + * Retrieve all fields of the records and send it back to the function caller. + * return values: the array with information, or -1 is nothing is found. + */ +function get_records_from_domain_id($id,$rowstart=0,$rowamount=999999) +{ + global $db; + if (is_numeric($id)) + { + if ($_SESSION[$id."_ispartial"] == 1) { + + $result = $db->query("SELECT record_owners.record_id as id + FROM record_owners,domains,records + WHERE record_owners.user_id = ".$_SESSION["userid"]." + AND record_owners.record_id = records.id + AND records.domain_id = ".$id." + GROUP bY record_owners.record_id + LIMIT $rowstart,$rowamount"); + + $ret = array(); + if($result->numRows() == 0) + { + return -1; + } + else + { + $ret[] = array(); + $retcount = 0; + while($r = $result->fetchRow()) + { + // Call get_record_from_id for each row. + $ret[$retcount] = get_record_from_id($r["id"]); + $retcount++; + } + return $ret; + } + + } else { + + $result = $db->query("SELECT id FROM records WHERE domain_id=$id LIMIT $rowstart,$rowamount"); + $ret = array(); + if($result->numRows() == 0) + { + return -1; + } + else + { + $ret[] = array(); + $retcount = 0; + while($r = $result->fetchRow()) + { + // Call get_record_from_id for each row. + $ret[$retcount] = get_record_from_id($r["id"]); + $retcount++; + } + return $ret; + } + + } + } + else + { + error(sprintf(ERR_INV_ARG, "get_records_from_domain_id")); + } +} + + +function get_users_from_domain_id($id) +{ + global $db; + $result = $db->getCol("SELECT owner FROM zones WHERE domain_id=$id"); + $ret = array(); + foreach($result as $uid) + { + $fullname = $db->getOne("SELECT fullname FROM users WHERE id=$uid"); + $ret[] = array( + "id" => $uid, + "fullname" => $fullname + ); + } + return $ret; +} + +function search_record($question) +{ + global $db; + $question = trim($question); + if (empty($question)) + { + $S_INPUT_TYPE = -1; + } + + /* now for some input-type searching */ + if (is_valid_ip($question) || is_valid_ip6($question)) + { + $S_INPUT_TYPE = 0; + } + elseif(is_valid_domain($question) || + is_valid_hostname($question) || + is_valid_mboxfw($question)) // I guess this one can appear in records table too (content?!) + { + $S_INPUT_TYPE = 1; + } + else + { + $S_INPUT_TYPE = -1; + } + switch($S_INPUT_TYPE) + { + case '0': + $sqlq = "SELECT * FROM `records` WHERE `content` = '".$question."' ORDER BY `type` DESC"; + $result = $db->query($sqlq); + $ret_r = array(); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_r[] = array( + 'id' => $r['id'], + 'domain_id' => $r['domain_id'], + 'name' => $r['name'], + 'type' => $r['type'], + 'content' => $r['content'], + 'ttl' => $r['ttl'], + 'prio' => $r['prio'], + 'change_date' => $r['change_date'] + ); + } + } + break; + + case '1' : + $sqlq = "SELECT `domains`.*, count(`records`.`id`) AS `numrec`, `zones`.`owner` + FROM `domains`, `records`, `zones` + WHERE `domains`.`id` = `records`.`domain_id` + AND `zones`.`domain_id` = `domains`.`id` + AND `domains`.`name` = '".$question."' + GROUP BY (`domains`.`id`)"; + + $result = $db->query($sqlq); + $ret_d = array(); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_d[] = array( + 'id' => $r['id'], + 'name' => $r['name'], + 'numrec' => $r['numrec'], + 'owner' => $r['owner'] + ); + } + } + + $sqlq = "SELECT * FROM `records` WHERE `name` = '".$question."' OR `content` = '".$question."' ORDER BY `type` DESC"; + $result = $db->query($sqlq); + while ($r = $result->fetchRow()) + { + if(xs($r['domain_id'])) + { + $ret_r[] = array( + 'id' => $r['id'], + 'domain_id' => $r['domain_id'], + 'name' => $r['name'], + 'type' => $r['type'], + 'content' => $r['content'], + 'ttl' => $r['ttl'], + 'prio' => $r['prio'], + ); + } + } + break; + } + if($S_INPUT_TYPE == 1) + { + return array('domains' => $ret_d, 'records' => $ret_r); + } + return array('records' => $ret_r); +} + +function get_domain_type($id) +{ + global $db; + $type = $db->getOne("SELECT `type` FROM `domains` WHERE `id` = '".$id."'"); + if($type == "") + { + $type = "NATIVE"; + } + return $type; + +} + +function change_domain_type($type, $id) +{ + global $db; + $result = $db->query("UPDATE `domains` SET `type` = '" .$type. "' WHERE `id` = '".$id."'"); +} +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/toolkit.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/toolkit.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,295 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: toolkit.inc.php +// Startdate: 26-10-2002 +// Description: general functions needed on a large variety of locations. +// Kills the db.inc.php. +// If you include this file you include the whole 'backend' +// +// $Id: toolkit.inc.php,v 1.13 2003/02/24 01:46:31 azurazu Exp $ +// + +/************* + * Constants * + *************/ + +define(ROWAMOUNT, 500); + +if (isset($_GET["start"])) { + define(ROWSTART, (($_GET["start"] - 1) * ROWAMOUNT)); + } else { + define(ROWSTART, 0); +} + +if (isset($_GET["letter"])) { + define(LETTERSTART, $_GET["letter"]); + $_SESSION["letter"] = $_GET["letter"]; +} elseif(isset($_SESSION["letter"])) { + define(LETTERSTART, $_SESSION["letter"]); +} else { + define(LETTERSTART, "a"); +} + +if(!@include_once("config.inc.php")) +{ + error("You have to create a config.inc.php!"); +} + +if(is_file( dirname(__FILE__) . '/../install.php')) +{ + error("You have to remove install.php before this program will run"); +} + +if(is_file( dirname(__FILE__) . '/../migrator.php')) +{ + error("You have to remove migrator.php before this program will run"); +} + +/* Database connection */ + +require_once("database.inc.php"); +// Generates $db variable to access database. + +/************* + * Includes * + *************/ + +require_once("error.inc.php"); +require_once("auth.inc.php"); +require_once("users.inc.php"); +require_once("dns.inc.php"); +require_once("record.inc.php"); + + +/************* + * Functions * + *************/ + +/* + * Display the page option: [1] [2] .. [n] + */ + +function show_pages($amount,$rowamount,$id='') +{ + if ($amount > $rowamount) { + if (!isset($_GET["start"])) $_GET["start"]=1; + echo "

Show page "; + for ($i=1;$i<=ceil($amount / $rowamount);$i++) { + if ($_GET["start"] == $i) { + echo "[ ".$i." ] "; + } else { + echo "[ ".$i." ] "; + } + } + echo "
"; + } +} + +/* + * Display the alphabetic option: [0-9] [a] [b] .. [z] + */ + +function show_letters($letterstart,$doms) +{ + foreach ($doms as $dom) { + if (is_numeric($dom["name"][0])) { + $letter_taken["0"] = 1; + } else { + $letter_taken[$dom["name"][0]] = 1; + } + } + + echo "Show domains beginning with:
"; + if ($letterstart == 1) { + echo "[ 0-9 ] "; + } elseif ($letter_taken["0"] != 1) { + echo "[ 0-9 ] "; + } else { + echo "[ 0-9 ] "; + } + + foreach (range('a','z') as $letter) { + if ($letterstart === $letter) { + echo "[ ".$letter." ] "; + } elseif ($letter_taken[$letter] != 1) { + echo "[ ".$letter." ] "; + } else { + echo "[ ".$letter." ] "; + } + } +} + +/* + * Print a nice useraimed error. + */ +function error($msg) +{ + // General function for printing critical errors. + if ($msg) + { + include_once("header.inc.php"); + ?> +

Oops! An error occured!

+
+

<< back

+ +

Success!

+
+ +

+ +

+
+

+ << back +

+

+ = $l) + { + return 1; + } + else + { + return 0; + } +} + +function xs($zoneid) +{ + global $db; + if (is_numeric($zoneid) && is_numeric($_SESSION["level"])) + { + $result = $db->query("SELECT id FROM zones WHERE owner=".$_SESSION["userid"]." AND domain_id=$zoneid"); + $result_extra = $db->query("SELECT record_owners.id FROM record_owners,records WHERE record_owners.user_id=".$_SESSION["userid"]." AND records.domain_id = $zoneid AND records.id = record_owners.record_id LIMIT 1"); + + if ($result->numRows() == 1 || $_SESSION["level"] >= 5) + { + $_SESSION[$zoneid."_ispartial"] = 0; + return true; + } + elseif ($result_extra->numRows() == 1) + { + $_SESSION[$zoneid."_ispartial"] = 1; + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} + +function get_status($res) +{ + if ($res == '0') + { + return "Inactive"; + } + elseif ($res == '1') + { + return "Active"; + } +} + +function parse_template_value($val, $domain, $webip, $mailip) +{ + $val = str_replace('##DOMAIN##', $domain, $val); + $val = str_replace('##WEBIP##', $webip, $val); + $val = str_replace('##MAILIP##', $mailip, $val); + return $val; +} + + +/* + * Validates an email address. + * Checks if there is something before the at '@' sign and its followed by a domain and a tld of minimum 2 + * and maximum of 4 characters. + */ +function is_valid_email($email) +{ + if(!eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.([a-z]{2,6}$)", $email)) + { + return false; + } + return true; +} +?> diff -r 2cd8c1649ba9 -r 58094faf794d inc/users.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/users.inc.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,369 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: users.inc.php +// Startdate: 26-10-2002 +// Description: all user modifications etc. are done here +// +// $Id: users.inc.php,v 1.8 2003/01/01 22:33:47 azurazu Exp $ +// + + + +/* + * Retrieve all users. + * Its to show_users therefore the odd name. Has to be changed. + * return values: an array with all users in it. + */ +function show_users($id='',$rowstart=0,$rowamount=9999999) +{ + global $db; + if(is_numeric($id)) + { + //When a user id is given, it is excluded from the userlist returned. + $add = " WHERE users.id!=$id"; + } + + // Make a huge query. + $sqlq = "SELECT users.id AS id, + users.username AS username, + users.fullname AS fullname, + users.email AS email, + users.description AS description, + users.level AS level, + users.active AS active, + count(zones.owner) AS aantal FROM users + LEFT JOIN zones ON users.id=zones.owner$add + GROUP BY + users.id, + users.username, + users.fullname, + users.email, + users.description, + users.level, + users.active + ORDER BY + users.fullname + LIMIT $rowstart,$rowamount"; + + // Execute the huge query. + $result = $db->query($sqlq); + $ret = array(); + $retcount = 0; + while ($r = $result->fetchRow()) + { + $ret[] = array( + "id" => $r["id"], + "username" => $r["username"], + "fullname" => $r["fullname"], + "email" => $r["email"], + "description" => $r["description"], + "level" => $r["level"], + "active" => $r["active"], + "numdomains" => $r["aantal"] + ); + } + return $ret; +} + + +/* + * Check if the given $userid is connected to a valid user. + * return values: true if user exists, false if users doesnt exist. + */ + function is_valid_user($id) +{ + global $db; + if(is_numeric($id)) + { + $result = $db->query("SELECT id FROM users WHERE id=$id"); + if ($result->numRows() == 1) + { + return true; + } + else + { + return false; + } + } +} + + +/* + * Gives a textdescribed value of the given levelid + * return values: the text associated with the level + */ +function leveldescription($id) +{ + // Fixed descriptions for each user level (feel free to edit, anyway..) + // Will get moved to the config file soon. + switch($id) + { + case 1: + global $NAME_LEVEL_1; + return $NAME_LEVEL_1; + break; + case 5: + global $NAME_LEVEL_5; + return $NAME_LEVEL_5; + break; + case 10: + global $NAME_LEVEL_10; + return $NAME_LEVEL_10; + break; + default: + return "Unknown"; + break; + } +} + + +/* + * Checks if a given username exists in the database. + * return values: true if exists, false if not. + */ +function user_exists($user) +{ + global $db; + $result = $db->query("SELECT id FROM users WHERE username='$user'"); + if ($result->numRows() == 0) + { + return false; + } + elseif($result->numRows() == 1) + { + return true; + } + else + { + error(ERR_UNKOWN); + } +} + + +/* + * Get all user info for the given user in an array. + * return values: the database style array with the information about the user. + */ +function get_user_info($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT id, username, fullname, email, description, level, active from users where id=$id"); + $r = $result->fetchRow(); + return $r; + } + else + { + error(sprintf(ERR_INV_ARGC,"get_user_info", "you gave illegal arguments: $id")); + } +} + + +/* + * Delete a user from the system + * return values: true if user doesnt exist. + */ +function delete_user($id) +{ + global $db; + if (!level(10)) + { + error(ERR_LEVEL_10); + } + if (is_numeric($id)) + { + $db->query("DELETE FROM users WHERE id=$id"); + $db->query("DELETE FROM zones WHERE owner=$id"); + return true; + // No need to check the affected rows. If the affected rows would be 0, + // the user isnt in the dbase, just as we want. + } + else + { + error(ERR_INV_ARG); + } +} + + +/* + * Adds a user to the system. + * return values: true if succesfully added. + */ +function add_user($user, $password, $fullname, $email, $level, $description, $active) +{ + global $db; + if (!level(10)) + { + error(ERR_LEVEL_10); + } + if (!user_exists($user)) + { + // Might have to be changed. + // TODO probably. + $description = mysql_escape_string($description); + + // Clean up the fullname + $fullname = mysql_escape_string($fullname); + is_valid_email($email); + + // Get id and insert information. + $idusers= $db->nextID('users'); + $db->query("INSERT INTO users (id, username, password, fullname, email, description, level, active) VALUES ($idusers, '$user', '" . md5($password) . "', '$fullname', '$email', '$description', '$level', '$active')"); + return true; + } + else + { + error(ERR_USER_EXISTS); + } +} + + +/* + * Edit the information of an user.. sloppy implementation with too many queries.. (2) :) + * return values: true if succesful + */ +function edit_user($id, $user, $fullname, $email, $level, $description, $active, $password) +{ + global $db; + if(!level(10)) { + error(ERR_LEVEL_10); + } + + // Might have to be changed. + // TODO + $description = mysql_escape_string($description); + $fullname = mysql_escape_string($fullname); + is_valid_email($email); + + $sqlquery = "UPDATE users set username='$user', fullname='$fullname', email='$email', level=$level, description='$description', active=$active "; + + if($password != "") + { + $sqlquery .= ", password= '" . md5($password) . "' "; + } + + $sqlquery .= "where id=$id" ; + + // Search the username that right now goes with this ID. + $result = $db->query("SELECT username from users where id=$id"); + $r = array(); + $r = $result->fetchRow(); + + // If the found username with this ID is the given username with the command.. execute. + + if($r["username"] == $user) + { + $db->query($sqlquery); + return true; + } + + // Its not.. so the user wants to change. + // Find if there is an id that has the wished username. + $otheruser = $db->query("SELECT id from users where username='$user'"); + if($otheruser->numRows() > 0) + { + error(ERR_USER_EXIST); + } + + // Its fine it seems.. :) + // Lets execute it. + else + { + $db->query($sqlquery); + return true; + } +} + +/* + * Change the pass of the user. + * The user is automatically logged out after the pass change. + * return values: none. + */ +function change_user_pass($currentpass, $newpass, $newpass2) +{ + global $db; + + // Check if the passwords are equal. + if($newpass != $newpass2) + { + error(ERR_USER_MATCH_NEW_PASS); + } + + // Retrieve the users password. + $result = $db->query("SELECT password, id FROM users WHERE username='". $_SESSION["userlogin"] ."'"); + $rinfo = $result->fetchRow(); + + // Check the current password versus the database password and execute the update. + if(md5($currentpass) == $rinfo["password"]) + { + $sqlquery = "update users set password='" . md5($newpass) . "' where id='" . $rinfo["id"] . "'"; + $db->query($sqlquery); + + // Logout the user. + logout("Pass changed please re-login"); + } + else + { + error(ERR_USER_WRONG_CURRENT_PASS); + } +} + + +/* + * Get a fullname when you have a userid. + * return values: gives the fullname from a userid. + */ +function get_fullname_from_userid($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT fullname FROM users WHERE id=$id"); + $r = $result->fetchRow(); + return $r["fullname"]; + } + else + { + error(ERR_INV_ARG); + } +} + + +/* + * Get a fullname when you have a userid. + * return values: gives the fullname from a userid. + */ +function get_owner_from_id($id) +{ + global $db; + if (is_numeric($id)) + { + $result = $db->query("SELECT fullname FROM users WHERE id=$id"); + if ($result->numRows() == 1) + { + $r = $result->fetchRow(); + return $r["fullname"]; + } + else + { + error(ERR_USER_NOT_EXIST); + } + } + error(ERR_INV_ARG); +} +?> diff -r 2cd8c1649ba9 -r 58094faf794d index.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/index.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,251 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: index.php,v 1.13 2003/05/10 20:20:05 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +/* +// Checks if the user migrated his database, can be deprecated in the future +function check_updated() +{ + global $db; + $checkzone = $db->query("select * from zones"); + $zonetables = $checkzone->tableInfo(); + //var_dump($zonetables[1]); + if(strcmp($zonetables[1]["name"], "name") == 0) + { + include_once("inc/header.inc.php"); + error("You have to migrate your database first! + + The reason for this migration is that PowerAdmin wasnt supporting the gmysql backend yet. Now it fully does we have to support it aswell. + The gmysql users another table and other fields though, therefore we had to change the layout of the zones table. In this version thats fully done, but before this we have to migrate it. + + Please be sure you have a working backup of your data! + we assume it all works but cant guarantuee it for 100% because we dont have + too many betatesters.
+ + Do the following to migrate: + - rename the file migrator.php-pa in your webdir to migrator.php. + - Go here to migrate it. + + It is recommended to synchronize your database aswell after the update"); + die(); + } +} + +// Call above function +check_updated(); +*/ + +if ($_POST["submit"]) +{ + $domain = trim($_POST["domain"]); + $owner = $_POST["owner"]; + $webip = $_POST["webip"]; + $mailip = $_POST["mailip"]; + $empty = $_POST["empty"]; + $dom_type = isset($_POST["dom_type"]) ? $_POST["dom_type"] : "NATIVE"; + if(!$empty) + { + $empty = 0; + if(!eregi('in-addr.arpa', $domain) && (!is_valid_ip($webip) || !is_valid_ip($mailip)) ) + { + $error = "Web or Mail ip is invalid!"; + } + } + if (!$error) + { + if (!is_valid_domain($domain)) + { + $error = "Domain name is invalid!"; + } + elseif (domain_exists($domain)) + { + $error = "Domain already exists!"; + } + //elseif (isset($mailip) && is_valid_ip( + else + { + add_domain($domain, $owner, $webip, $mailip, $empty, $dom_type); + clean_page(); + } + } +} + +if($_POST["passchange"]) +{ + if(strlen($_POST["newpass"]) < 4) + { + error('Length of the pass should be at least 4'); + } + else + { + change_user_pass($_POST["currentpass"], $_POST["newpass"], $_POST["newpass2"]); + } +} + +include_once("inc/header.inc.php"); +?> +

DNS Admin

+ + + +
+Welcome, . +
+ +Your userlevel is: () +

+ +

Error:

+ +Current domains in DNS (click to view or edit): +
+ +Number of domains: ".$num_domains."
"; + +if ($num_domains > ROWAMOUNT) { + show_letters(LETTERSTART,$doms); + echo "
"; +} + +$doms = get_domains(0,LETTERSTART); +show_pages(count($doms),ROWAMOUNT); + +?> + +
+ + + +
 NameRecordsOwner
 No domains in this listing, sorry.
+ + ">[ delete zone ] + ">
+ +You only administer some records of domains marked with an (*) + + +

+ + Create new domain:
+ + + + + + + + + + +
Domain name:">
Web IP:">
Mail IP:">
Owner: + +
Domain type: + +
Create zone without
applying records-template:
 
+ + + +

+
+Change your password:
+ + + + + +
Current password:
New Password:
New Password:
 
+
+ diff -r 2cd8c1649ba9 -r 58094faf794d install.php.orig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install.php.orig Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,213 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// | Add-ons: Wim Mostrey mostrey be> | +// +--------------------------------------------------------------------+ + +// Filename: install.php +// Description: installs your PowerAdmin +// +// $Id: install.php,v 1.12 2003/01/07 23:29:24 lyon Exp $ +// + +// addslashes to vars if magic_quotes_gpc is off +function slash_input_data(&$data) +{ + if ( is_array($data) ) + { + foreach ( $data as $k => $v ) + { + $data[$k] = ( is_array($v) ) ? slash_input_data($v) : addslashes($v); + } + } + return $data; +} + +set_magic_quotes_runtime(0); + +// If magic quotes is off, addslashes +if ( !get_magic_quotes_gpc() ) +{ + $_GET = slash_input_data($_GET); + $_POST = slash_input_data($_POST); + $_COOKIE = slash_input_data($_COOKIE); +} + + +error_reporting(E_ALL); +if(!@require_once("inc/config.inc.php")) +{ + error("You have to create a config.inc.php!"); +} +include_once("inc/header.inc.php"); + +$sup_types = array('mysql'); + +function error($msg=false) +{ + // General function for printing critical errors. + if ($msg) + { + ?> +

Oops! An error occured!

+
+

<< back

+ query($sqlusers); + + if($db->isError($resusers)) + { + error("Can not create table users in $dbdatabase"); + } + + $reszones = $db->query($sqlzones); + + if($db->isError($reszones)) + { + error("Can not create zones table in $dbdatabase"); + } + + $id = $db->nextID('users'); + + /* TODO next version: fix the strip_slashes. might give trouble upgrading :/ -Lyon */ + $sqlinsert = "INSERT INTO + users + VALUES ( + $id, + '". $_POST['login'] ."', + '". md5(stripslashes($_POST['password'])) ."', + '". $_POST["fullname"] ."', + '". $_POST["email"] ."', + '". $_POST["description"] ."', + 10, + 1)"; + + $resadmin = $db->query($sqlinsert); + + if($db->isError($resadmin)) + { + + error("Can not add the admin to database $dbdatabase.users"); + } + else + { + + ?> +

PowerAdmin has succesfully been installed.

+
+Remove this file (install.php) from your webdir.
+WARNING: PowerAdmin will not work until you delete install.php
+
+You can click here to start using PowerAdmin + +You didnt fill in one of the required fields!"; + } +} + +else +{ +?> + +

PowerAdmin for PowerDNS

+
+This config file will setup your database to be ready for PowerAdmin. Please fill in the next fields which will create an +administrator login.
+Fields marked with a * are required. +


+ +
+ + + + + + + +
Login Name: *
Password: *
Full name: *
Email: *
Description:
 
+
+ +

+PowerAdmin v1.0 Copyright ©2002 The +PowerAdmin Team diff -r 2cd8c1649ba9 -r 58094faf794d migrator.php-pa --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/migrator.php-pa Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,129 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ +// +// File: migrator.php +// Description: Migrates PowerAdmin 1.1.2 to the new 1.2 format + +if(!@include_once("inc/config.inc.php")) +{ + error("You have to create a config.inc.php!"); +} +require_once("inc/database.inc.php"); + +PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'error'); +function error($msg) +{ + // General function for printing critical errors. + include_once("inc/header.inc.php"); + ?> +

Oops! An error occured!

+
+ + code) + { + case -19: + echo "

It seems you already have your PowerAdmin migrated because the tables cant be + altered. Another problem can be that you dont ALTER right on your database, + check this if you think your database doesnt have the proper format yet!

"; + break; + case -18: + echo "

One of the tables required doesnt exist, please run + test_setup.php.

PEAR::DB Error: " . $msg->getDebugInfo(); + break; + default: + echo "Unknown error, sorry: PEAR::DB Returned: " . $msg->getDebugInfo(); + break; + } + } + else + { + echo $msg; + } + ?> + +

<< back

+ +

Success!

+
+ +

+ +

+
+

+ << back +

+

+ getCol("select id from zones"); + +foreach($zoneresult as $zr) +{ + // Look up the domain_id + $zonename = $db->getOne("select name from zones where zones.id=" . $zr); + // do a count, if the record already exists in the domains table, dont insert it + $dom_count = $db->query("select id from domains where name='$zonename'"); + if($dom_count->numRows() == 0) + { + $dom_id = $db->nextID("domains"); + $db->query("INSERT INTO domains(id, name, type) VALUES('$dom_id', '$zonename', 'NATIVE')"); + $db->query("UPDATE records SET domain_id=$dom_id where domain_id=$zr"); + $db->query("UPDATE zones SET name=$dom_id where id=$zr"); + } + else + { + $row = $dom_count->fetchRow(); + + $db->query('UPDATE records SET domain_id=' . $row["id"] . " where domain_id=$zr"); + $db->query('UPDATE zones SET name=' . $row['id'] . " where id=$zr"); + } +} + +if(!DB::isError($zoneresult)) +{ + $db->query("ALTER TABLE zones CHANGE name domain_id INT(11) NOT NULL"); + + message("Done updating your tables, enjoy your new PowerAdmin! + Please remove this file from your webdirectory!"); +} +else +{ + error("You seem to have no information in the table zones"); +} +?> diff -r 2cd8c1649ba9 -r 58094faf794d robots.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/robots.txt Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff -r 2cd8c1649ba9 -r 58094faf794d search.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/search.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,183 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: search.php +// Startdate: 9-01-2003 +// Searches the database for corresponding records or domains. +// +// The sourecode for this program was donated by DeViCeD, THANKS! +// +// $Id: search.php,v 1.1 2003/01/09 23:23:39 azurazu Exp $ +// + +require_once('inc/toolkit.inc.php'); + +if (isset($_POST['s_submit']) || isset($_POST['q'])) +{ + $submitted = true; + $search_result = search_record($_POST['q']); +} + + +// we will continue after the search form ... +include_once('inc/header.inc.php'); +?> +

Search zones or records

+
+Type a hostname or a record in the box below and press search to see if the record exists in the system. + + + + + + + + + + + +
Enter a hostname or IP address
 
+ + +
'; + + // let's check if we found any domains ... + if (count($search_result) == 2 && count($search_result['domains'])) + { + ?> + Domains found: +

+ + + + + + + + + + + + + + + +
 NameRecordsOwner
+ [ delete zone ]'; + } + else + { + echo ' '; + } + ?> +
+

+ + Records found: +

+ + + + + + + + + + + + + + + + + + +
 NameTypeContentPriorityTTL
+ + [ edit record ] + [ delete record ] + +
+ + + + + +
+ Nothing found for query "" +
+ + diff -r 2cd8c1649ba9 -r 58094faf794d seq_update.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/seq_update.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,55 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ +// +// File: seq_update.php +// Description: synches your database after manual insertions. +// Doesnt do much, just searches the highest record_id and updates the seq table with this + +require_once("inc/toolkit.inc.php"); +require_once("inc/header.inc.php"); + +// Ok we have to synch it all. +// What to do? Find the MAX(id) on each table and set it to the _seq table. + +echo "

Synching databases. This is useful if you did manual insertions (in case you havent been here yet)

"; + +if(!level(10)) +{ + error(ERR_LEVEL_10); +} + +function seq_update(&$item) +{ + global $db; + $number_u = $db->getOne("SELECT MAX(id) FROM $item"); + if($number_u > 1) + { + echo $number_u; + $number_u_seq = $db->getOne("SELECT id FROM " . $item . "_seq"); + if($number_u_seq < $number_u) + { + $number_u += 1; + $db->query("UPDATE " . $item . "_seq SET id='$number_u'"); + } + } +} + +$tables = array('users', 'zones', 'records', 'domains'); + +array_walk($tables, 'seq_update'); + +message("All tables are successfully synchronized."); + +php?> diff -r 2cd8c1649ba9 -r 58094faf794d style/style.css.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/style.css.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,147 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// +// $Id: style.css.php,v 1.4 2003/01/12 20:20:24 azurazu Exp $ +// + +include_once("../inc/config.inc.php"); +$bgcolor = "#FCC229"; //Original style +//$bgcolor = "#B5C6D2"; //Greenish style +?> + + +A:link { color: #000000} +A:visited { color: #000000} +A:active { color: #000000} +A:hover {text-decoration: none} +BODY {font-family: Verdana, Arial, Helvetica; background-image: url("images/background.jpg");} +TABLE {background-color: ; border: 1px solid #000000; width: 900px;} +TD {background-color: White; font-size: 12px;} +TR {background-color: } +.TDBG { + background-color: ; +} +.ERROR { + background-color: #FF0000; + border: 1px solid; + width: 600px; +} +.MESSAGETABLE { + background-color: ; + border: 1px solid; + width: 600px; +} + +.MESSAGE { + background-color: ; + width: 600px; +} +.NONE { + background-color: transparent; + border: none; + width: 0px; +} +.TEXT { + background-color: transparent !important; + border: 0px; +} +.SBUTTON { + BORDER-BOTTOM: #999999 1px solid; + BORDER-LEFT: #999999 1px solid; + BORDER-RIGHT: #999999 1px solid; + BORDER-TOP: #999999 1px solid; + BACKGROUND-COLOR: ; + COLOR: #000000; + BORDER-COLOR: #000000; + FONT-FAMILY: Verdana; + FONT-WEIGHT: Bold; + FONT-SIZE: 10px; + WIDTH MENARU: 60px; +} +.BUTTON { + BORDER-BOTTOM: #999999 1px solid; + BORDER-LEFT: #999999 1px solid; + BORDER-RIGHT: #999999 1px solid; + BORDER-TOP: #999999 1px solid; + BACKGROUND-COLOR: ; + COLOR: #000000; + BORDER-COLOR: #000000; + FONT-FAMILY: Verdana; + FONT-WEIGHT: Bold; + FONT-SIZE: 10px; + WIDTH MENARU: 120px; +} +.INPUT { + BORDER-BOTTOM: #999999 1px solid; + BORDER-LEFT: #999999 1px solid; + BORDER-RIGHT: #999999 1px solid; + BORDER-TOP: #999999 1px solid; + BACKGROUND-COLOR: #FFFFFF; + + COLOR: #000000; + BORDER-COLOR: #000000; + FONT-FAMILY: Verdana; + FONT-SIZE: 11px; + WIDTH MENARU: 180px; +} +.SINPUT { + BORDER-BOTTOM: #999999 1px solid; + BORDER-LEFT: #999999 1px solid; + BORDER-RIGHT: #999999 1px solid; + BORDER-TOP: #999999 1px solid; + BACKGROUND-COLOR: #FFFFFF; + COLOR: #000000; + BORDER-COLOR: #000000; + FONT-FAMILY: Verdana; + FONT-SIZE: 11px; + WIDTH MENARU: 40px; +} +.WARNING { + color: #FF0000; + font-weight: Bold; +} +.FOOTER { + font-size: 10px; +} +.ACTIVE { + color: #669933; + font-weight: Bold; +} +.INACTIVE { + color: #FF0000; + font-weight: Bold; +} +.NAV { + color: #0000FF; + font-weight: Bold; + A:link { color: #0000FF} + A:visited { color: #0000FF} + A:active { color: #0000FF} + A:hover {text-decoration: none} +} +.inputarea { + BORDER-BOTTOM: #999999 1px solid; + BORDER-LEFT: #999999 1px solid; + BORDER-RIGHT: #999999 1px solid; + BORDER-TOP: #999999 1px solid; + BACKGROUND-COLOR: #FFFFFF; + COLOR: #000000; + BORDER-COLOR: #000000; + FONT-FAMILY: Verdana; + FONT-SIZE: 11px; + WIDTH MENARU: 300px; + HEIGHT MENARU: 100px; +} diff -r 2cd8c1649ba9 -r 58094faf794d test_setup.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_setup.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,85 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ + +// Filename: test_setup.php +// Description: tests your PowerAdmin install. +// Adding tables? Increase the total count to (2^numberoftables)-1 +// Substract its binary value and put it in the last failure close. +// Yes this is binary, why? Because thats cool! Squeeky geeky stuff! +// +// $Id: test_setup.php,v 1.4 2003/01/08 00:40:08 azurazu Exp $ +// + +include_once("inc/header.inc.php"); +require_once("inc/config.inc.php"); +require_once("inc/database.inc.php"); + +// Initialize variables +global $db; +$bad_array = array(); +$check_tables = array('zones', 'users', 'records', 'domains'); + +function error() +{ + return true; +} + +PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'error'); + +foreach($check_tables as $table) +{ + if(DB::isError($db->query("select * from $table"))) + { + $bad_array[] = $table; + } +} + +$bad = (count($bad_array) == 0) ? false : true; + +// Start error or message output + +echo "

"; + +if($bad) +{ + ?>

Not all tables are ok!

Successful!

+
+ +Sorry, but there are error(s) found in the following table(s):.

Please fix these errors and run the script again.

+

+ diff -r 2cd8c1649ba9 -r 58094faf794d users.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/users.php Tue Apr 10 22:40:43 2007 +0000 @@ -0,0 +1,117 @@ + trancer nl> | +// | Sjeemz sjeemz nl> | +// +--------------------------------------------------------------------+ +// +// $Id: users.php,v 1.11 2003/02/05 23:22:33 azurazu Exp $ +// + +require_once("inc/toolkit.inc.php"); + +if($_POST["submit"] +&& $_POST["username"] != "" +&& $_POST["password"] != "" +&& $_POST["fullname"] != "" +&& $_POST["email"] != "" +&& $_POST["level"] > 0) +{ + if(substr_count($_POST["username"], " ") == 0) + { + add_user($_POST["username"], $_POST["password"], $_POST["fullname"], $_POST["email"], $_POST["level"], $_POST["description"], $_POST["active"]); + clean_page($BASE_URL . $BASE_PATH . "users.php"); + } + else + { + $error = "Usernames cant contain spaces"; + } +} +elseif($_POST["submit"]) +{ + $error = "Please fill in all fields"; +} + +// Dirty hack, maybe revise? +include_once("inc/header.inc.php"); +?> +

User Admin

+

Error:

Current users (click to edit):"; + +$users = show_users(''); + +echo "

Number of users: ".count($users); + +show_pages(count($users),ROWAMOUNT); +?> + +

+ + + + + + + +
 NameDomainsDomain listLevelStatus
">[ delete user ]"> () + ">[ delete domain ] ">
+

+ +
+Create new user:
+ + + + + + + + + +
User name:">
Full name:">
Password:">
E-mail:">
User level:
Description:
Active:
 
+
+