#pragma implementation #include #include #include #include #include #include #include #include #include #include #include "netconf.h" #include "netconf.m" #include #include "internal.h" #include static NETCONF_HELP_FILE help_others ("others"); static NETCONF_HELP_FILE help_netconf ("netconf"); static NETCONF_HELP_FILE help_netlevel ("netlevel"); static MESSAGE_DEF resetfw("resetfw"); static const char *tbargs[]={"...",NULL}; static MESSAGE_DEF dialoutmain ("dialoutmain",tbargs); /* Bring the system in sync with its configuration. */ void netconf_update(int msg) { if (perm_rootaccess(MSG_U(P_PERMUPDATE ,"update the status of the system"))){ if (!simul_ison()) net_introlog (msg); netconf_runlevel (-1); } } /* Bring the system in sync with its configuration. */ void netconf_update() { int msg = NETINTRO_UPDATE; if (file_exist (VAR_RUN_BOOTING)){ msg = NETINTRO_BOOTING; unlink (VAR_RUN_BOOTING); } netconf_update (msg); } /* Check what have to be done to bring the system in sync with its configuration. */ void netconf_status() { simul_init (stdout); printf (MSG_U(X_LIST ,"List of things required to activate current configuration\n")); netconf_update(NETINTRO_UPDATE); } static const char *your_system; static const char *other_hosts; static const char *other_networks; static const char *routing_tables; static const char *resolv; static const char *order; static const char *ipx; static const char *alias; static const char *htmlaccess; static const char *isolated; static void ft (void *p) { const char *key = (const char *)p; module_domenu (MENU_NETWORK_CLIENT,key); module_domenu (MENU_NETWORK_SERVER,key); module_domenu (MENU_NETWORK_BOOT,key); module_domenu (MENU_NETWORK_FIREWALL,key); module_domenu (MENU_NETWORK_MISC,key); if (key == isolated){ simple_install(); }else if (key == your_system){ netconf_edithost(); }else if (key == other_hosts){ netconf_edithosts(); }else if (key == other_networks){ netconf_editnet(); }else if (key == routing_tables){ netconf_editroutes(); }else if (key == resolv){ dnsconf_editresolv(); }else if (key == order){ dnsconf_editorder(); }else if (key == ipx){ ipx_edit(); }else if (key == alias){ alias_edit(); }else if (key == htmlaccess){ html_access_edit(); } } void netconf_edit() { /* #Specification: netconf / principal netconf use a large flat menu to direct the user to the proper configuration dialogs. The menu is splitted in several sections. # Basic informations. Client related configurations Server related configurations. Firewalling. # */ int choice=0; your_system = MSG_U(M_INFOR,"Host name and IP network devices"); other_hosts = MSG_U(M_HOSTS,"Information about other hosts"); other_networks = MSG_U(M_NETWORKS,"Information about other networks"); routing_tables = MSG_U(M_ROUTING,"Routing and gateways"); resolv= MSG_U(M_RESOLV,"Name server specification (DNS)"); order= MSG_U(M_ORDER,"Host name search path"); ipx= MSG_U(M_IPXCONF,"IPX interface setup"); alias = MSG_U(M_ALIAS,"IP aliases for virtual hosts"); htmlaccess = MSG_U(M_HTMLACCES,"Linuxconf network access"); isolated = MSG_U(M_ISOL,"Isolated/simple network from scratch"); static const char *menuopt1[]={ "-", MSG_U(T_CLIENTTASKS,"Client tasks"), "host:", your_system, "nameserver:", resolv, "routing:", routing_tables, "ipx:", ipx, NULL }; static const char *menuopt2[]={ "-", MSG_U(T_SERVER,"Server tasks"), "ipalias:", alias, NULL }; static const char *menuopt5[]={ "-", MSG_U(T_NETMISC,"Misc"), "otherhosts:", other_hosts, "othernetworks:", other_networks, "", htmlaccess, "search:", order, #if 0 "", isolated, #endif NULL }; DIALOG_MENU dia; dia.setsidetitle (MSG_U(T_NETWORKING,"NETWORKING")); dia.new_menuitems (menuopt1); module_setmenu (dia,MENU_NETWORK_CLIENT); dia.new_menuitems (menuopt2); module_setmenu (dia,MENU_NETWORK_SERVER); { dia.new_menuitem ("-",MSG_U(T_BOOT,"Boot services")); int nb = dia.getnb(); module_setmenu (dia,MENU_NETWORK_BOOT); if (nb == dia.getnb()) dia.remove_del(nb-1); } { dia.new_menuitem ("-",MSG_U(T_FIREWALL,"Firewalling")); int nb = dia.getnb(); module_setmenu (dia,MENU_NETWORK_FIREWALL); if (nb == dia.getnb()) dia.remove_del(nb-1); } dia.new_menuitems (menuopt5); module_setmenu (dia,MENU_NETWORK_MISC); while (1){ MENU_STATUS code = dia.editmenu ( MSG_U(T_NETWORK,"Network configurator") ,MSG_U(I_NETWORK,"This package allows you to configure a\n" "TCP/IP network from scratch using ethernet\n" "and modem (or other serial connection)") ,help_netconf ,choice,0); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else{ const char *key = dia.getmenustr(choice); uithread (ft,(void*)key); } } } /* Return 0 if nothing had to be done, 1 if it was done, 2 if the user don't want to quit -1 if something had to be done but was not done. */ EXPORT int netconf_checkupdate(bool showdontquit) { /* #Specification: configuration / probing for update linuxconf can compare the current (running) configuration of the machine with the intended (what is setup in configuration files) one. It will compute what has to be done to bring the machine in sync with the intended configuraiton. It will present a summary to the user and let him decide if he wants to activate this now or wait later. One (maybe) unrelated mecanism has been added here. The fixperm facility is included in the probing. It is expected that with both set of tests, the linux machine will be always up and running without puzzling bugs for the administrator. */ int ret = -1; netconf_getlastmsgs(); // Flush prior usage of netconf_system if (perm_rootaccess(MSG_R(P_PERMUPDATE))){ simul_init(); netconf_update(NETINTRO_UPDATE); ret = simul_prompt(showdontquit); if (ret==1){ net_setshowmode (false); netconf_update (NETINTRO_UPDATE); net_setshowmode (true); } } return ret; } static void usage() { xconf_error ("%s\n%s\n%s" ,MSG_U(E_NETCONF,"Netconf: Invalid arguments\n") ,MSG_U(I_USAGE, "netconf command line options\n" "\n" " --bootrc rc_dir_path [ previous_rc_dir_path ]\n" " --connect site [--fore]\n" " --dialctl\n" " --disconnect site\n" " --initnet\n" " --postconnect linuxconf_dialout site ppp-device\n" " --postconnect linuxconf_dialin site ppp-device\n" " --predisconnect linuxconf_dialout site ppp-device\n" " --predisconnect linuxconf_dialin site ppp-device\n" " --resetfw\n" " --runlevel 0|1|2\n" " --runlevel local|client|server\n" " --S00linuxconf\n" " --S99linuxconf\n" " --setdevdef no_device name ip netmask device\n" " --setgateway ip\n" " --setupdiald site iface mask local remote metric\n" " --status\n" " --update\n" "\n") ,MSG_U(E_NETCONFDEF,"`netconf' without an argument starts the interactive mode\n") ); exit (-1); } const char *netconf_getusage() { return MSG_R(I_USAGE); } static void netconf_gorun(const char *arg) { /* #Specification: netconf / runlevel option if netconf is run with the argument --runlevel, it will activate/desactivate all the daemons associated with this runlevel. It will also check if running daemons are informed of any changes in there configuration files. */ const char *pt = arg; int netmode=-1; if (strcmp(arg,"local")==0){ netmode = 0; }else if (strcmp(arg,"client")==0){ netmode = 1; }else if (strcmp(arg,"server")==0){ netmode = 2; }else{ int runlevel = atoi(arg); while (*pt != '\0'){ if (!isdigit(*pt)){ runlevel = -1; break; } pt++; } if (runlevel > 0 && runlevel < 7){ static char tb[7]={0 ,1 // Maintenance mode ,0 // Text mode only ,2 // Text mode and network (server mode) ,1 // X terminal ,0 // Graphic only ,2 // Graphic and network }; netmode = tb[runlevel]; } } if (netmode != -1){ net_introlog (NETINTRO_RUNLEVEL); netconf_runlevel (netmode); }else{ xconf_error (MSG_U(E_IVLRUNLEVEL ,"Invalid runlevel %s for network daemons\n" "Values 1,2,3,4,5,6 or local,client,server\n" "are valid.\n") ,arg); dialog_end(); } } void netconf_editrunlevel() { char level = (char)netconf_getnetlevel(); DIALOG dia; dia.newf_radio ("",level,0,MSG_U(F_LOCALMODE,"No network")); dia.newf_radio ("",level,1,MSG_U(F_CLIENTMODE,"Client mode")); dia.newf_radio ("",level,2,MSG_U(F_SERVERMODE,"Server")); if (dia.edit_form ( MSG_U(T_NETRUNLEVEL,"Network operation mode") ,MSG_U(I_NETRUNLEVEL,"") ,help_netlevel)==MENU_ACCEPT){ if (perm_rootaccess(MSG_U(E_NETRUNLEVEL ,"Change network operation mode"))){ netconf_setnetlevel (level); netconf_checkupdate(false); } } } static PRIVILEGE p_mainaccess ("mainaccess" ,P_MSG_U(T_MAINACCESS,"0-May use linuxconf") ,P_MSG_U(T_PSYSCONTROL,"0-General system control")); /* check if the user has the minimum privilege to enter the main menus of linuxconf. Return 0 if not. */ EXPORT bool netconf_mainaccess() { extern PRIVILEGE p_mainaccess; return perm_access (&p_mainaccess,MSG_U(P_MAINACCESS,"access linuxconf")); } /* check if the user is root. If not print a message and exit Return true if user is root */ EXPORT bool netconf_rootaccess(const char *msg) { if (getuid()!=0){ fprintf (stderr,"%s\n",msg); exit (-1); } return true; } EXPORT bool netconf_rootaccess() { return netconf_rootaccess (MSG_U(E_ONLYROOT ,"Only root is allowed to do that")); } int netconf_main (int argc, char *argv[]) { int ret = 0; if (netconf_mainaccess()){ if (argc == 1){ do { netconf_edit(); }while (netconf_checkupdate(true) == 2); }else if (argc == 2){ char *arg1 = argv[1]; if (strcmp(arg1,"--update")==0){ /* #Specification: netconf / option / --update netconf --update is equivalent to run netconf --runlevel with the current runlevel value. */ netconf_update(); }else if (strcmp(arg1,"--status")==0){ /* #Specification: netconf / option / --status netconf --status perform a simulation of netconf --update. It simply shows what netconf --update will do to activate the current configuration. Most of time, it prints only a header, since the system is "current". */ netconf_status(); }else if (strcmp(arg1,"--resetfw")==0){ /* #Specification: netconf / option / --resetfw netconf --resetfw turn off completly the firewalling configuration. This means that the machine is now wide open (as far as packet filtering goes). This only reset the "running" configuration, not the configuration itself. netconf --update will bring the firewall back to its previous state. */ module_sendmessage ("resetfw",0,NULL); }else if (strcmp(arg1,"--dialctl")==0){ /* #Specification: dialout / option / --dialctl netconf --dialctl presents a list of all available PPP/SLip dialout configuration in a menu and let the operator establish or terminate a connection. Normal privileges apply. */ if (module_sendmessage (dialoutmain,argc ,(const char **)argv)==LNCF_NOT_APPLICABLE){ xconf_error (MSG_U(E_NODIALOUTMODULE ,"The option --dialctl, --connect and --disconnect\n" "are hooks to enter the dialout module.\n" "But this module is currently disabled.\n" "Visit the control/control file & systems/linuxconf modules\n" "menu and enable it.")); } }else if (strcmp(arg1,"--S00linuxconf")==0){ if (perm_rootaccess(MSG_R(P_PERMUPDATE))){ netconf_s00linuxconf (2); } }else if (strcmp(arg1,"--S99linuxconf")==0){ if (perm_rootaccess(MSG_R(P_PERMUPDATE))){ netconf_s99linuxconf (2); } }else{ usage(); } }else if (argc >= 2 && strcmp(argv[1],"--initnet")==0){ if (perm_rootaccess(MSG_U(P_INITNET ,"Intialising the network"))){ net_introlog (NETINTRO_UPDATE); net_title (MSG_R(S_IPDEVICES)); SSTRINGS reconf; netconf_setdevices(NULL,reconf); net_title (MSG_R(S_IPXDEVICES)); ipx_set(NULL,reconf); net_title (MSG_R(S_IPROUTES)); route_install(NULL,true,true); } }else if (argc >= 3){ char *arg1 = argv[1]; if (strcmp(arg1,"--connect")==0){ /* #Specification: netconf / option / --connect netconf --connect establish a PPP or SLIP connection to a preconfigured site. */ ret = module_sendmessage (dialoutmain,argc,(const char **)argv); if (ret == LNCF_NOT_APPLICABLE){ fprintf (stderr,"%s\n",MSG_R(E_NODIALOUTMODULE)); } }else if (strcmp(arg1,"--disconnect")==0){ /* #Specification: netconf / option / --disconnect netconf --disconnect terminate a PPP or SLIP connection. */ ret = module_sendmessage (dialoutmain,argc,(const char **)argv); if (ret == LNCF_NOT_APPLICABLE){ fprintf (stderr,"%s\n",MSG_R(E_NODIALOUTMODULE)); } }else if (strcmp(arg1,"--postconnect")==0 && argc == 5){ ret = module_sendmessage (dialoutmain,argc,(const char **)argv); }else if (strcmp(arg1,"--predisconnect")==0 && argc == 5){ ret = module_sendmessage (dialoutmain,argc,(const char **)argv); }else if (strcmp(arg1,"--setdevdef")==0){ if (argc != 7){ usage(); }else if (netconf_rootaccess( MSG_U(E_SETETH0DEF ,"netconf --setdevdef can only be used by root\n"))){ host_setdevdef (atoi(argv[2]),argv[3],argv[4],argv[5],argv[6]); } }else if (strcmp(arg1,"--setupdiald")==0){ ret = module_sendmessage (dialoutmain,argc,(const char **)argv); }else if (strcmp(arg1,"--setgateway")==0){ if (argc != 3){ usage(); }else if (netconf_rootaccess(MSG_U(E_SETGATEWAY ,"netconf --setgateway can only be used by root\n"))){ groutes_setgateway (argv[2],false); } }else if (strcmp(arg1,"--setclockmode")==0){ if (argc != 3){ usage(); }else if (netconf_rootaccess(MSG_U(E_SETCLOCKMODE ,"netconf --setclockmode can only be used by root\n"))){ datetime_setmode (argv[2]); } }else if (strcmp(arg1,"--runlevel")==0){ netconf_gorun(argv[2]); }else if (strcmp(arg1,"--bootrc")==0){ if (argc != 3 && argc != 4){ fprintf (stderr,"%s\n",MSG_U(E_BOOTRC ,"netconf --bootrc path [ path ]")); }else if (perm_rootaccess(MSG_R(P_PERMUPDATE))){ bool booting = file_exist (VAR_RUN_BOOTING) != 0; unlink (VAR_RUN_BOOTING); net_introlog (booting ? NETINTRO_BOOTING : NETINTRO_RUNLEVEL); ret = bootrc_do (argv[2],argv[3],booting); } }else{ usage(); } }else{ usage(); } } return ret; }