Dnsadmin
by Ken Jones
Dnsadmin is a GPL project to simply management of DNS information. It supports both bind and djbdns.
The simple way to install is as follows
That will compile and install dnsadmin. Next is to load your bind zone information into the database. If your named.conf is in the /etc directory (default). Just run dnsloadzone. It will automatically create all the needed mysql database/tables, read the named.conf information, parse each of the zone files and load them into the database.
From there you can run the cgi program to admin the DNS information. When you are ready to output your DNS information to bind zone or djbdns tinydns data file run eithe dnszone (for bind) or dnsdata (tinydns). These will create the needed bind or tinydns data files.
The intro API is to provide a simplied interface to the underlying code. More design is placed on optimizing the learning curve of the development programmer. These calls also simply writing the command line programs.
int domain_id dns_add_dom( char *domain );
First thing is you need are domains to work on. This call adds a domain to the system and returns back an internal domain_id integer used to optimize the data traffic. All is well if it returns greater or equal to 0.
int dns_del_dom( char *domain );
Once we add a domain we should be able to delete it. It is inteligent enough to attempt to make the integrity of the data store. Meaning it will also delete all the mx, host and nameserver records too. For more advance developers, the domain_id is the primary key used the tables for all the records.
int dns_add_ns( char *domain, char *nameserver );
Add a name server. The record only needs the domain you want to set a nameserver for and the fully qualified hostname of the domain name server. This call should be followed by a dns_add_host to set the IP for the nameserver.
int dns_del_ns( char *domain, char *nameserver );
Input the domain name and the name server you want to delete.
int dns_add_mx( char *domain, char *mailserver, int distance, char *mailzone );
The first inputs are easy to understand. The domain name, a mailserver name, the priority number 0 and greater. The last option is a bit strange and optional. If the mailzone = NULL then it uses the default domain name. If you want to set the indivdual mail server record for a single machine then set the mailzone to the fully qualified host name of the machine.
Create table domains ( domain_id int auto_increment not null, domain varchar(200) not null, primary key ( domain_id ) ); create index domains_idx on domains ( domains(20) );
The domains table contains a list of all the domains on the system. A domain_id integer is automatically assign when the domain is added using the auto_increment feature of mysql. This domain_id column is used as a key into all the other tables. There are two indexes on the table for efficency. The first index is required on the domain_id column because it is a mysql auto_increment column. The second index will probably be used more often, it is on the domain name column. It will be used when calls are made to lookup the domain_id for a particular domain name.
Create table nameservers ( domain_id int not null, nameserver varchar(200)not null, primary key ( domain_id ) ); create index namservers_idx on nameservers ( nameserver(20) );
The name server table keeps a list of all the name servers setup for a particular domain. It only contains the domain_id column and the name server. The IP address for the name server is stored in a host record for that name server. The two indexes are similar to the domains table. The first index is on the domain_id column so lookups based on domain_id are fast. The second is on the nameserver column to speed lookups based on name server only.
Create table mailservers ( domain_id int not null, mailserver varchar(200) not null, dist int, mailzone varchar(200), primary key ( domain_id ) ); create index mailservers_idx on mailservers ( mailserver(20) );
The mail server table keeps a list of each mail server defined for each domain. Mail server records require a distance value. This is the priority ( or distance ) that mail transfer agents use to decide which machine to connect. The lower a distance the higher the priority. 0 is the lowest value. The mail zone column specifies which host or domain to apply this mail server record to. Normally this column would be blank or contain the domain name. For sites which need to specify a different mailserver for particular hostnames or subdomains, you would place the hostname or the subdomain in the mailzone column.
There are two indexes on this table. The first is on the domain_id. Most queries will use this. The second is on the mailserver name column to speed lookups based on just the mailserver name.
The IP address for each of the mailserver records requires an entry in the hosts table.
Create table hosts ( domain_id int not null, host varchar(200) not null, host_type char, val varchar(200), primary key ( domain_id ) ); create index hosts_idx on hosts ( host(20) );
The hosts table keeps track of which IP's to assign to hostnames. For reverse records of host_type = H it also specifies the hostname to return for an IP.
Struct dns_dom_str
{ int domain_id;
char domain[200];
};Struct dns_ns_str
{ int domain_id;
char nameserver[200];
};Struct dns_mx_str
{ int domain_id;
char mailserver[200];
int dist;
char mailzon[200];
};Struct dns_host_struct
{ int domain_id;
host[200];
char host_type;
char val[200];
};The idea behind the structure API is to allow the calling function to use it's memory. Like the stat() call. You pass it a pointer to memory to fill in with the information. You can either malloc or staticly define your memory areas.
int dns_get_dom( dns_dom_str *doms );
Fill in the domain name in a dns_dom_str and pass the address to dns_get_dom(). It will use the domain field to perform an exact match. If it finds one it fills in the domain_id field and returns 0. On any error it does not touch the structure and returns a negative error code.
Here is some sample C code:
int ret;
struct dns_dom_str doms;
strncpy( doms.domain, inter7.com, 200);
while ( (ret=dns_get_dom( &doms )) == 1 ) {
printf(domain_id %d for domain %s\n, doms.domain_id, doms.domain);
}
if ( ret < 0 ) {
printf(error %d on dns_get_dom %s\n, ret, doms.domain);
}
int dns_search_dom( char *pattern, dns_dom_str *doms );Get all the domains that match a pattern. Fill in the dns_dom_str domain field with the substring you want to search for. It returns 1 for each row and fills in the domain_id and domain fields. After the last result it retuns a 0. On any error it returns a negative number.
Sample code:
int ret;
struct dns_dom_str doms;
strncpy( doms.domain, .com);
while ( (ret=dns_search_dom( &doms )) == 1 ) {
printf(domain %s domain_id %d\n,
doms.domain, doms.domain_id);
}
if ( ret < 0 ) {
printf(error %d on dns_search_dom\n, ret );
}int dns_get_host( dns_host_str *hosts );
Get all the host records for a domain. Fill in the domain_id field. It returns 1 for each row and puts the information in the structure. After the last row it returns 0. On any error it returns a negative number and doesn't touch the hosts structure.
Sample code:
int ret;
struct dns_host_str hosts;
/* get all the hosts for domain_id 100 */
hosts.domain_id = 100;
while ( (ret=dns_get_host( &hosts )) == 1 ) {
printf(host %s type %c val %s for domain_id %d\n,
hosts.host, hosts.host_type, hosts.val, hosts.domain_id);
}
if ( ret < 0 ) {
printf(error %d on dns_get_host for domain_id %d\n, ret, hosts.domain_id);
}int dns_get_ns( dns_ns_str *nss );
Get all the name server records for a domain. Fill in the dns_ns_str domain_id field. It retuns 1 for each record then returns 0 when there are no more records. On any error it returns less than 0. For each record it fills in the dns_ns_str structure.
int dns_get_mx ( dns_mx_str *mxs );
Get all the mail server records for a domain. Fill in the domain_id field. For each record it fills in the data and returns 1. When all records have been found it returns a 0. On any error it returns less than one and does not fill in the mx structure.
Example, get all the mail servers for domain_id 100:
int ret;
struct dns_mx_str mxs;
mxs.domain_id = 100;
while ( (ret=dns_get_mx( &mxs )) == 1 ) {
printf(mail server %s dist %d for domain_id %d\n,
mxs.mailserver, mxs.dist, mxs.domain_id);
}
if ( ret < 0 ) {
printf(error %d on dns_get_mx %d\n, ret, mxs.domain_id);
}