#include #include #include #include #include #include "internal.h" #include #include #include #include "../paths.h" #include "../diajava/proto.h" #include "netconf.m" #include #include static NETCONF_HELP_FILE help_resolv ("resolv"); static NETCONF_HELP_FILE help_host_conf ("host.conf"); static CONFIG_FILE f_resolv (ETC_RESOLV_CONF,help_resolv ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_netclient); static CONFIG_FILE f_host_conf (ETC_HOST_CONF,help_host_conf ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_netclient); #define MAX_SEARCH_RESOLV 6 #define MAX_NAMESERVER 3 class RESOLV{ public: VIEWITEMS_PARSER vip; VIEWITEMS items; SSTRING domain; SSTRING search[MAX_SEARCH_RESOLV]; IP_ADDR servers[MAX_NAMESERVER]; /*~PROTOBEG~ RESOLV */ public: RESOLV (void); private: void parse (const char *pt); public: void reset (void); int write (void); /*~PROTOEND~ RESOLV */ }; PRIVATE void RESOLV::parse (const char *pt) { int nb = 0; while (*pt != '\0'){ pt = str_skip(pt); char word[200]; pt = str_copyword(word,pt,sizeof(word)); if (word[0] == '\0') break; if (nb == MAX_SEARCH_RESOLV){ xconf_error (MSG_U(E_TOOMSEARCH ,"Too many entries in search statement\n" "in file %s") ,ETC_RESOLV_CONF); break; } search[nb++].setfrom (word); } } static const char K_DOMAIN[]="domain"; static const char K_NAMESERVER[]="nameserver"; static const char K_SEARCH[]="search"; PUBLIC RESOLV::RESOLV() : items (vip) { vip.sepchar = ' '; if (items.read (f_resolv) != -1){ char tmp[1000]; domain.setfrom (items.locateval (K_DOMAIN,tmp)); VIEWITEMS its; items.locate (K_NAMESERVER,its); for (int i=0; iline.get())); } its.remove_all(); items.locate (K_SEARCH,its); for (int i=0; iline.get())); } } } /* Forget all configuration */ PUBLIC void RESOLV::reset() { domain.setfrom (""); unsigned i; for (i=0; iline.setfromf ("%s %s",K_DOMAIN,domain.get()); }else{ items.remove_del (it); } { VIEWITEMS its; items.locate (K_NAMESERVER,its); for (int i=0; iline.setfromf ("%s %s",K_NAMESERVER,s); }else{ items.remove_del (it); } } } { VIEWITEMS its; items.locate (K_SEARCH,its); for (int i=0; iline.setfromf ("%s %s",K_SEARCH,s); }else{ items.remove_del (it); } } } return items.write (f_resolv,NULL); } static const char DNSCONF[]="DNSCONF"; static const char DNSNEEDED[]="dnsneeded"; static const char *tbsearch[]={ "sr1","sr2","sr3","sr4","sr5","sr6" }; void dnsconf_editresolv() { RESOLV res; DIALOG dia; char dnsneeded = (char)linuxconf_getvalnum (DNSCONF,DNSNEEDED,1); dia.newf_chk (MSG_U(F_DNSNEEDED,"DNS usage"),dnsneeded ,MSG_U(M_DNSNEEDED,"DNS is required for normal operation")); dia.newf_str (MSG_U(F_DEFDOM,"default domain"),res.domain); dia.newf_str (MSG_U(F_NAMESERV1,"IP of name server 1"),res.servers[0]); dia.newf_str (MSG_U(F_NAMESERV2,"IP of name server 2 (opt)"),res.servers[1]); dia.newf_str (MSG_U(F_NAMESERV3,"IP of name server 3 (opt)"),res.servers[2]); for (int i=0; iis_empty() && !s->is_valid()){ error.appendf (MSG_U(E_IVLDIPDNS ,"Invalid IP number for nameserver %d\n"),n+1); nofield = n + 2; } } if (error.is_empty()){ if (res.write() != -1){ linuxconf_setcursys (subsys_netclient); linuxconf_replace (DNSCONF,DNSNEEDED,dnsneeded); linuxconf_save(); break; } }else{ xconf_error (error.get()); } } } } static int resolv_chkchange( SSTRING &oldval, SSTRING &newval, bool verbose, const char *msg) { int ret = 0; if (oldval.cmp(newval)!=0){ ret = 1; if (verbose){ net_prtlog (NETLOG_CMD,msg,newval.get()); } } return ret; } /* Install a new resolv.conf with logging Return -1 if any error */ int resolv_updateconf ( const char *domain, SSTRING servers[3], SSTRINGS &search, bool verbose) { int ret = 0; RESOLV res; RESOLV nres; nres.reset(); nres.domain.setfrom (domain); int i; for (i=0; i<3; i++){ nres.servers[i].setfrom (servers[i].get()); } for (i=0; iget()); } int changes = 0; changes += resolv_chkchange (res.domain,nres.domain,verbose ,MSG_U(I_CHGDOMRES ,"Changing resolver domain to %s\n")); for (i=0; i<3; i++){ changes += resolv_chkchange ( res.servers[i],nres.servers[i] ,verbose ,MSG_U(I_CHGSERVER ,"Changing DNS server to %s\n")); } for (i=0; i 0){ if (verbose){ net_prtlog (NETLOG_CMD,MSG_U(I_UPDATING,"Updating %s\n") ,f_resolv.getpath()); } if (!simul_ison()) ret = nres.write(); } return ret; } /* Return != 0 if there is at least one nameserver specified in /etc/resolv.conf (IsReSoLv Configured). The resolver will use 127.0.0.1 if there is no nameserver entry, but some routine of linuxconf may assume that if there is no explicit nameserver, then this machine does not have one running either. This function also check if the DNS is really needed for normal operation of the computer. It will return 0 if the DNS is not needed. */ int dnsconf_isrslconf() { int ret = 0; if (linuxconf_getvalnum (DNSCONF,DNSNEEDED,1)){ RESOLV res; for (unsigned i=0; i ' ') */ static int dnsconf_strcmp(const char *str1, const char *str2) { int ret = -1; while (1){ str1 = str_skip(str1); str2 = str_skip(str2); if (*str1 == *str2){ if (*str1 == '\0'){ ret = 0; break; }else{ str1++; str2++; } }else{ ret = *str1 - *str2; break; } } return ret; } /* Read /etc/host.conf */ static void dnsconf_readhostconf ( VIEWITEMS &items, bool &multi, // Tell if the "multi" statement was seen unsigned char &order) // Will contain an index into tborder[] { items.read (f_host_conf); multi = false; order = 0; VIEWITEM *it = items.locate ("order"); if (it != NULL){ const char *pt = str_skipword(it->line.get()); for (int i=0; tborder[i] != NULL; i++){ if (dnsconf_strcmp(tborder[i],pt)==0){ order = i; break; } } } it = items.locate ("multi"); if (it != NULL){ const char *pt = str_skipword(it->line.get()); multi = stricmp(pt,"on")==0; } } /* Write /etc/host.conf */ static void dnsconf_writehostconf ( VIEWITEMS &items, bool multi, // Tell if the "multi" statement was seen unsigned char order) // Will contain an index into tborder[] { VIEWITEM *it = items.locate ("order"); char buf[100]; snprintf (buf,sizeof(buf)-1,"order %s",tborder[order]); if (it == NULL){ it = new VIEWITEM (buf); items.add (it); }else{ it->line.setfrom (buf); } it = items.locate ("multi"); if (multi){ if (it == NULL){ it = new VIEWITEM ("multi on"); items.add (it); }else{ it->line.setfrom ("multi on"); } }else{ items.remove_del (it); } items.write (f_host_conf,NULL); } /* Edit the file /etc/host.conf */ void dnsconf_editorder() { bool multi; unsigned char order; VIEWITEMS items; dnsconf_readhostconf(items,multi,order); DIALOG dia; dia.newf_chk ("",multi,MSG_U(F_MULTI,"Multiple IPs for one host")); dia.gui_passthrough (P_Dispolast,"l 3 c 1\n"); dia.newline(); dia.newf_title ("",""); dia.newline(); // User friendy version of tborder. It must have the same // order, line by line. "bind" just mean nothing to most people. static const char *tborder_v[]={ "hosts, NIS, dns", "hosts, NIS", "hosts, dns, NIS", "hosts, dns", "hosts", "NIS, hosts, dns", "NIS, hosts", "NIS, dns, hosts", "NIS, dns", "NIS", "dns, hosts, NIS", "dns, hosts", "dns, NIS, hosts", "dns, NIS", "dns", NULL }; for (int i=0; tborder_v[i] != NULL; i++){ if (i % 3 == 0 && i != 0) dia.newline(); dia.newf_radio ("",order,i,tborder_v[i]); } while (1){ if (dia.edit (MSG_U(T_NAMESERV,"Name service access") ,MSG_U(I_NAMESERV ,"You must tell the system in which order\n" "the various name services must be probed\n" "\n" "hosts mean /etc/hosts is probed\n" "NIS stand for Network Information System\n" "dns stands for Domain Name Service\n") ,help_host_conf)!=MENU_ACCEPT){ break; }else{ if (perm_rootaccess(MSG_U(P_WRITEHOSTS,"write /etc/host.conf"))){ dnsconf_writehostconf (items,multi,order); break; } } } } /* Obtain the default domain for dns search */ void resolv_getdomain (char *domain) { RESOLV res; res.domain.copy (domain); } #include static PUBLISH_VARIABLES_MSG resolv_var_list1[]={ {"defdom",P_MSG_R(F_DEFDOM)}, {"nameserver1",P_MSG_R(F_NAMESERV1)}, {"nameserver2",P_MSG_R(F_NAMESERV2)}, {"nameserver3",P_MSG_R(F_NAMESERV3)}, { NULL, NULL } }; static REGISTER_VARIABLES resolv_registry1("resolv",resolv_var_list1 ,NULL,dnsconf_editresolv); static PUBLISH_VARIABLES_STR resolv_var_list2[]={ {"searchdom1",tbsearch[0]}, {"searchdom2",tbsearch[1]}, {"searchdom3",tbsearch[2]}, {"searchdom4",tbsearch[3]}, {"searchdom5",tbsearch[4]}, {"searchdom6",tbsearch[5]}, { NULL, NULL } }; static REGISTER_VARIABLES resolv_registry2("resolv",resolv_var_list2, NULL,dnsconf_editresolv);