Source of file api.multigen.php
Size: 154,965 Bytes - Last Modified: 2024-04-27T15:26:05+03:00
/tmp/current_snapshot/api/libs/api.multigen.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816 | <?php /** * Most awesome FreeRADIUS support implementation ever */ class MultiGen { /** * Contains system alter.ini config as key=>value * * @var array */ protected $altCfg = array(); /** * Contains system billing.ini config as key=>value * * @var array */ protected $billCfg = array(); /** * Contains all stargazer user data * * @var array */ protected $allUserData = array(); /** * Contains all tariff speeds as tariffname=>speeddata(speeddown/speedup) Kbit/s * * @var array */ protected $tariffSpeeds = array(); /** * Contains user speed overrides as login=>override speed in Kbit/s * * @var array */ protected $userSpeedOverrides = array(); /** * Contains array of user switch assigns as login=>asigndata * * @var array */ protected $userSwitchAssigns = array(); /** * Contains available QinQ data * * @var array */ protected $switchesQinQ = array(); /** * Contains available users qinq bindings * * @var array */ protected $usersQinQ = array(); /** * Contains available s-vlans * * @var array */ protected $allSvlan = array(); /** * Contains all realms * * @var array */ protected $allRealms = array(); /** * Contains array of available switches as id=>switchdata * * @var array */ protected $allSwitches = array(); /** * Contains existing users NAS bindings * * @var array */ protected $userNases = array(); /** * Contains available networks as id=>data * * @var array */ protected $allNetworks = array(); /** * Contains all users with ext networks assign * * @var array */ protected $netExtUsers = array(); /** * Contains available NAS servers as id=>data * * @var array */ protected $allNas = array(); /** * Contains array of NASes served networks as netid=>nasids array * * @var array */ protected $networkNases = array(); /** * Contains available nethosts as ip=>data * * @var array */ protected $allNetHosts = array(); /** * Contains array of nethosts to networks bindings like ip=>netid * * @var array */ protected $nethostsNetworks = array(); /** * Contains list of available NAS attributes presets to generate as id=>data * * @var array */ protected $nasAttributes = array(); /** * Contains multigen NAS options like usernames types etc as nasid=>options * * @var array */ protected $nasOptions = array(); /** * Contains previously loaded scenarios attributes as scenario=>username=>attributes * * @var array */ protected $currentAttributes = array(); /** * Contains previous user states as login=>previous/current/changed state * * @var array */ protected $userStates = array(); /** * System message helper object placeholder * * @var object */ protected $messages = ''; /** * Contains available username types as type=>name * * @var array */ protected $usernameTypes = array(); /** * Contains available nas service handlers as type=>name * * @var array */ protected $serviceTypes = array(); /** * Contains available operators as operator=>name * * @var array */ protected $operators = array(); /** * Contains default NAS attributes modifiers as id=>name * * @var array */ protected $attrModifiers = array(); /** * Contains available reply scenarios as stringid=>name * * @var array */ protected $scenarios = array(); /** * Contains NAS attributes regeneration stats as nasid=>scenario=>statsdata * * @var array */ protected $scenarioStats = array(); /** * Contains performance timers and stats * * @var array */ protected $perfStats = array(); /** * Contains interesting fields from database acct table * * @var array */ protected $acctFieldsRequired = array(); /** * Contains additional fields from database acct table * * @var array */ protected $acctFieldsAdditional = array(); /** * Contains preloaded user accounting data * * @var array */ protected $userAcctData = array(); /** * Contains NAS services templates as nasid=>services data * * @var array */ protected $services = array(); /** * Contains services names which requires run, like pod or coa * * @var array */ protected $runServices = array(); /** * User activity detection accuracy flag * * @var bool */ protected $accurateUserActivity = true; /** * Is logging enabled may be exported from MULTIGEN_LOGGING option * * @var int */ protected $logging = 0; /** * Contains innodb usage/optimization flag from OPTION_INNO * * @var int */ protected $inno = 0; /** * Contains unfinished acct flag from OPTION_UNFFLAG * * @var int */ protected $unfinished = 0; /** * Contains default accounting display days from OPTION_DAYS * * @var int */ protected $days = 1; /** * System caching object instance * * @var object */ protected $cache = ''; /** * Contains previous accounting traffic stats as login=>data * * @var array */ protected $previousTraffic = array(); /** * Contains ishimura archived year/month traffic stats for current month * * @var array */ protected $trafficArchive = array(); /** * Contains current accounting traffic stats as login=>data * * @var array */ protected $currentTraffic = array(); /** * Contains current stargazer users traffic stats as login=>data D0/U0 * * @var array */ protected $usersTraffic = array(); /** * Contains users current balance cash amount as login=>cash * * @var array */ protected $allUsersCash = array(); /** * Contains default echo path * * @var string */ protected $echoPath = '/bin/echo'; /** * Contains default path and options for radclient * * @var string */ protected $radclienPath = '/usr/local/bin/radclient -r 3 -t 1'; /** * Contains default path to sudo * * @var string */ protected $sudoPath = '/usr/local/bin/sudo'; /** * Contains default path to printf * * @var string */ protected $printfPath = '/usr/bin/printf'; /** * Default remote radclient port * * @var int */ protected $remotePort = 3799; /** * Ishimura enabled flag * * @var int */ protected $ishimuraFlag = 0; /** * Contains default usernames caching timeout in seconds * * @var int */ protected $usernamesCachingTimeout = 0; /** * Contains current multigen instance unique ID * * @var string */ protected $instanceId = ''; /** * stardust process manager instance * * @var object */ protected $stardust = ''; /** * Mea culpa protected instance * * @var object */ protected $meaCulpa = ''; /** * Is mea culpa enabled flag? * * @var bool */ protected $meaCulpaFlag = false; /** * Contains basic module path */ const URL_ME = '?module=multigen'; /** * Contains default user profile link */ const URL_PROFILE = '?module=userprofile&username='; /** * Default radius clients table/view name */ const CLIENTS = 'mlg_clients'; /** * Default NAS options table name */ const NAS_OPTIONS = 'mlg_nasoptions'; /** * Default services templates table name */ const NAS_SERVICES = 'mlg_services'; /** * Default NAS attributes templates table name */ const NAS_ATTRIBUTES = 'mlg_nasattributes'; /** * Default accounting table name */ const NAS_ACCT = 'mlg_acct'; /** * Default postauth table name */ const NAS_POSTAUTH = 'mlg_postauth'; /** * Default traffic aggregation table name */ const NAS_TRAFFIC = 'mlg_traffic'; /** * Default previous/current traffic stats table name */ const NAS_ISHIMURA = 'mlg_ishimura'; /** * Default user states database table name */ const USER_STATES = 'mlg_userstates'; /** * Default scenario tables prefix */ const SCENARIO_PREFIX = 'mlg_'; /** * Attributes generation logging option name */ const OPTION_LOGGING = 'MULTIGEN_LOGGING'; /** * RADIUS client option name */ const OPTION_RADCLIENT = 'MULTIGEN_RADCLIENT'; /** * sudo path option name */ const OPTION_SUDO = 'SUDO'; /** * Default inno-db performance fix option name */ const OPTION_INNO = 'MULTIGEN_MAKE_INNODB_GREAT_AGAIN'; /** * Default switches QinQ management option name */ const OPTION_QINQ = 'QINQ_ENABLED'; /** * Default user switchport assign option name */ const OPTION_SWASSIGN = 'SWITCHPORT_IN_PROFILE'; /** * Default universal QinQ management option name */ const OPTION_UNIVERSALQINQ = 'UNIVERSAL_QINQ_ENABLED'; /** * Default additional fields option */ const OPTION_FIELDS = 'MULTIGEN_FIELDSACCT'; /** * Default unfinished sessions flag option name */ const OPTION_UNFFLAG = 'MULTIGEN_UNFACCT'; /** * Default accounting days option name */ const OPTION_DAYS = 'MULTIGEN_DAYSACCT'; /** * Default ishimura mech enabling option name */ const OPTION_ISHIMURA = 'ISHIMURA_ENABLED'; /** * Usernames cache expiring timeout option name */ const OPTION_USERNAMESTIMEOUT = 'MULTIGEN_UNTIMEOUT'; /** * Extended networks option name */ const OPTION_EXTNETS = 'NETWORKS_EXT'; /** * Mea maxima culpa coinfig option name */ const OPTION_CULPA = 'MEACULPA_ENABLED'; /** * Default log path */ const LOG_PATH = 'exports/multigen.log'; /** * Contains default path to PoD scripts queue */ const POD_PATH = 'exports/pod_queue_'; /** * Contains default path to CoA scripts queue */ const COA_PATH = 'exports/coa_queue_'; /** * Default RemoteAPI lock name */ const MULTIGEN_PID = 'MULTIGEN'; /** * Creates new MultiGen instance * * @return void */ public function __construct() { $this->loadConfigs(); $this->setOptions(); $this->initMessages(); $this->initStarDust(); $this->initCache(); $this->loadNases(); $this->loadNasAttributes(); $this->loadNasOptions(); $this->loadNasServices(); } /** * Loads huge amounts of data, required only for attributes generation/processing * * @return void */ protected function loadHugeRegenData() { $this->loadUserData(); $this->loadNethosts(); $this->loadNetworks(); $this->loadTariffSpeeds(); $this->loadUserSpeedOverrides(); $this->preprocessUserData(); $this->loadSwitches(); $this->loadSwithchAssigns(); $this->loadAllQinQ(); $this->loadScenarios(); $this->loadUserStates(); $this->loadNetExtUsers(); $this->loadMeaCulpa(); } /** * Loads reqired configss * * @global object $ubillingConfig * * @return void */ protected function loadConfigs() { global $ubillingConfig; $this->altCfg = $ubillingConfig->getAlter(); $this->billCfg = $ubillingConfig->getBilling(); } /** * Sets some basic options for further usage * * @return void */ protected function setOptions() { if (isset($this->altCfg[self::OPTION_LOGGING])) { if ($this->altCfg[self::OPTION_LOGGING]) { $this->logging = $this->altCfg[self::OPTION_LOGGING]; } } if (isset($this->altCfg[self::OPTION_RADCLIENT])) { $this->radclienPath = $this->altCfg[self::OPTION_RADCLIENT]; } if (isset($this->billCfg[self::OPTION_SUDO])) { $this->sudoPath = $this->billCfg[self::OPTION_SUDO]; } if (isset($this->altCfg[self::OPTION_INNO])) { if ($this->altCfg[self::OPTION_INNO]) { $this->inno = $this->altCfg[self::OPTION_INNO]; } } if (isset($this->altCfg[self::OPTION_UNFFLAG])) { if ($this->altCfg[self::OPTION_UNFFLAG]) { $this->unfinished = $this->altCfg[self::OPTION_UNFFLAG]; } } if (isset($this->altCfg[self::OPTION_DAYS])) { if ($this->altCfg[self::OPTION_DAYS]) { $this->days = $this->altCfg[self::OPTION_DAYS]; } } if (isset($this->altCfg[self::OPTION_ISHIMURA])) { if ($this->altCfg[self::OPTION_ISHIMURA]) { $this->ishimuraFlag = $this->altCfg[self::OPTION_ISHIMURA]; } } if (isset($this->altCfg[self::OPTION_USERNAMESTIMEOUT])) { if ($this->altCfg[self::OPTION_USERNAMESTIMEOUT]) { $this->usernamesCachingTimeout = $this->altCfg[self::OPTION_USERNAMESTIMEOUT]; } } $this->instanceId = 'MLG' . zb_rand_string(8); $this->usernameTypes = array( 'login' => __('Login'), 'ip' => __('IP'), 'mac' => __('MAC') . ' ' . __('default'), 'macup' => __('MAC') . ' ' . __('upper case'), 'macju' => __('MAC') . ' ' . __('JunOS like') ); //some additional username types if ((isset($this->altCfg[self::OPTION_SWASSIGN])) AND ( isset($this->altCfg[self::OPTION_QINQ]))) { if (($this->altCfg[self::OPTION_SWASSIGN]) AND ( $this->altCfg[self::OPTION_QINQ])) { $this->usernameTypes['qinq'] = __('QinQ') . ' ' . __('default'); $this->usernameTypes['qinqju'] = __('QinQ') . ' ' . __('JunOS like'); } } // quia peccavi nimis // cogitatione, verbo // opere et omissione if (isset($this->altCfg[self::OPTION_CULPA])) { if ($this->altCfg[self::OPTION_CULPA]) { $this->usernameTypes['meaculpa'] = __('Mea culpa'); $this->meaCulpaFlag = true; } } $this->serviceTypes = array( 'none' => __('No'), 'coa' => __('CoA'), 'pod' => __('PoD'), 'podcoa' => __('PoD') . '+' . __('CoA') ); $this->scenarios = array( 'check' => 'check', 'reply' => 'reply', 'groupreply' => 'groupreply' ); $this->attrModifiers = array( 'all' => __('All'), 'active' => __('Active'), 'inactive' => __('Inactive') ); $this->operators = array( '=' => '=', ':=' => ':=', '==' => '==', '+=' => '+=', '!=' => '!=', '>' => '>', '>=' => '>=', '<=' => '<=', '=~' => '=~', '!~' => '!~', '=*' => '=*', '!*' => '!*', ); $this->acctFieldsRequired = array( 'acctsessionid', 'username', 'nasipaddress', 'nasportid', 'acctstarttime', 'acctstoptime', 'acctinputoctets', 'acctoutputoctets', 'framedipaddress', 'acctterminatecause' ); if (isset($this->altCfg[self::OPTION_FIELDS])) { if ($this->altCfg[self::OPTION_FIELDS]) { $this->acctFieldsAdditional = explode(',', $this->altCfg[self::OPTION_FIELDS]); } } } /** * Inits system message helper for further usage * * @return void */ protected function initMessages() { $this->messages = new UbillingMessageHelper(); } /** * Inits system caching object for further usage * * @return void */ protected function initCache() { $this->cache = new UbillingCache(); } /** * Inits process manager * * @return void */ protected function initStarDust() { $this->stardust = new StarDust(self::MULTIGEN_PID); } /** * Loads all existing users data from database * * @return void */ protected function loadUserData() { $this->allUserData = zb_UserGetAllData(); } /** * Loads all existing users data from database * * @return void */ protected function loadUserCash() { $this->allUsersCash = zb_UserGetAllBalance(); } /** * Loads existing tariffs speeds from database * * @return void */ protected function loadTariffSpeeds() { $this->tariffSpeeds = zb_TariffGetAllSpeeds(); } /** * Loads user speed overrides if they assigned for user * * @return void */ protected function loadUserSpeedOverrides() { $speedOverrides_q = "SELECT * from `userspeeds` WHERE `speed` NOT LIKE '0';"; $rawOverrides = simple_queryall($speedOverrides_q); if (!empty($rawOverrides)) { foreach ($rawOverrides as $io => $each) { $this->userSpeedOverrides[$each['login']] = $each['speed']; } } } /** * Loads switch port assigns from database * * @return void */ protected function loadSwithchAssigns() { if (@$this->altCfg[self::OPTION_SWASSIGN]) { $query = "SELECT * from `switchportassign`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->userSwitchAssigns[$each['login']] = $each; } } } } /** * Loads switches QinQ data from database * * @return void */ protected function loadAllQinQ() { if ((@$this->altCfg[self::OPTION_QINQ]) AND ( @$this->altCfg[self::OPTION_SWASSIGN])) { $qinq = new SwitchesQinQ(); $this->switchesQinQ = $qinq->getAllQinQ(); } if (@$this->altCfg[self::OPTION_UNIVERSALQINQ]) { $universalqinq = new UniversalQINQ(); $this->usersQinQ = $universalqinq->getAll(); $svlanObj = new VlanManagement(); $this->allSvlan = $svlanObj->getAllSvlan(); $this->allRealms = $svlanObj->getAllRealms(); } } /** * Loads all existing switches data from database * * @return void */ protected function loadSwitches() { $switchesTmp = zb_SwitchesGetAll(); if (!empty($switchesTmp)) { foreach ($switchesTmp as $io => $each) { $this->allSwitches[$each['id']] = $each; } } } /** * Prepares user to NAS bindings array * * @return void */ protected function preprocessUserData() { if (!empty($this->allUserData)) { foreach ($this->allUserData as $io => $each) { $userIP = $each['ip']; if (isset($this->nethostsNetworks[$userIP])) { if (isset($this->networkNases[$this->nethostsNetworks[$userIP]])) { $userNases = $this->networkNases[$this->nethostsNetworks[$userIP]]; $this->userNases[$each['login']] = $userNases; } } } } } /** * Loads existing networks from database * * @return void */ protected function loadNetworks() { $networksRaw = multinet_get_all_networks(); if (!empty($networksRaw)) { foreach ($networksRaw as $io => $each) { $this->allNetworks[$each['id']] = $each; } } } /** * Loads users extended networks data * * @return void */ protected function loadNetExtUsers() { if (isset($this->altCfg[self::OPTION_EXTNETS])) { if ($this->altCfg[self::OPTION_EXTNETS]) { $netExtUsers_q = "SELECT * from `netextpools` WHERE `login` <> '';"; $rawNetExtUsers = simple_queryall($netExtUsers_q); if (!empty($rawNetExtUsers)) { foreach ($rawNetExtUsers as $io => $each) { $this->netExtUsers[$each['login']] = $each['pool'] . "/" . $each['netmask']; } } } } } /** * Loads mea culpa instance for further usage * * @return void */ protected function loadMeaCulpa() { if ($this->meaCulpaFlag) { $this->meaCulpa = new MeaCulpa(); } } /** * Loads existing NAS servers from database * * @return void */ protected function loadNases() { $nasesRaw = zb_NasGetAllData(); if (!empty($nasesRaw)) { foreach ($nasesRaw as $io => $each) { $this->allNas[$each['id']] = $each; $this->networkNases[$each['netid']][$each['id']] = $each['id']; } } } /** * Loads existing NAS servers attributes generation optionss * * @return void */ protected function loadNasAttributes() { $query = "SELECT * from `" . self::NAS_ATTRIBUTES . "`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->nasAttributes[$each['id']] = $each; } } } /** * Loads previous user states from database * * @return void */ protected function loadUserStates() { $query = "SELECT * from `" . self::USER_STATES . "`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->userStates[$each['login']]['previous'] = $each['state']; $this->userStates[$each['login']]['current'] = ''; $this->userStates[$each['login']]['changed'] = ''; } } } /** * Loads multigen NAS options from database * * @return void */ protected function loadNasOptions() { $query = "SELECT * from `" . self::NAS_OPTIONS . "`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->nasOptions[$each['nasid']] = $each; } } } /** * Loads NAS services presets * * @return void */ protected function loadNasServices() { $query = "SELECT * from `" . self::NAS_SERVICES . "`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->services[$each['nasid']] = $each; } } } /** * Loads existing nethosts from database * * @return void */ protected function loadNethosts() { $query = "SELECT * from `nethosts`"; $nethostsRaw = simple_queryall($query); if (!empty($nethostsRaw)) { foreach ($nethostsRaw as $io => $each) { $this->allNetHosts[$each['ip']] = $each; $this->nethostsNetworks[$each['ip']] = $each['netid']; } } } /** * Loads existing scenarios attributes * * @return void */ protected function loadScenarios() { if (!empty($this->scenarios)) { foreach ($this->scenarios as $scenarioId => $scenarioName) { $query = "SELECT * from `" . self::SCENARIO_PREFIX . $scenarioId . "`"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->currentAttributes[$scenarioId][$each['username']][$each['attribute']]['name'] = $each['attribute']; $this->currentAttributes[$scenarioId][$each['username']][$each['attribute']]['value'] = $each['value']; $this->currentAttributes[$scenarioId][$each['username']][$each['attribute']]['op'] = $each['op']; } } } } } /** * Loading some accounting data from database * * @return void */ protected function loadAcctData() { $fieldsList = implode(', ', $this->acctFieldsRequired); if (!empty($this->acctFieldsAdditional)) { $fieldsList .= ', ' . implode(', ', $this->acctFieldsAdditional); } if (wf_CheckGet(array('datefrom', 'dateto'))) { $searchDateFrom = mysql_real_escape_string($_GET['datefrom']); $searchDateTo = mysql_real_escape_string($_GET['dateto']); } else { $curTime = time(); $dayAgo = $curTime - (86400 * $this->days); $dayAgo = date("Y-m-d", $dayAgo); $dayTomorrow = $curTime + 86400; $dayTomorrow = date("Y-m-d", $dayTomorrow); $searchDateFrom = $dayAgo; $searchDateTo = $dayTomorrow; } if (wf_CheckGet(array('showunfinished'))) { $unfQueryfilter = "AND `acctstoptime` IS NULL "; } else { $unfQueryfilter = ''; } if (wf_CheckGet(array('lastsessions'))) { $query = "SELECT * FROM `" . self::NAS_ACCT . "` GROUP BY `username` DESC ORDER BY `acctstarttime`;"; } else { $query = "SELECT " . $fieldsList . " FROM `" . self::NAS_ACCT . "` WHERE `acctstarttime` BETWEEN '" . $searchDateFrom . "' AND '" . $searchDateTo . "'" . " " . $unfQueryfilter . " ORDER BY `radacctid` DESC ;"; } $this->userAcctData = simple_queryall($query); } /** * Logs data if logging is enabled * * @param string $data * @param int $logLevel * * @return void */ protected function logEvent($data, $logLevel = 1) { if ($this->logging) { if ($this->logging >= $logLevel) { $curDate = curdatetime(); $logData = $curDate . ' ' . $data . "\n"; file_put_contents(self::LOG_PATH, $logData, FILE_APPEND); } } } /** * Renders NAS options editing form * * @param int $nasId * * @return string */ public function renderNasOptionsEditForm($nasId) { $result = ''; $nasId = vf($nasId, 3); if (isset($this->allNas[$nasId])) { $onlyActiveParams = array('1' => __('Yes'), '0' => __('No')); $inputs = wf_Selector('editnasusername', $this->usernameTypes, __('Username override'), @$this->nasOptions[$nasId]['usernametype'], false) . ' '; $inputs .= wf_Selector('editnasservice', $this->serviceTypes, __('Service'), @$this->nasOptions[$nasId]['service'], false) . ' '; $inputs .= wf_Selector('editnasonlyactive', $onlyActiveParams, __('Only active users'), @$this->nasOptions[$nasId]['onlyactive'], false) . ' '; $nasPort = @$this->nasOptions[$nasId]['port']; $nasPort = (!empty($nasPort)) ? $nasPort : $this->remotePort; $inputs .= wf_TextInput('editnasport', __('Port'), $nasPort, false, 6, 'digits') . ' '; $inputs .= wf_HiddenInput('editnasid', $nasId); $inputs .= wf_Submit(__('Save')); $result .= wf_Form(self::URL_ME . '&editnasoptions=' . $nasId, 'POST', $inputs, 'glamour'); } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('NAS not exists'), 'error'); } return ($result); } /** * Checks is NAS basically configured? * * @param int $nasId * * @return bool */ public function nasHaveOptions($nasId) { $result = false; $nasId = vf($nasId, 3); if (isset($this->allNas[$nasId])) { if (isset($this->nasOptions[$nasId])) { $result = true; } } return ($result); } /** * Saves NAS basic options * * @return void/string on error */ public function saveNasOptions() { $result = ''; if (wf_CheckPost(array('editnasid', 'editnasusername', 'editnasservice', 'editnasport'))) { $nasId = vf($_POST['editnasid'], 3); if (isset($this->allNas[$nasId])) { $newUserName = $_POST['editnasusername']; $newService = $_POST['editnasservice']; $newOnlyActive = $_POST['editnasonlyactive']; $newPort = $_POST['editnasport']; //some NAS options already exists if (isset($this->nasOptions[$nasId])) { $currentNasOptions = $this->nasOptions[$nasId]; $currentRecordId = $currentNasOptions['id']; $where = "WHERE `id`='" . $currentRecordId . "'"; if ($currentNasOptions['usernametype'] != $newUserName) { simple_update_field(self::NAS_OPTIONS, 'usernametype', $newUserName, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE USERNAME `' . $newUserName . '`'); } if ($currentNasOptions['service'] != $newService) { simple_update_field(self::NAS_OPTIONS, 'service', $newService, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE SERVICE `' . $newService . '`'); } if ($currentNasOptions['onlyactive'] != $newOnlyActive) { simple_update_field(self::NAS_OPTIONS, 'onlyactive', $newOnlyActive, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE ONLYACTIVE `' . $newOnlyActive . '`'); } if ($currentNasOptions['port'] != $newPort) { simple_update_field(self::NAS_OPTIONS, 'port', $newPort, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE PORT `' . $newPort . '`'); } } else { //new NAS options creation $newUserName_f = mysql_real_escape_string($newUserName); $newService_f = mysql_real_escape_string($newService); $newOnlyActive_f = mysql_real_escape_string($newOnlyActive); $newPort_f = vf($newPort, 3); $quyery = "INSERT INTO `" . self::NAS_OPTIONS . "` (`id`,`nasid`,`usernametype`,`service`,`onlyactive`,`port`) VALUES " . "(NULL,'" . $nasId . "','" . $newUserName_f . "','" . $newService_f . "','" . $newOnlyActive_f . "','" . $newPort_f . "');"; nr_query($quyery); log_register('MULTIGEN NAS [' . $nasId . '] CREATE USERNAME `' . $newUserName . '` SERVICE `' . $newService . '` ONLYAACTIVE `' . $newOnlyActive . '` PORT `' . $newPort . '`'); } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } } return ($result); } /** * Saves NAS services templates * * @return void/string on error */ public function saveNasServices() { $result = ''; if (wf_CheckPost(array('newnasservicesid'))) { $nasId = vf($_POST['newnasservicesid'], 3); if (isset($this->allNas[$nasId])) { $newPod = $_POST['newnasservicepod']; $newCoaConnect = $_POST['newnasservicecoaconnect']; $newCoaDisconnect = $_POST['newnasservicecoadisconnect']; //some NAS services already exists if (isset($this->services[$nasId])) { $currentNasServices = $this->services[$nasId]; $currentRecordId = $currentNasServices['id']; $where = "WHERE `id`='" . $currentRecordId . "'"; //update pod script template if ($currentNasServices['pod'] != $newPod) { simple_update_field(self::NAS_SERVICES, 'pod', $newPod, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE SERVICE POD'); } //update coa connect script template if ($currentNasServices['coaconnect'] != $newCoaConnect) { simple_update_field(self::NAS_SERVICES, 'coaconnect', $newCoaConnect, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE SERVICE COACONNECT'); } //update coa disconnect script template if ($currentNasServices['coadisconnect'] != $newCoaDisconnect) { simple_update_field(self::NAS_SERVICES, 'coadisconnect', $newCoaDisconnect, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE SERVICE COADISCONNECT'); } } else { //new NAS services creation $newPod_f = mysql_real_escape_string($newPod); $newCoaConnect_f = mysql_real_escape_string($newCoaConnect); $newCoaDisconnect_f = mysql_real_escape_string($newCoaDisconnect); $quyery = "INSERT INTO `" . self::NAS_SERVICES . "` (`id`,`nasid`,`pod`,`coaconnect`,`coadisconnect`) VALUES " . "(NULL,'" . $nasId . "','" . $newPod_f . "','" . $newCoaConnect_f . "','" . $newCoaDisconnect_f . "');"; nr_query($quyery); log_register('MULTIGEN NAS [' . $nasId . '] CREATE SERVICES'); } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } } return ($result); } /** * Returns list of attribute presets for some NAS * * @param int $nasId * * @return array */ protected function getNasAttributes($nasId) { $result = array(); if (!empty($this->nasAttributes)) { foreach ($this->nasAttributes as $io => $each) { if ($each['nasid'] == $nasId) { $result[$io] = $each; } } } return ($result); } /** * Returns list of services for some NAS * * @param int $nasId * * @return array */ protected function getNasServices($nasId) { $result = array(); if (!empty($this->services)) { foreach ($this->services as $io => $each) { if ($each['nasid'] == $nasId) { $result[$io] = $each; } } } return ($result); } /** * Deletes some attribute preset * * @param int $attributeId * * @return void/string on error */ public function deleteNasAttribute($attributeId) { $result = ''; $attributeId = vf($attributeId, 3); if (isset($this->nasAttributes[$attributeId])) { $attributeData = $this->nasAttributes[$attributeId]; $query = "DELETE from `" . self::NAS_ATTRIBUTES . "` WHERE `id`='" . $attributeId . "';"; nr_query($query); log_register('MULTIGEN ATTRIBUTE `' . $attributeData['attribute'] . '` DELETE [' . $attributeId . ']'); } else { $result .= __('Something went wrong') . ': ' . __('not existing attribute'); } return ($result); } /** * Flushes all attributes for all scenarios * * @return void */ public function flushAllScenarios() { if (!empty($this->scenarios)) { foreach ($this->scenarios as $scenarioId => $scenarioName) { $query = "TRUNCATE TABLE `" . self::SCENARIO_PREFIX . $scenarioId . "`;"; nr_query($query); log_register('MULTIGEN FLUSH SCENARIO `' . $scenarioId . '`'); } } } /** * Performs cleanup of accounting data for some period * * @param int $days * @param int $unfinished * * @return void */ public function cleanupAccounting($daysCount = 0, $unfinished = 0) { $daysCount = ubRouting::filters($daysCount, 'int'); if ($daysCount) { $intervalq = "<= NOW() - INTERVAL " . $daysCount . " DAY "; //old finished sessions, accounting data $query = "DELETE FROM `" . self::NAS_ACCT . "` WHERE `acctstarttime` " . $intervalq . " AND `acctstoptime` IS NOT NULL"; nr_query($query); //postauth $query = "DELETE FROM `" . self::NAS_POSTAUTH . "` WHERE `authdate` " . $intervalq; nr_query($query); if ($unfinished) { //old unfinished sessions (seems its dead) $query = "DELETE FROM `" . self::NAS_ACCT . "` WHERE `acctupdatetime` " . $intervalq . " AND `acctstoptime` IS NULL"; nr_query($query); } log_register('MULTIGEN ACCOUNTING CLEANUP `' . $daysCount . '` DAYS'); } } /** * Renders list of flushed scenarios * * @return string */ public function renderFlushAllScenariosNotice() { $result = ''; if (!empty($this->scenarios)) { foreach ($this->scenarios as $scenarioId => $scenarioName) { $result .= $this->messages->getStyledMessage(__('All attributes in scenario was deleted') . ': ' . $scenarioId, 'error'); } } return ($result); } /** * Renders list of available attributes for some NAS * * @param int $nasId * * @return string */ public function renderNasAttributesList($nasId) { $result = ''; $nasId = vf($nasId, 3); if (isset($this->allNas[$nasId])) { $currentAtrributes = $this->getNasAttributes($nasId); if (!empty($currentAtrributes)) { $cells = wf_TableCell(__('Users')); $cells .= wf_TableCell(__('Scenario')); $cells .= wf_TableCell(__('Attribute')); $cells .= wf_TableCell(__('Operator')); $cells .= wf_TableCell(__('Value')); $cells .= wf_TableCell(__('Actions')); $rows = wf_TableRow($cells, 'row1'); foreach ($currentAtrributes as $io => $each) { $cells = wf_TableCell($this->attrModifiers[$each['modifier']]); $cells .= wf_TableCell($each['scenario']); $cells .= wf_TableCell($each['attribute']); $cells .= wf_TableCell($each['operator']); $cells .= wf_TableCell($each['content']); $attributeControls = wf_JSAlert(self::URL_ME . '&editnasoptions=' . $nasId . '&deleteattributeid=' . $each['id'], web_delete_icon(), $this->messages->getDeleteAlert()) . ' '; $attributeControls .= wf_modalAuto(web_edit_icon(), __('Edit'), $this->renderAttributeTemplateEditForm($each['id'])); $cells .= wf_TableCell($attributeControls); $rows .= wf_TableRow($cells, 'row5'); } $result .= wf_TableBody($rows, '100%', 0, 'sortable'); } else { $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning'); } } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('NAS not exists'), 'error'); } return ($result); } /** * Renders NAS attributes creation form * * @param int $nasId * * @return string */ public function renderNasAttributesCreateForm($nasId) { $result = ''; $nasId = vf($nasId, 3); if (isset($this->allNas[$nasId])) { $inputs = ''; $inputs .= wf_Selector('newmodifier', $this->attrModifiers, __('Users'), '', false) . ' '; $inputs .= wf_Selector('newscenario', $this->scenarios, __('Scenario'), '', false) . ' '; $inputs .= wf_TextInput('newattribute', __('Attribute'), '', false, 20) . ' '; $inputs .= wf_Selector('newoperator', $this->operators, __('Operator'), '', false) . ' '; $inputs .= wf_TextInput('newcontent', __('Value'), '', false, 20) . ' '; $inputs .= wf_HiddenInput('newattributenasid', $nasId); $inputs .= wf_Submit(__('Create')); //form assembly $result .= wf_Form(self::URL_ME . '&editnasoptions=' . $nasId, 'POST', $inputs, 'glamour'); } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('NAS not exists'), 'error'); } return ($result); } /** * Renders existing NAS attribute template editing forms * * @param int $attributeId * * @return string */ public function renderAttributeTemplateEditForm($attributeId) { $result = ''; $attributeId = vf($attributeId, 3); if (isset($this->nasAttributes[$attributeId])) { $attributeData = $this->nasAttributes[$attributeId]; $nasId = $attributeData['nasid']; $inputs = ''; $inputs .= wf_Selector('chmodifier', $this->attrModifiers, __('Users'), $attributeData['modifier'], false) . ' '; $inputs .= wf_Selector('chscenario', $this->scenarios, __('Scenario'), $attributeData['scenario'], false) . ' '; $inputs .= wf_TextInput('chattribute', __('Attribute'), $attributeData['attribute'], false, 20) . ' '; $inputs .= wf_Selector('choperator', $this->operators, __('Operator'), $attributeData['operator'], false) . ' '; $currentContent = htmlspecialchars($attributeData['content']); $inputs .= wf_TextInput('chcontent', __('Value'), $currentContent, false, 20) . ' '; $inputs .= wf_HiddenInput('chattributenasid', $nasId); $inputs .= wf_HiddenInput('chattributeid', $attributeId); $inputs .= wf_Submit(__('Save')); //form assembly $result .= wf_Form(self::URL_ME . '&editnasoptions=' . $nasId, 'POST', $inputs, 'glamour'); } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': EX_ATTRIBUTEID_NOT_EXIST', 'error'); } return ($result); } /** * Creates new NAS attribute preset * * * @return void/string on error */ public function createNasAttribute() { $result = ''; if (wf_CheckPost(array('newattributenasid'))) { $nasId = vf($_POST['newattributenasid'], 3); if (isset($this->allNas[$nasId])) { if (ubRouting::checkPost(array('newscenario', 'newattribute', 'newoperator', 'newmodifier'))) { $newScenario = ubRouting::post('newscenario'); $newScenario_f = ubRouting::filters($newScenario, 'mres'); $newModifier = ubRouting::post('newmodifier'); $newModifier_f = ubRouting::filters($newModifier, 'mres'); $newAttribute = ubRouting::post('newattribute'); $newAttribute_f = ubRouting::filters($newAttribute, 'mres'); $newAttribute_f = trim($newAttribute_f); $newOperator = ubRouting::post('newoperator'); $newOperator_f = ubRouting::filters($newOperator, 'mres'); $newContent = ubRouting::post('newcontent'); $newContent_f = ubRouting::filters($newContent, 'mres'); $newContent_f = trim($newContent_f); $query = "INSERT INTO `" . self::NAS_ATTRIBUTES . "` (`id`,`nasid`,`scenario`,`modifier`,`attribute`,`operator`,`content`) VALUES " . "(NULL,'" . $nasId . "','" . $newScenario_f . "','" . $newModifier_f . "','" . $newAttribute_f . "','" . $newOperator_f . "','" . $newContent_f . "');"; nr_query($query); $newId = simple_get_lastid(self::NAS_ATTRIBUTES); log_register('MULTIGEN NAS [' . $nasId . '] CREATE ATTRIBUTE `' . $newAttribute . '` ID [' . $newId . ']'); } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } } return ($result); } /** * Creates new NAS attribute preset * * * @return void/string on error */ public function saveNasAttribute() { $result = ''; if (wf_CheckPost(array('chattributenasid'))) { $nasId = vf($_POST['chattributenasid'], 3); if (isset($this->allNas[$nasId])) { if (ubRouting::checkPost(array('chscenario', 'chattribute', 'choperator', 'chmodifier'))) { $attributeId = vf($_POST['chattributeid'], 3); if (isset($this->nasAttributes[$attributeId])) { $chAttribute = ubRouting::post('chattribute'); $chAttribute = trim($chAttribute); $chContent = ubRouting::post('chcontent'); $chContent = trim($chContent); $where = "WHERE `id`='" . $attributeId . "';"; simple_update_field(self::NAS_ATTRIBUTES, 'scenario', ubRouting::post('chscenario'), $where); simple_update_field(self::NAS_ATTRIBUTES, 'modifier', ubRouting::post('chmodifier'), $where); simple_update_field(self::NAS_ATTRIBUTES, 'attribute', $chAttribute, $where); simple_update_field(self::NAS_ATTRIBUTES, 'operator', ubRouting::post('choperator'), $where); simple_update_field(self::NAS_ATTRIBUTES, 'content', $chContent, $where); log_register('MULTIGEN NAS [' . $nasId . '] CHANGE ATTRIBUTE [' . $attributeId . ']'); } else { $result .= __('Something went wrong') . ': EX_ATTRIBUTE_NOT_EXIST'; } } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } } return ($result); } /** * Creates user state if its not exists * * @param string $login * @param int $state * * @return void */ protected function createUserState($login, $state) { $login = mysql_real_escape_string($login); $state = mysql_real_escape_string($state); $query = "INSERT INTO `" . self::USER_STATES . "` (`id`,`login`,`state`) VALUES "; $query .= "(NULL,'" . $login . "'," . $state . ");"; nr_query($query); } /** * Deletes some user state from states table * * @param string $login * * @return void */ protected function deleteUserState($login) { $login = mysql_real_escape_string($login); $query = "DELETE FROM `" . self::USER_STATES . "` WHERE `login`='" . $login . "';"; nr_query($query); } /** * Changes user state in database * * @param string $login * @param int $state * * @return void */ protected function changeUserState($login, $state) { $where = "WHERE `login`='" . $login . "'"; simple_update_field(self::USER_STATES, 'state', $state, $where); } /** * Saves user states into database if something changed * * @return void */ protected function saveUserStates() { if (!empty($this->userStates)) { foreach ($this->userStates as $login => $state) { if ($state['changed'] == 3) { //new user state appeared if ($state != '') { $this->createUserState($login, $state['current']); $this->logEvent('USERSTATE CREATED ' . $login . ' STATE ' . $state['current'], 3); } } else { //user state changed if ($state['current'] != $state['previous']) { if (isset($this->allUserData[$login])) { $this->changeUserState($login, $state['current']); $this->logEvent('USERSTATE CHANGED ' . $login . ' STATE ' . $state['previous'] . ' ON ' . $state['current'], 3); } } } } } } /** * Checks is user active or not * * @param string $userLogin * * @return bool */ protected function isUserActive($userLogin) { $result = false; if (isset($this->allUserData[$userLogin])) { //not existing users is inactive by default if ($this->accurateUserActivity) { //full checks for users activity, may be optional in future if ($this->allUserData[$userLogin]['Cash'] >= '-' . abs($this->allUserData[$userLogin]['Credit'])) { if ($this->allUserData[$userLogin]['Passive'] == 0) { if ($this->allUserData[$userLogin]['AlwaysOnline'] == 1) { if ($this->allUserData[$userLogin]['Down'] == 0) { $result = true; } } } } } else { //just check financial data $result = ($this->allUserData[$userLogin]['Cash'] >= '-' . $this->allUserData[$userLogin]['Credit']) ? true : false; } } return ($result); } /** * Checks is some user attribute available in scenario and is not changed * * @param string $scenario * @param string $userLogin * @param string $userName * @param string $attribute * @param string $operator * @param string $value * * @return int 0 - not exist / 1 - exists and not changed / -2 - changed */ protected function checkScenarioAttribute($scenario, $userLogin, $userName, $attribute, $operator, $value) { $result = 0; if (isset($this->currentAttributes[$scenario])) { if (isset($this->currentAttributes[$scenario][$userName])) { if (isset($this->currentAttributes[$scenario][$userName][$attribute])) { if ($this->currentAttributes[$scenario][$userName][$attribute]['value'] == $value) { if ($this->currentAttributes[$scenario][$userName][$attribute]['op'] == $operator) { $result = 1; } else { $result = -2; } } else { $result = -2; } } else { $result = 0; } } else { $result = 0; } } else { $result = 0; } $this->logEvent($userLogin . ' AS ' . $userName . ' SCENARIO ' . $scenario . ' TEST ' . $attribute . ' ' . $operator . ' ' . $value . ' RESULT ' . $result, 2); return ($result); } /** * Pushes some scenario attribute to database * * @param string $scenario * @param string $userLogin * @param string $userName * @param string $attribute * @param string $op * @param string $value * * @return void */ protected function createScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value) { $query = "INSERT INTO `" . self::SCENARIO_PREFIX . $scenario . "` (`id`,`username`,`attribute`,`op`,`value`) VALUES " . "(NULL,'" . $userName . "','" . $attribute . "','" . $op . "','" . $value . "');"; nr_query($query); $this->logEvent($userLogin . ' AS ' . $userName . ' SCENARIO ' . $scenario . ' CREATE ' . $attribute . ' ' . $op . ' ' . $value, 1); } /** * Drops some reply attribute from database (required on value changes) * * @param string $scenario * @param string $userLogin * @param string $userName * @param string $attribute * * @return void */ protected function deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute) { $query = "DELETE FROM `" . self::SCENARIO_PREFIX . $scenario . "` WHERE `username`='" . $userName . "' AND `attribute`='" . $attribute . "';"; nr_query($query); $this->logEvent($userLogin . ' AS ' . $userName . ' SCENARIO ' . $scenario . ' DELETE ' . $attribute, 1); } /** * Writes attributes regeneration stats * * @param int $nasId * @param string $scenario * @param string $attributeState * * @return void */ protected function writeScenarioStats($nasId, $scenario, $attributeState) { if ((!isset($this->scenarioStats[$nasId])) OR (!isset($this->scenarioStats[$nasId][$scenario])) OR (!isset($this->scenarioStats[$nasId][$scenario][$attributeState]))) { $this->scenarioStats[$nasId][$scenario][$attributeState] = 1; } else { $this->scenarioStats[$nasId][$scenario][$attributeState]++; } } /** * Stores performance timing data for future stats * * @return void */ public function writePerformanceTimers($key) { if (isset($this->perfStats[$key])) { $this->perfStats[$key] = microtime(true) - $this->perfStats[$key]; } else { $this->perfStats[$key] = microtime(true); } } /** * Flushes buried user attributes if they are exists in database * * @param int $nasId * @param string $scenario * @param string $userLogin * @param string $userName * @param string $attribute * * @return void */ protected function flushBuriedUser($nasId, $scenario, $userLogin, $userName, $attribute) { if (isset($this->currentAttributes[$scenario])) { if (isset($this->currentAttributes[$scenario][$userName])) { if (isset($this->currentAttributes[$scenario][$userName][$attribute])) { $this->deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute); $this->writeScenarioStats($nasId, $scenario, 'buried'); } } } } /** * Returns user state as string * * @param string $userLogin * * @return string */ protected function getUserStateString($userLogin) { $result = ''; if (isset($this->allUserData[$userLogin])) { if (($this->allUserData[$userLogin]['Cash'] >= '-' . $this->allUserData[$userLogin]['Credit']) AND ( $this->allUserData[$userLogin]['AlwaysOnline'] == 1)) { $result = 'ON-LINE'; } else { $result = 'OFF-LINE'; } if ($this->allUserData[$userLogin]['Down']) { $result = 'DOWN'; } if ($this->allUserData[$userLogin]['Passive']) { $result = 'PASSIVE'; } } else { $result = 'NOT-EXIST'; } return ($result); } /** * Parses network data to network address and network CIDR * * @param string $netDesc * * @return array */ protected function parseNetworkDesc($netDesc) { $result = array(); $netDesc = explode('/', $netDesc); $result = array('addr' => $netDesc[0], 'cidr' => $netDesc[1]); return ($result); } /** * Transforms mac from xx:xx:xx:xx:xx:xx format to xxxx.xxxx.xxxx * * @param string $mac * * @return string */ protected function transformMacDotted($mac) { $result = implode(".", str_split(str_replace(":", "", $mac), 4)); return ($result); } /** * Transforms mac from xx:xx:xx:xx:xx:xx format to XX-XX-XX-XX-XX-XX * * @param string $mac * @param bool $caps * * @return string */ protected function transformMacMinused($mac, $caps = false) { $result = str_replace(':', '-', $mac); if ($caps) { $result = strtoupper($result); } return ($result); } /** * Transforms CIDR notation to xxx.xxx.xxx.xxx netmask * * @param string $cidr - CIDR * * @return string */ protected function transformCidrtoMask($cidr) { $result = long2ip(-1 << (32 - (int) $cidr)); return ($result); } /** * Returns current user speeds including personal override in Kbit/s * * @param string $userLogin * * @return array as speeddown/speedup=>values */ protected function getUserSpeeds($userLogin) { $result = array('speeddown' => 0, 'speedup' => 0); if (isset($this->allUserData[$userLogin])) { $userTariff = $this->allUserData[$userLogin]['Tariff']; if (isset($this->tariffSpeeds[$userTariff])) { //basic tariff speed $result = array('speeddown' => $this->tariffSpeeds[$userTariff]['speeddown'], 'speedup' => $this->tariffSpeeds[$userTariff]['speedup']); } if (isset($this->userSpeedOverrides[$userLogin])) { //personal speed overrides $result = array('speeddown' => $this->userSpeedOverrides[$userLogin], 'speedup' => $this->userSpeedOverrides[$userLogin]); } } return ($result); } /** * Returns speed transformed from kbit/s to bit/s by some offset * * @param int $speed * @param int $offset * * @return int */ protected function transformSpeedBits($speed, $offset = 1024) { $result = $speed * $offset; return ($result); } /** * Returns attribute templates value with replaced macro * * @param string $userLogin * @param string $userName * @param int $nasId * @param string $template * * @return string */ public function getAttributeValue($userLogin, $userName, $nasId, $template) { if (strpos($template, '{') !== false) { //skipping templates with no macro inside if (isset($this->allUserData[$userLogin])) { if (strpos($template, '{IP}') !== false) { $template = str_replace('{IP}', $this->allUserData[$userLogin]['ip'], $template); } if (strpos($template, '{MAC}') !== false) { $template = str_replace('{MAC}', $this->allUserData[$userLogin]['mac'], $template); } if (strpos($template, '{MACFDL}') !== false) { $template = str_replace('{MACFDL}', $this->transformMacDotted($this->allUserData[$userLogin]['mac']), $template); } if (strpos($template, '{MACFML}') !== false) { $template = str_replace('{MACFML}', str_replace('.', '-', $this->transformMacDotted($this->allUserData[$userLogin]['mac'])), $template); } if (strpos($template, '{MACTMU}') !== false) { $template = str_replace('{MACTMU}', $this->transformMacMinused($this->allUserData[$userLogin]['mac'], true), $template); } if (strpos($template, '{MACTML}') !== false) { $template = str_replace('{MACTML}', $this->transformMacMinused($this->allUserData[$userLogin]['mac'], false), $template); } if (strpos($template, '{LOGIN}') !== false) { $template = str_replace('{LOGIN}', $userLogin, $template); } if (strpos($template, '{USERNAME}') !== false) { $template = str_replace('{USERNAME}', $userName, $template); } if (strpos($template, '{PASSWORD}') !== false) { $template = str_replace('{PASSWORD}', $this->allUserData[$userLogin]['Password'], $template); } if (strpos($template, '{TARIFF}') !== false) { $template = str_replace('{TARIFF}', $this->allUserData[$userLogin]['Tariff'], $template); } if (strpos($template, '{NETID}') !== false) { $template = str_replace('{NETID}', $this->nethostsNetworks[$this->allUserData[$userLogin]['ip']], $template); } if (strpos($template, '{NETADDR}') !== false) { $netDesc = $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['desc']; $netDesc = $this->parseNetworkDesc($netDesc); $netAddr = $netDesc['addr']; $template = str_replace('{NETADDR}', $netAddr, $template); } if (strpos($template, '{NETCIDR}') !== false) { $netDesc = $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['desc']; $netDesc = $this->parseNetworkDesc($netDesc); $netCidr = $netDesc['cidr']; $template = str_replace('{NETCIDR}', $netCidr, $template); } if (strpos($template, '{NETSTART}') !== false) { $template = str_replace('{NETSTART}', $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['startip'], $template); } if (strpos($template, '{NETEND}') !== false) { $template = str_replace('{NETEND}', $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['endip'], $template); } if (strpos($template, '{NETDESC}') !== false) { $template = str_replace('{NETDESC}', $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['desc'], $template); } if (strpos($template, '{NETMASK}') !== false) { $netDesc = $this->allNetworks[$this->nethostsNetworks[$this->allUserData[$userLogin]['ip']]]['desc']; $netDesc = $this->parseNetworkDesc($netDesc); $netCidr = $netDesc['cidr']; $netMask = $this->transformCidrtoMask($netCidr); $template = str_replace('{NETMASK}', $netMask, $template); } if (strpos($template, '{SPEEDDOWN}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedDown = $userSpeeds['speeddown']; $template = str_replace('{SPEEDDOWN}', $speedDown, $template); } if (strpos($template, '{SPEEDUP}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedUp = $userSpeeds['speedup']; $template = str_replace('{SPEEDUP}', $speedUp, $template); } if (strpos($template, '{SPEEDDOWNB}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedDown = $this->transformSpeedBits($userSpeeds['speeddown'], 1024); $template = str_replace('{SPEEDDOWNB}', $speedDown, $template); } if (strpos($template, '{SPEEDUPB}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedUp = $this->transformSpeedBits($userSpeeds['speedup'], 1024); $template = str_replace('{SPEEDUPB}', $speedUp, $template); } if (strpos($template, '{SPEEDDOWNBD}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedDown = $this->transformSpeedBits($userSpeeds['speeddown'], 1000); $template = str_replace('{SPEEDDOWNBD}', $speedDown, $template); } if (strpos($template, '{SPEEDUPBD}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedUp = $this->transformSpeedBits($userSpeeds['speedup'], 1000); $template = str_replace('{SPEEDUPBD}', $speedUp, $template); } if (strpos($template, '{SPEEDDOWNBC}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedDown = $this->transformSpeedBits($userSpeeds['speeddown'], 1024) / 8; $template = str_replace('{SPEEDDOWNBC}', $speedDown, $template); } if (strpos($template, '{SPEEDUPBC}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $speedUp = $this->transformSpeedBits($userSpeeds['speedup'], 1024) / 8; $template = str_replace('{SPEEDUPBC}', $speedUp, $template); } if (strpos($template, '{SPEEDMRL}') !== false) { $userSpeeds = $this->getUserSpeeds($userLogin); $template = str_replace('{SPEEDMRL}', $userSpeeds['speedup'] . 'k/' . $userSpeeds['speeddown'] . 'k', $template); } if (strpos($template, '{USERSWITCHIP}') !== false) { $userSwitchId = @$this->userSwitchAssigns[$userLogin]['switchid']; $switchData = @$this->allSwitches[$userSwitchId]; $switchIp = @$switchData['ip']; $template = str_replace('{USERSWITCHIP}', $switchIp, $template); } if (strpos($template, '{USERSWITCHPORT}') !== false) { $userSwitchPort = @$this->userSwitchAssigns[$userLogin]['port']; $template = str_replace('{USERSWITCHPORT}', $userSwitchPort, $template); } if (strpos($template, '{USERSWITCHMAC}') !== false) { $userSwitchId = @$this->userSwitchAssigns[$userLogin]['switchid']; $switchData = @$this->allSwitches[$userSwitchId]; $switchMac = @$switchData['swid']; $template = str_replace('{USERSWITCHMAC}', $switchMac, $template); } if (strpos($template, '{NETEXT}') !== false) { if (isset($this->netExtUsers[$userLogin])) { $netExtData = $this->netExtUsers[$userLogin]; $template = str_replace('{NETEXT}', $netExtData, $template); } } } if (isset($this->allNas[$nasId])) { $nasIp = $this->allNas[$nasId]['nasip']; if (strpos($template, '{NASIP}') !== false) { $template = str_replace('{NASIP}', $nasIp, $template); } if (strpos($template, '{NASSECRET}') !== false) { $nasSecret = substr(md5(ip2int($nasIp)), 0, 12); $template = str_replace('{NASSECRET}', $nasSecret, $template); } if (strpos($template, '{NASPORT}') !== false) { $nasPort = $this->nasOptions[$nasId]['port']; $template = str_replace('{NASPORT}', $nasPort, $template); } } if (strpos($template, '{STATE}') !== false) { $template = str_replace('{STATE}', $this->getUserStateString($userLogin), $template); } if (strpos($template, '{RADCLIENT}') !== false) { $template = str_replace('{RADCLIENT}', $this->radclienPath, $template); } if (strpos($template, '{SUDO}') !== false) { $template = str_replace('{SUDO}', $this->sudoPath, $template); } if (strpos($template, '{PRINTF}') !== false) { $template = str_replace('{PRINTF}', $this->printfPath, $template); } } return ($template); } /** * Returns array of all possible radius-preprocessed usernames * * @return array */ public function getAllUserNames() { $result = array(); if (empty($this->allUserData)) { $this->loadUserData(); if ((isset($this->altCfg[self::OPTION_SWASSIGN])) AND ( isset($this->altCfg[self::OPTION_QINQ]))) { if (($this->altCfg[self::OPTION_SWASSIGN]) AND ( $this->altCfg[self::OPTION_QINQ])) { $this->loadSwitches(); $this->loadSwithchAssigns(); $this->loadAllQinQ(); } } else { if (isset($this->altCfg[self::OPTION_UNIVERSALQINQ])) { if ($this->altCfg[self::OPTION_UNIVERSALQINQ]) { $this->loadAllQinQ(); } } } //preloading culpa instance if ($this->meaCulpaFlag) { $this->loadMeaCulpa(); } } if (!empty($this->allUserData)) { foreach ($this->allUserData as $eachUserLogin => $eachUserData) { foreach ($this->usernameTypes as $eachUsernameType => $usernameTypeName) { $userName = $this->getLoginUsername($eachUserLogin, $eachUserData, $eachUsernameType); $result[$eachUserLogin][] = (string) $userName; } } } return($result); } /** * Returns transformed username by some type * * @param string $userLogin * @param array $userdata * @param string $usernameType * * @return string */ protected function getLoginUsername($userLogin, $userData, $userNameType) { $result = ''; switch ($userNameType) { case 'login': $result = $userLogin; break; case 'ip': $result = @$userData['ip']; break; case 'mac': $result = @$userData['mac']; break; case 'macup': $result = @strtoupper($userData['mac']); break; case 'macju': $result = @$this->transformMacDotted($userData['mac']); break; case 'qinq': $result = $this->getQinQUsername($userLogin, '.'); break; case 'qinqju': $result = $this->getQinQUsername($userLogin, '-'); break; case 'meaculpa': $result = $this->meaCulpa->get($userLogin); break; } return ($result); } /** * Returns default switch based QinQ username * * @param string $userLogin * @param string $delimiter * * @return string/void */ protected function getQinQUsername($userLogin, $delimiter = '.') { $result = ''; if (isset($this->usersQinQ[$userLogin])) { $qinqData = $this->usersQinQ[$userLogin]; if ($this->allSvlan[$qinqData['svlan_id']]['svlan'] === '0') { $result .= $qinqData['cvlan']; } else { $result .= $this->allSvlan[$qinqData['svlan_id']]['svlan'] . $delimiter . $qinqData['cvlan']; } } elseif (isset($this->userSwitchAssigns[$userLogin])) { $assignData = $this->userSwitchAssigns[$userLogin]; $assignedSwitchId = $assignData['switchid']; $assignedPort = $assignData['port']; if (isset($this->switchesQinQ[$assignedSwitchId])) { $qinqData = $this->switchesQinQ[$assignedSwitchId]; if (!empty($assignedPort)) { if ($this->allSvlan[$qinqData['svlan_id']]['svlan'] === '0') { $result .= ($qinqData['cvlan'] + ($assignedPort - 1)); } else { $result .= $this->allSvlan[$qinqData['svlan_id']]['svlan'] . $delimiter . ($qinqData['cvlan'] + ($assignedPort - 1)); } } } } if (!empty($result)) { if (isset($this->allSvlan[$qinqData['svlan_id']])) { $realmId = $this->allSvlan[$qinqData['svlan_id']]['realm_id']; if ($realmId != 1) { $result .= '@' . $this->allRealms[$realmId]['realm']; } } } return($result); } /** * Returns user login if some username for him found * * @param string $userName * @param array $allUserNames * * @return string */ public function getUserLogin($userName, $allUserNames) { $result = ''; if (!empty($allUserNames)) { $userName = (string) $userName; foreach ($allUserNames as $login => $each) { if (array_search($userName, $each, true) !== false) { $result = $login; break; } } } return($result); } /** * Need to disconnect user when data like username changed. * * @param string $userLogin * @param array $userData * * @return void */ public function podOnExternalEvent($userLogin, $userData, $newUserData = array()) { $this->loadHugeRegenData(); if (!empty($this->allUserData)) { $this->preprocessUserData(); if (isset($this->userNases[$userLogin])) { $userNases = $this->userNases[$userLogin]; if (!empty($userNases)) { foreach ($userNases as $eachNasId) { @$nasOptions = $this->nasOptions[$eachNasId]; @$userNameType = $nasOptions['usernametype']; if ($userNameType != 'login') { $userName = $this->getLoginUsername($userLogin, $userData, $userNameType); if (!empty($userName)) { if (!empty($nasOptions)) { if ($nasOptions['service'] != 'none') { $nasServices = @$this->services[$eachNasId]; if (!empty($nasServices)) { $this->allUserData[$userLogin]['ip'] = $userData['ip']; $this->allUserData[$userLogin]['mac'] = $userData['mac']; if (strpos($nasOptions['service'], 'pod') !== false) { $podCommand = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['pod']) . "\n"; $this->savePodQueue($podCommand); if (!empty($newUserData)) { $newUserName = $this->getLoginUsername($userLogin, $newUserData, $userNameType); $this->replaceSingleUser($newUserName, $userName); $this->changeFramedIp($newUserData['ip'], $userData['ip'], $newUserName); } //adding else to avoid user double kill when use pod + coa services } else { if (strpos($nasOptions['service'], 'coa') !== false) { $podCommand = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['pod']) . "\n"; $this->saveCoaQueue($podCommand); if (!empty($newUserData)) { $newUserName = $this->getLoginUsername($userLogin, $newUserData, $userNameType); $this->replaceSingleUser($newUserName, $userName); $this->changeFramedIp($newUserData['ip'], $userData['ip'], $newUserName); } } } } } } } } } } } //run PoD queue if (isset($this->runServices['pod'])) { $this->runPodQueue(); } //run CoA queue if (isset($this->runServices['coa'])) { $this->runCoaQueue(); } } } /** * Replaces old username in mlg_* tables * * @param string $newUserName * @param striing $oldUserName * * @return void */ protected function replaceSingleUser($newUserName, $oldUserName) { if (!empty($newUserName) and !empty($oldUserName)) { foreach ($this->scenarios as $eachScenario) { $query = 'UPDATE `' . self::SCENARIO_PREFIX . $eachScenario . '` SET `username`="' . $newUserName . '" WHERE `username`="' . $oldUserName . '"'; nr_query($query); } } } /** * Replaces old Framed-IP-Address in mlg_reply table * * @param string $newIp * @param string $oldIp * @param string $userName * * @return void */ protected function changeFramedIp($newIp, $oldIp, $userName) { if (!empty($newIp) and !empty($oldIp)) { $query = 'UPDATE `' . self::SCENARIO_PREFIX . 'reply' . '` SET `Value`="' . $newIp . '" WHERE `attribute`="Framed-IP-Address" AND `value`="' . $oldIp . '" AND `username`="' . $userName . '"'; nr_query($query); } } /** * Performs generation of user attributes if their NAS requires it. * * @return void */ public function generateNasAttributes() { $this->writePerformanceTimers('genstart'); //loading huge amount of required data $this->loadHugeRegenData(); $this->writePerformanceTimers('dataloaded'); if (!empty($this->allUserData)) { //starting regeneration transaction if required if ($this->inno) { nr_query("START TRANSACTION;"); } foreach ($this->allUserData as $io => $eachUser) { $userLogin = $eachUser['login']; //user actual state right now $userRealState = $this->isUserActive($userLogin); //getting previous user state, setting current state if (isset($this->userStates[$userLogin])) { $userPreviousState = $this->userStates[$userLogin]['previous']; $this->userStates[$userLogin]['current'] = ($userRealState) ? 1 : 0; } else { $userPreviousState = 3; $this->userStates[$userLogin]['previous'] = $userPreviousState; $this->userStates[$userLogin]['current'] = ($userRealState) ? 1 : 0; $this->userStates[$userLogin]['changed'] = 3; } if (isset($this->userNases[$userLogin])) { $userNases = $this->userNases[$userLogin]; if (!empty($userNases)) { foreach ($userNases as $eachNasId) { @$nasOptions = $this->nasOptions[$eachNasId]; @$userNameType = $nasOptions['usernametype']; //overriding username type if required $userName = $this->getLoginUsername($userLogin, $eachUser, $userNameType); //yeah, this is possible in some unusual cases with QinQ or something like that if (!empty($userName)) { if (!empty($nasOptions)) { $nasAttributes = $this->getNasAttributes($eachNasId); $onlyActive = $nasOptions['onlyactive']; //Processing NAS attributes only for active users if ($onlyActive == 1) { if (!empty($nasAttributes)) { foreach ($nasAttributes as $eachAttributeId => $eachAttributeData) { $scenario = $eachAttributeData['scenario']; $attribute = $eachAttributeData['attribute']; $op = $eachAttributeData['operator']; $template = $eachAttributeData['content']; if ($userRealState) { $value = $this->getAttributeValue($userLogin, $userName, $eachNasId, $template); $attributeCheck = $this->checkScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); if ($attributeCheck == -2) { //dropping already changed attribute from this scenario $this->deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute); //setting current user state as changed $this->userStates[$userLogin]['changed'] = -2; } if (($attributeCheck == 0) OR ( $attributeCheck == -2)) { //creating new attribute with actual data $this->createScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); $this->writeScenarioStats($eachNasId, $scenario, 'generated'); } if ($attributeCheck == 1) { //attribute exists and not changed $this->writeScenarioStats($eachNasId, $scenario, 'skipped'); } } else { //flush some not-active user attributes if required $this->flushBuriedUser($eachNasId, $scenario, $userLogin, $userName, $attribute); } } } } //Processing NAS attributes for all users using attributes modifiers if ($onlyActive == 0) { if (!empty($nasAttributes)) { foreach ($nasAttributes as $eachAttributeId => $eachAttributeData) { $scenario = $eachAttributeData['scenario']; $modifier = $eachAttributeData['modifier']; $attribute = $eachAttributeData['attribute']; $op = $eachAttributeData['operator']; $template = $eachAttributeData['content']; //this attribute template is actual for all users if ($modifier == 'all') { $value = $this->getAttributeValue($userLogin, $userName, $eachNasId, $template); $attributeCheck = $this->checkScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); if ($attributeCheck == -2) { //dropping already changed attribute from this scenario $this->deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute); //setting current user state as changed $this->userStates[$userLogin]['changed'] = -2; } if (($attributeCheck == 0) OR ( $attributeCheck == -2)) { //creating new attribute with actual data $this->createScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); $this->writeScenarioStats($eachNasId, $scenario, 'generated'); } if ($attributeCheck == 1) { //attribute exists and not changed $this->writeScenarioStats($eachNasId, $scenario, 'skipped'); } } //this attribute is actual only for active users if ($modifier == 'active') { if ($userRealState) { $value = $this->getAttributeValue($userLogin, $userName, $eachNasId, $template); $attributeCheck = $this->checkScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); if ($attributeCheck == -2) { //dropping already changed attribute from this scenario $this->deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute); //setting current user state as changed $this->userStates[$userLogin]['changed'] = -2; } if (($attributeCheck == 0) OR ( $attributeCheck == -2)) { //creating new attribute with actual data $this->createScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); $this->writeScenarioStats($eachNasId, $scenario, 'generated'); } if ($attributeCheck == 1) { //attribute exists and not changed $this->writeScenarioStats($eachNasId, $scenario, 'skipped'); } } else { //flush some not-active user attribute if required $this->flushBuriedUser($eachNasId, $scenario, $userLogin, $userName, $attribute); } } //this attribute is actual only for inactive users if ($modifier == 'inactive') { if (!$userRealState) { $value = $this->getAttributeValue($userLogin, $userName, $eachNasId, $template); $attributeCheck = $this->checkScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); if ($attributeCheck == -2) { //dropping already changed attribute from this scenario $this->deleteScenarioAttribute($scenario, $userLogin, $userName, $attribute); //setting current user state as changed $this->userStates[$userLogin]['changed'] = -2; } if (($attributeCheck == 0) OR ( $attributeCheck == -2)) { //creating new attribute with actual data $this->createScenarioAttribute($scenario, $userLogin, $userName, $attribute, $op, $value); $this->writeScenarioStats($eachNasId, $scenario, 'generated'); } if ($attributeCheck == 1) { //attribute exists and not changed $this->writeScenarioStats($eachNasId, $scenario, 'skipped'); } } else { //flush some active user attribute if required $this->flushBuriedUser($eachNasId, $scenario, $userLogin, $userName, $attribute); } } } } } //processing Per-NAS services if ($nasOptions['service'] != 'none') { $nasServices = @$this->services[$eachNasId]; if (!empty($nasServices)) { if (strpos($nasOptions['service'], 'pod') !== false) { if (!empty($nasServices['pod'])) { if (($userPreviousState == 1) AND ( $this->userStates[$userLogin]['current'] == 0)) { $newPodContent = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['pod']) . "\n"; $this->savePodQueue($newPodContent); } } } if (strpos($nasOptions['service'], 'coa') !== false) { //sending some disconnect if (!empty($nasServices['coadisconnect'])) { if (($userPreviousState == 1) AND ( $this->userStates[$userLogin]['current'] == 0)) { //user out of money $newCoADisconnectContent = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['coadisconnect']) . "\n"; $this->saveCoaQueue($newCoADisconnectContent); } } //and connect services if (!empty($nasServices['coaconnect'])) { if (($userPreviousState == 0) AND ( $this->userStates[$userLogin]['current'] == 1)) { //user now restores his activity $newCoAConnectContent = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['coaconnect']) . "\n"; $this->saveCoaQueue($newCoAConnectContent); } } //emulating reset action if something changed in user attributes if ((!empty($nasServices['coadisconnect'])) AND (!empty($nasServices['coaconnect']))) { if (($this->userStates[$userLogin]['changed'] == -2) AND ( $this->userStates[$userLogin]['current'] == 1) AND ( $this->userStates[$userLogin]['previous'] == 1)) { $newCoADisconnectContent = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['coadisconnect']) . "\n"; $this->saveCoaQueue($newCoADisconnectContent); $newCoAConnectContent = $this->getAttributeValue($userLogin, $userName, $eachNasId, $nasServices['coaconnect']) . "\n"; $this->saveCoaQueue($newCoAConnectContent); } } } } } } } } } } } //run PoD queue if (isset($this->runServices['pod'])) { $this->runPodQueue(); } //run CoA queue if (isset($this->runServices['coa'])) { $this->runCoaQueue(); } //saving user states $this->saveUserStates(); //commiting changes to database if required if ($this->inno) { nr_query("COMMIT;"); } } $this->writePerformanceTimers('genend'); } /** * Saves data to PoD queue for furtner run * * @param string $data * * @return void */ protected function savePodQueue($data) { $this->runServices['pod'] = 1; file_put_contents(self::POD_PATH . $this->instanceId, $data, FILE_APPEND); $this->logEvent('POD_QUEUE_ADD ' . $this->instanceId . ': ' . trim($data), 3); //Omae wa mou shindeiru } /** * Saves data to CoA queue for furtner run * * @param string $data * * @return void */ protected function saveCoaQueue($data) { $this->runServices['coa'] = 1; file_put_contents(self::COA_PATH . $this->instanceId, $data, FILE_APPEND); $this->logEvent('COA_QUEUE_ADD ' . $this->instanceId . ': ' . trim($data), 3); } /** * Runs PoD queue if not empty and flushes after it * * @return void */ protected function runPodQueue() { if (file_exists(self::POD_PATH . $this->instanceId)) { chmod(self::POD_PATH . $this->instanceId, 0755); $podQueueCleanup = $this->echoPath . ' "" > ' . getcwd() . '/' . self::POD_PATH . $this->instanceId . "\n"; $this->savePodQueue($podQueueCleanup); if ($this->logging >= 4) { shell_exec(self::POD_PATH . $this->instanceId . ' >>' . self::LOG_PATH . ' 2>> ' . self::LOG_PATH); } else { shell_exec(self::POD_PATH . $this->instanceId . ' >/dev/null 2>/dev/null &'); } $this->logEvent('POD_QUEUE_RUN: ' . $this->instanceId, 3); //nani? } } /** * Runs CoA queue if not empty and flushes after it * * @return void */ protected function runCoaQueue() { if (file_exists(self::COA_PATH . $this->instanceId)) { chmod(self::COA_PATH . $this->instanceId, 0755); $coaQueueCleanup = $this->echoPath . ' "" > ' . getcwd() . '/' . self::COA_PATH . $this->instanceId . "\n"; $this->saveCoaQueue($coaQueueCleanup); if ($this->logging >= 4) { shell_exec(self::COA_PATH . $this->instanceId . ' >>' . self::LOG_PATH . ' 2>> ' . self::LOG_PATH); } else { shell_exec(self::COA_PATH . $this->instanceId . ' >/dev/null 2>/dev/null &'); } $this->logEvent('COA_QUEUE_RUN: ' . $this->instanceId, 3); } } /** * Returns NAS label as IP - name * * @param int $nasId * * @return string */ public function getNaslabel($nasId) { $result = ''; if (isset($this->allNas[$nasId])) { $result .= $this->allNas[$nasId]['nasip'] . ' - ' . $this->allNas[$nasId]['nasname']; } return ($result); } /** * Renders some NAS attributes regeneration stats * * @return strings */ public function renderScenarioStats() { $result = ''; $totalAttributeCount = 0; if (!empty($this->scenarioStats)) { foreach ($this->scenarioStats as $nasId => $scenario) { $nasLabel = $this->getNaslabel($nasId); $result .= $this->messages->getStyledMessage($nasLabel, 'success'); if (!empty($scenario)) { foreach ($scenario as $scenarioName => $counters) { if (!empty($counters)) { foreach ($counters as $eachState => $eachCount) { switch ($eachState) { case 'skipped': $stateName = __('Attributes is unchanged and generation was skipped'); $stateStyle = 'info'; break; case 'generated': $stateName = __('New or changed attributes generated'); $stateStyle = 'warning'; break; case 'buried': $stateName = __('Attributes was flushed due user inactivity'); $stateStyle = 'warning'; break; default : $stateName = $eachState; $stateStyle = 'info'; break; } $totalAttributeCount += $eachCount; $result .= $this->messages->getStyledMessage($stateName . ' ' . __('for scenario') . ' ' . $scenarioName . ': ' . $eachCount, $stateStyle); } } } } } } if (!empty($this->perfStats)) { $timeStats = ''; $perfStats = ''; $dataLoadingTime = $this->perfStats['dataloaded'] - $this->perfStats['genstart']; $totalTime = $this->perfStats['genend'] - $this->perfStats['genstart']; $timeStats .= __('Total time spent') . ': ' . round($totalTime, 2) . ' ' . __('sec.') . ' '; $timeStats .= __('Data loading time') . ': ' . round($dataLoadingTime, 2) . ' ' . __('sec.') . ' '; $timeStats .= __('Attributes processing time') . ': ' . round(($totalTime - $dataLoadingTime), 2) . ' ' . __('sec.') . ' '; $timeStats .= __('Memory used') . ': ~' . stg_convert_size(memory_get_usage(true)); $perfStats .= __('Total attributes processed') . ': ' . $totalAttributeCount . ' '; if ($totalTime > 0) { //preventing zero divisions $perfStats .= __('Performance') . ': ' . round($totalAttributeCount / ($totalTime - $dataLoadingTime), 2) . ' ' . __('attributes/sec'); $perfStats .= ' ( ' . round($totalAttributeCount / ($totalTime), 2) . ' ' . ' ' . __('brutto') . ')'; } else { $perfStats .= __('Performance') . ': ' . wf_tag('b') . __('Black magic') . wf_tag('b', true); } $result .= $this->messages->getStyledMessage($timeStats, 'success'); $result .= $this->messages->getStyledMessage($perfStats, 'success'); } return ($result); } /** * Renders NAS controls panel * * @param int $nasId * * @return string */ public function nasControlPanel($nasId) { $result = ''; $result .= wf_BackLink('?module=nas') . ' '; $result .= wf_modal(wf_img('skins/icon_clone.png') . ' ' . __('Clone NAS configuration'), __('Clone NAS configuration'), $this->renderNasCloneForm($nasId), 'ubButton', '750', '390'); if ($this->nasHaveOptions($nasId)) { $result .= wf_AjaxLoader(); $result .= wf_AjaxLink(self::URL_ME . '&ajnasregen=true&editnasoptions=' . $nasId, wf_img('skins/refresh.gif') . ' ' . __('Base regeneration'), 'nascontrolajaxcontainer', false, 'ubButton'); $result .= wf_AjaxLink(self::URL_ME . '&ajscenarioflush=true&editnasoptions=' . $nasId, wf_img('skins/skull.png') . ' ' . __('Flush all attributes in all scenarios'), 'nascontrolajaxcontainer', false, 'ubButton'); if ($this->nasOptions[$nasId]['service'] != 'none') { $result .= wf_modalAuto(web_icon_extended() . ' ' . __('Service'), __('Service'), $this->renderNasServicesEditForm($nasId), 'ubButton'); } $result .= wf_AjaxContainer('nascontrolajaxcontainer'); } return ($result); } /** * Returns NAS services editing form * * @param int $nasId * * @return string */ protected function renderNasServicesEditForm($nasId) { $result = ''; $nasId = vf($nasId, 3); if ($this->nasHaveOptions($nasId)) { $nasOptions = $this->nasOptions[$nasId]; if ($nasOptions['service'] != 'none') { $nasServices = @$this->services[$nasId]; $inputs = wf_HiddenInput('newnasservicesid', $nasId); $inputs .= __('PoD') . wf_tag('br'); $inputs .= wf_TextArea('newnasservicepod', '', @$nasServices['pod'], true, '90x2'); $inputs .= __('CoA Connect') . wf_tag('br'); $inputs .= wf_TextArea('newnasservicecoaconnect', '', @$nasServices['coaconnect'], true, '90x2'); $inputs .= __('CoA Disconnect') . wf_tag('br'); $inputs .= wf_TextArea('newnasservicecoadisconnect', '', @$nasServices['coadisconnect'], true, '90x2'); $inputs .= wf_Submit(__('Save')); $result .= wf_Form(self::URL_ME . '&editnasoptions=' . $nasId, 'POST', $inputs, 'glamour'); } } return ($result); } /** * Returns some NAS text-based configuration info for copy/paste settings * * @param int $nasId * * @return array/string if empty */ protected function getNasCopyString($nasId) { $result = array(); if (isset($this->nasOptions[$nasId])) { $result['options'] = $this->nasOptions[$nasId]; $result['attributes'] = $this->getNasAttributes($nasId); $result['services'] = $this->getNasServices($nasId); $result = json_encode($result); $result = base64_encode($result); } else { $result = ''; } return ($result); } /** * Renders NAS copy&paste settings form * * @param int $nasId * * @return string */ protected function renderNasCopyPasteForm($nasId) { $result = ''; $inputs = __('You can copy&paste current NAS configuration as text'); $inputs .= wf_tag('br'); $inputs .= wf_TextInput('nascopypastetext', __('Settings'), $this->getNasCopyString($nasId), true, 55); $inputs .= wf_CheckInput('nascopypasteagree', __('I understand that changing that completely destroys all current NAS settings if they exist and will replace them with the another configuration'), true, false); $inputs .= wf_delimiter(); $inputs .= wf_Submit(__('Save')); $result .= wf_Form('', 'POST', $inputs, 'glamour'); return ($result); } /** * Renders nas options/atributes/services cloning form * * @param int $nasId * * @return string * */ protected function renderNasCloneForm($nasId) { $result = ''; $nasId = vf($nasId, 3); $nasParamsTmp = array(); $otherNasCount = 0; if (isset($this->allNas[$nasId])) { /** * Get the fuck off * Mother fucker * Back the fuck off * Fucking hustler * What the fuck? What the fuck? * I don't wanna * I don't need ya * Watch out the fire * Of the Saiya */ if ((!empty($this->nasOptions)) AND (!empty($this->allNas))) { foreach ($this->nasOptions as $io => $each) { if (($io != $nasId) AND ( isset($this->allNas[$io]))) { $nasBasicData = $this->allNas[$io]; $nasExtendedOptions = $each; $nasUsernameType = @$this->usernameTypes[$nasExtendedOptions['usernametype']]; $nasService = $this->serviceTypes[$nasExtendedOptions['service']]; $attributeTemplates = $this->getNasAttributes($io); $attributeTemplatesCount = sizeof($attributeTemplates); $nasLabel = $nasBasicData['nasip'] . ' - ' . $nasBasicData['nasname'] . ' (' . $nasUsernameType . ' / ' . $nasService . ' / ' . $attributeTemplatesCount . ' ' . __('NAS attributes') . ')'; $nasParamsTmp[$nasBasicData['id']] = $nasLabel; $otherNasCount++; } } if (!empty($nasParamsTmp)) { $inputs = wf_Selector('clonenasfromid', $nasParamsTmp, __('Clone') . ' ' . __('NAS'), '', true); $inputs .= wf_HiddenInput('clonenastoid', $nasId); $inputs .= wf_CheckInput('clonenasagree', __('I understand that cloning completely destroys all current NAS settings if they exist and will replace them with the configuration of another NAS'), true, false); $inputs .= wf_delimiter(); $inputs .= wf_Submit(__('Clone')); $result .= wf_Form('', 'POST', $inputs, 'glamour'); } } } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('NAS not exists'), 'error'); } if ($otherNasCount < 1) { $result .= $this->messages->getStyledMessage(__('No other configured NAS to cloning'), 'warning'); } //copy&paste form $result .= wf_tag('br'); $result .= $this->renderNasCopyPasteForm($nasId); return ($result); } /** * Flushes all NAS configuration from database * * @param int $nasId * * @return void */ public function deleteAllNasConfiguration($nasId) { $nasId = vf($nasId, 3); $query = "DELETE FROM `" . self::NAS_OPTIONS . "` WHERE `nasid`='" . $nasId . "';"; nr_query($query); log_register('MULTIGEN NAS [' . $nasId . '] FLUSH OPTIONS'); $query = "DELETE FROM `" . self::NAS_ATTRIBUTES . "` WHERE `nasid`='" . $nasId . "';"; nr_query($query); log_register('MULTIGEN NAS [' . $nasId . '] FLUSH ATTRIBUTES'); $query = "DELETE FROM `" . self::NAS_SERVICES . "` WHERE `nasid`='" . $nasId . "';"; nr_query($query); log_register('MULTIGEN NAS [' . $nasId . '] FLUSH SERVICES'); } /** * Clones all NAS options, attributes and services * * @param int $fromId * @param int $toId * * @return void/string on error */ public function cloneNasConfiguration($fromId, $toId) { $result = ''; $fromId = vf($fromId, 3); $toId = vf($toId, 3); if ((isset($this->allNas[$fromId])) AND ( $this->allNas[$toId])) { if (isset($this->nasOptions[$fromId])) { $sourceNasOptions = $this->nasOptions[$fromId]; $sourceNasAttributes = $this->getNasAttributes($fromId); $sourceNasServices = $this->getNasServices($fromId); //deleting all old NAS setup $this->deleteAllNasConfiguration($toId); //Creating new NAS options if (!empty($sourceNasOptions)) { log_register('MULTIGEN NAS [' . $toId . '] CLONE CONFIGURATION FROM [' . $fromId . ']'); $newUserName = $sourceNasOptions['usernametype']; $newService = $sourceNasOptions['service']; $newOnlyActive = $sourceNasOptions['onlyactive']; $newPort = $sourceNasOptions['port']; //new NAS options creation $newUserName_f = mysql_real_escape_string($newUserName); $newService_f = mysql_real_escape_string($newService); $newOnlyActive_f = mysql_real_escape_string($newOnlyActive); $newPort_f = vf($newPort, 3); $query = "INSERT INTO `" . self::NAS_OPTIONS . "` (`id`,`nasid`,`usernametype`,`service`,`onlyactive`,`port`) VALUES " . "(NULL,'" . $toId . "','" . $newUserName_f . "','" . $newService_f . "','" . $newOnlyActive_f . "','" . $newPort_f . "');"; nr_query($query); log_register('MULTIGEN NAS [' . $toId . '] CLONE USERNAME `' . $newUserName . '` SERVICE `' . $newService . '` ONLYAACTIVE `' . $newOnlyActive . '` PORT `' . $newPort . '` FROM NAS [' . $fromId . ']'); } //Creating new NAS attribute templates if (!empty($sourceNasAttributes)) { foreach ($sourceNasAttributes as $io => $each) { $newScenario = $each['scenario']; $newScenario_f = mysql_real_escape_string($newScenario); $newModifier = $each['modifier']; $newModifier_f = mysql_real_escape_string($newModifier); $newAttribute = $each['attribute']; $newAttribute_f = mysql_real_escape_string($newAttribute); $newOperator = $each['operator']; $newOperator_f = mysql_real_escape_string($newOperator); $newContent = $each['content']; $newContent_f = mysql_real_escape_string($newContent); $query = "INSERT INTO `" . self::NAS_ATTRIBUTES . "` (`id`,`nasid`,`scenario`,`modifier`,`attribute`,`operator`,`content`) VALUES " . "(NULL,'" . $toId . "','" . $newScenario_f . "','" . $newModifier_f . "','" . $newAttribute_f . "','" . $newOperator_f . "','" . $newContent_f . "');"; nr_query($query); $newId = simple_get_lastid(self::NAS_ATTRIBUTES); log_register('MULTIGEN NAS [' . $toId . '] CLONE ATTRIBUTE `' . $newAttribute . '` ID [' . $newId . '] FROM NAS [' . $fromId . ']'); } } //Creating new NAS services if (!empty($sourceNasServices)) { $newPod = $sourceNasServices[$fromId]['pod']; $newPod_f = mysql_real_escape_string($newPod); $newCoaConnect = $sourceNasServices[$fromId]['coaconnect']; $newCoaConnect_f = mysql_real_escape_string($newCoaConnect); $newCoaDisconnect = $sourceNasServices[$fromId]['coadisconnect']; $newCoaDisconnect_f = mysql_real_escape_string($newCoaDisconnect); $query = "INSERT INTO `" . self::NAS_SERVICES . "` (`id`,`nasid`,`pod`,`coaconnect`,`coadisconnect`) VALUES " . "(NULL,'" . $toId . "','" . $newPod_f . "','" . $newCoaConnect_f . "','" . $newCoaDisconnect_f . "');"; nr_query($query); log_register('MULTIGEN NAS [' . $toId . '] CLONE SERVICES FROM NAS [' . $fromId . ']'); } } else { $result .= __('Something went wrong') . ': ' . __('Configuration') . ' ' . __('NAS not exists'); } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } return ($result); } /** * Pastes some configuration string data to some NAS * * @param int $nasId * @param string $confString * * @return string */ public function pasteNasConfiguration($nasId, $confString) { $result = ''; $nasId = vf($nasId, 3); $confString = trim($confString); if (!empty($nasId)) { if (isset($this->allNas[$nasId])) { if (!empty($confString)) { $confString = base64_decode($confString); $confString = json_decode($confString, true); if (!empty($confString)) { if (is_array($confString)) { if ((isset($confString['options'])) AND ( isset($confString['attributes'])) AND ( isset($confString['services']))) { $sourceNasOptions = $confString['options']; $sourceNasAttributes = $confString['attributes']; $sourceNasServices = $confString['services']; //deleting all old NAS setup $this->deleteAllNasConfiguration($nasId); //Creating new NAS options if (!empty($sourceNasOptions)) { log_register('MULTIGEN NAS [' . $nasId . '] PASTE CONFIGURATION'); $newUserName = $sourceNasOptions['usernametype']; $newService = $sourceNasOptions['service']; $newOnlyActive = $sourceNasOptions['onlyactive']; $newPort = $sourceNasOptions['port']; //new NAS options creation $newUserName_f = mysql_real_escape_string($newUserName); $newService_f = mysql_real_escape_string($newService); $newOnlyActive_f = mysql_real_escape_string($newOnlyActive); $newPort_f = vf($newPort, 3); $query = "INSERT INTO `" . self::NAS_OPTIONS . "` (`id`,`nasid`,`usernametype`,`service`,`onlyactive`,`port`) VALUES " . "(NULL,'" . $nasId . "','" . $newUserName_f . "','" . $newService_f . "','" . $newOnlyActive_f . "','" . $newPort_f . "');"; nr_query($query); log_register('MULTIGEN NAS [' . $nasId . '] PASTE USERNAME `' . $newUserName . '` SERVICE `' . $newService . '` ONLYAACTIVE `' . $newOnlyActive . '` PORT `' . $newPort . '`'); } //Creating new NAS attribute templates if (!empty($sourceNasAttributes)) { foreach ($sourceNasAttributes as $io => $each) { $newScenario = $each['scenario']; $newScenario_f = mysql_real_escape_string($newScenario); $newModifier = $each['modifier']; $newModifier_f = mysql_real_escape_string($newModifier); $newAttribute = $each['attribute']; $newAttribute_f = mysql_real_escape_string($newAttribute); $newOperator = $each['operator']; $newOperator_f = mysql_real_escape_string($newOperator); $newContent = $each['content']; $newContent_f = mysql_real_escape_string($newContent); $query = "INSERT INTO `" . self::NAS_ATTRIBUTES . "` (`id`,`nasid`,`scenario`,`modifier`,`attribute`,`operator`,`content`) VALUES " . "(NULL,'" . $nasId . "','" . $newScenario_f . "','" . $newModifier_f . "','" . $newAttribute_f . "','" . $newOperator_f . "','" . $newContent_f . "');"; nr_query($query); $newId = simple_get_lastid(self::NAS_ATTRIBUTES); log_register('MULTIGEN NAS [' . $nasId . '] PASTE ATTRIBUTE `' . $newAttribute . '` ID [' . $newId . ']'); } } //Creating new NAS services if (!empty($sourceNasServices)) { $sourceNasServices = array_shift($sourceNasServices); //getting first service element $newPod = $sourceNasServices['pod']; $newPod_f = mysql_real_escape_string($newPod); $newCoaConnect = $sourceNasServices['coaconnect']; $newCoaConnect_f = mysql_real_escape_string($newCoaConnect); $newCoaDisconnect = $sourceNasServices['coadisconnect']; $newCoaDisconnect_f = mysql_real_escape_string($newCoaDisconnect); $query = "INSERT INTO `" . self::NAS_SERVICES . "` (`id`,`nasid`,`pod`,`coaconnect`,`coadisconnect`) VALUES " . "(NULL,'" . $nasId . "','" . $newPod_f . "','" . $newCoaConnect_f . "','" . $newCoaDisconnect_f . "');"; nr_query($query); log_register('MULTIGEN NAS [' . $nasId . '] PASTE SERVICES'); } } else { $result .= __('Something went wrong') . ': EX_CONFSTRING_INCOMPLETE'; } } else { $result .= __('Something went wrong') . ': EX_CONFSTRING_CORRUPTED'; } } else { $result .= __('Something went wrong') . ': EX_CONFSTRING_CORRUPTED'; } } else { $result .= __('Something went wrong') . ': EX_EMPTY_CONFSTRING'; } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } } else { $result .= __('Something went wrong') . ': ' . __('NAS not exists'); } return ($result); } /** * Renders controls for acct date search * * @return string */ public function renderDateSerachControls() { $result = ''; $curTime = time(); $dayAgo = $curTime - (86400 * $this->days); $dayAgo = date("Y-m-d", $dayAgo); $dayTomorrow = $curTime + 86400; $dayTomorrow = date("Y-m-d", $dayTomorrow); $preDateFrom = (wf_CheckPost(array('datefrom'))) ? $_POST['datefrom'] : $dayAgo; $preDateTo = (wf_CheckPost(array('dateto'))) ? $_POST['dateto'] : $dayTomorrow; $unfinishedFlag = (wf_CheckPost(array('showunfinished'))) ? true : false; if (!wf_CheckPost(array('showunfinished'))) { $unfinishedFlag = $this->unfinished; } $inputs = wf_DatePickerPreset('datefrom', $preDateFrom, false); $inputs .= wf_DatePickerPreset('dateto', $preDateTo, false); $inputs .= wf_CheckInput('showunfinished', __('Show only unfinished'), false, $unfinishedFlag); $inputs .= wf_Submit(__('Show')); $result = wf_Form('', 'POST', $inputs, 'glamour'); return ($result); } /** * Renders preloaded accounting data into JSON * * @return void */ public function renderAcctStatsAjlist() { $result = ''; $totalCount = 0; $json = new wf_JqDtHelper(); if ($this->usernamesCachingTimeout) { $guessedUsernames = $this->cache->get('MLG_TELEPATHY', $this->usernamesCachingTimeout); //contains already guessed logins by usernames if (empty($guessedUsernames)) { $guessedUsernames = array(); } } else { $guessedUsernames = array(); } $this->loadAcctData(); //login filtering if ($this->usernamesCachingTimeout) { $allUserNames = $this->cache->get('MLG_USERNAMES', $this->usernamesCachingTimeout); if (empty($allUserNames)) { $allUserNames = $this->getAllUserNames(); } else { //here required to preload some users data if (empty($this->allUserData)) { $this->loadUserData(); if ((isset($this->altCfg[self::OPTION_SWASSIGN])) AND ( isset($this->altCfg[self::OPTION_QINQ]))) { if (($this->altCfg[self::OPTION_SWASSIGN]) AND ( $this->altCfg[self::OPTION_QINQ])) { $this->loadSwitches(); $this->loadSwithchAssigns(); $this->loadAllQinQ(); } } else { if (isset($this->altCfg[self::OPTION_UNIVERSALQINQ])) { if ($this->altCfg[self::OPTION_UNIVERSALQINQ]) { $this->loadAllQinQ(); } } } } //preloading culpa instance if ($this->meaCulpaFlag) { $this->loadMeaCulpa(); } } } else { $allUserNames = $this->getAllUserNames(); } if (ubRouting::checkGet('login')) { $filterLogin = ubRouting::get('login'); } else { $filterLogin = ''; } if (!empty($this->userAcctData)) { foreach ($this->userAcctData as $io => $each) { $fc = ''; $efc = wf_tag('font', true); //time filtering if (!empty($each['acctstoptime'])) { $startTime = strtotime($each['acctstarttime']); $endTime = strtotime($each['acctstoptime']); $timeOffsetRaw = $endTime - $startTime; $timeOffset = zb_formatTime($timeOffsetRaw); } else { $timeOffset = ''; $timeOffsetRaw = ''; } //some coloring if (empty($each['acctstoptime'])) { $fc = wf_tag('font', false, '', 'color="#ff6600"'); } else { $fc = wf_tag('font', false, '', 'color="#005304"'); } //try to speed up that search if (isset($guessedUsernames[$each['username']])) { $eachUserLogin = $guessedUsernames[$each['username']]; } else { $eachUserLogin = $this->getUserLogin($each['username'], $allUserNames); $guessedUsernames[$each['username']] = $eachUserLogin; } if (!empty($eachUserLogin)) { $userLink = wf_Link(self::URL_PROFILE . $eachUserLogin, web_profile_icon() . ' ' . @$this->allUserData[$eachUserLogin]['fulladress']); } else { $userLink = ''; } $data[] = $fc . $each['acctsessionid'] . $efc; $data[] = $each['username']; $data[] = $each['nasipaddress']; $data[] = $each['nasportid']; $data[] = $each['acctstarttime']; $data[] = $each['acctstoptime']; $data[] = stg_convert_size($each['acctinputoctets']); $data[] = stg_convert_size($each['acctoutputoctets']); $data[] = $each['framedipaddress']; $data[] = $each['acctterminatecause']; if (!empty($this->acctFieldsAdditional)) { foreach ($this->acctFieldsAdditional as $ia => $eachField) { $data[] = $each[$eachField]; } } $data[] = $timeOffset; $data[] = $userLink; if (!empty($filterLogin)) { if ($filterLogin == $eachUserLogin) { $json->addRow($data); } } else { $json->addRow($data); } unset($data); } } if ($this->usernamesCachingTimeout) { $this->cache->set('MLG_TELEPATHY', $guessedUsernames, $this->usernamesCachingTimeout); $this->cache->set('MLG_USERNAMES', $allUserNames, $this->usernamesCachingTimeout); } $json->getJson(); } /** * Renders multigen acoounting stats container * * @return string */ public function renderAcctStatsContainer() { $result = ''; $columns = array('acctsessionid', 'username', 'nasipaddress', 'nasportid', 'acctstarttime', 'acctstoptime', 'acctinputoctets', 'acctoutputoctets', 'framedipaddress', 'acctterminatecause'); if (!empty($this->acctFieldsAdditional)) { foreach ($this->acctFieldsAdditional as $io => $each) { $columns[] = $each; } } $columns[] = 'Time'; $columns[] = 'User'; if (wf_CheckPost(array('datefrom', 'dateto'))) { $searchDateFrom = mysql_real_escape_string($_POST['datefrom']); $searchDateTo = mysql_real_escape_string($_POST['dateto']); } else { $curTime = time(); $dayAgo = $curTime - (86400 * $this->days); $dayAgo = date("Y-m-d", $dayAgo); $dayTomorrow = $curTime + 86400; $dayTomorrow = date("Y-m-d", $dayTomorrow); $searchDateFrom = $dayAgo; $searchDateTo = $dayTomorrow; } if (wf_CheckPost(array('showunfinished'))) { $unfinishedFlag = "&showunfinished=true"; } else { $unfinishedFlag = ''; } if (wf_CheckGet(array('lastsessions'))) { $lastFlag = '&lastsessions=true'; } else { $lastFlag = ''; } if (wf_CheckGet(array('username'))) { $userLogin = mysql_real_escape_string($_GET['username']); $userNameFilter = '&login=' . $userLogin; } else { $userNameFilter = ''; $userLogin = ''; } $ajUrl = self::URL_ME . '&ajacct=true&datefrom=' . $searchDateFrom . '&dateto=' . $searchDateTo . $unfinishedFlag . $userNameFilter . $lastFlag; $options = '"order": [[ 0, "desc" ]]'; $result = wf_JqDtLoader($columns, $ajUrl, false, __('sessions'), 50, $options); $result .= wf_tag('br'); if (!empty($userLogin)) { $result .= wf_BackLink(self::URL_PROFILE . $userLogin); $result .= wf_Link(self::URL_ME . '&userattributes=true&username=' . $userLogin, wf_img('skins/dna_icon.png') . ' ' . __('User attributes'), false, 'ubButton') . ' '; $result .= wf_Link(self::URL_ME . '&manualpod=true&username=' . $userLogin, wf_img('skins/skull.png') . ' ' . __('Terminate user session'), false, 'ubButton') . ' '; } else { if (!wf_CheckGet(array('lastsessions'))) { $result .= wf_Link(self::URL_ME . '&lastsessions=true', wf_img('skins/clock.png') . ' ' . __('Last sessions'), false, 'ubButton'); } else { $result .= wf_BackLink(self::URL_ME); } } return ($result); } /** * Renders user manual user POD form * * @param string $userLogin * * @return string */ public function renderManualPodForm($userLogin) { $result = ''; if (!empty($userLogin)) { //preloading some required data if (empty($this->userNases)) { $this->loadUserData(); $this->loadNethosts(); $this->loadNetworks(); $this->preprocessUserData(); } if (isset($this->allUserData[$userLogin])) { if (isset($this->userNases[$userLogin])) { if (!empty($this->userNases[$userLogin])) { $nasTmp = array(); foreach ($this->userNases[$userLogin] as $io => $each) { $nasTmp[$each] = $this->allNas[$each]['nasip'] . ' - ' . $this->allNas[$each]['nasname']; } $inputs = wf_HiddenInput('manualpod', 'true'); $inputs .= wf_HiddenInput('manualpodlogin', $userLogin); $inputs .= wf_Selector('manualpodnasid', $nasTmp, __('NAS'), '', false) . ' '; $inputs .= wf_Submit(__('Send') . ' ' . __('PoD')); $result .= wf_Form('', 'POST', $inputs, 'glamour'); } else { $result .= $this->messages->getStyledMessage(__('NAS not exists') . ' ' . __('for') . ' ' . $userLogin, 'error'); } } else { $result .= $this->messages->getStyledMessage(__('NAS not exists') . ' ' . __('for') . ' ' . $userLogin, 'error'); } } else { $result .= $this->messages->getStyledMessage(__('User not exists') . ': ' . $userLogin, 'error'); } } $result .= wf_tag('br'); $result .= wf_BackLink(self::URL_ME . '&username=' . $userLogin); return ($result); } /** * Renders actual user attributes data in all available scenarios. * * @param string $userLogin * * @return string */ public function renderUserAttributes($userLogin) { $result = ''; $tmpArr = array(); if (empty($this->allUserData)) { //preloading userdata $this->loadUserData(); //loading data required for QinQ users if ((isset($this->altCfg[self::OPTION_SWASSIGN])) AND ( isset($this->altCfg[self::OPTION_QINQ]))) { if (($this->altCfg[self::OPTION_SWASSIGN]) AND ( $this->altCfg[self::OPTION_QINQ])) { $this->loadSwitches(); $this->loadSwithchAssigns(); $this->loadAllQinQ(); } } //preloading culpa instance if ($this->meaCulpaFlag) { $this->loadMeaCulpa(); } } if (isset($this->allUserData[$userLogin])) { $userData = $this->allUserData[$userLogin]; $allPossibleUserNames = $this->getAllUserNames(); if (isset($allPossibleUserNames[$userLogin])) { if (!empty($allPossibleUserNames[$userLogin])) { $possibleUserNames = $allPossibleUserNames[$userLogin]; if (!empty($this->scenarios)) { foreach ($this->scenarios as $scenarioId => $scenarioName) { $scenarioTable = self::SCENARIO_PREFIX . $scenarioId; $scenarioDb = new NyanORM($scenarioTable); foreach ($possibleUserNames as $io => $eachPossibleUserName) { $scenarioDb->orWhere('username', '=', $eachPossibleUserName); } $tmpArr[$scenarioId] = $scenarioDb->getAll(); } } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('cant read scenarios'), 'error'); } } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('cant detect username for') . ' ' . $userLogin, 'error'); } } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('cant detect username for') . ' ' . $userLogin, 'error'); } } else { $result .= $this->messages->getStyledMessage(__('User not exists') . ': ' . $userLogin, 'error'); } //render available attributes data if (!empty($tmpArr)) { foreach ($tmpArr as $scenarioId => $attributes) { $result .= wf_tag('h3') . __('Scenario') . ' ' . $scenarioId . wf_tag('h3', true); if (!empty($attributes)) { if (isset($attributes[0])) { $scenarioColumns = array_keys($attributes[0]); $cells = ''; //list available data colums foreach ($scenarioColumns as $io => $each) { $cells .= wf_TableCell($each); } $cells .= wf_TableCell(__('Actions')); $rows = wf_TableRow($cells, 'row1'); //list available user attributes foreach ($attributes as $io => $eachAttribute) { $cells = ''; foreach ($eachAttribute as $column => $value) { $cells .= wf_TableCell($value); } $delControl = self::URL_ME . '&userattributes=true&username=' . $userLogin . '&delattr=' . $eachAttribute['id'] . '&delscenario=' . $scenarioId; $delCancelControl = self::URL_ME . '&userattributes=true&username=' . $userLogin; $attrControls = wf_ConfirmDialogJS($delControl, web_delete_icon() . ' ' . __('Delete'), $this->messages->getDeleteAlert(), '', $delCancelControl); $cells .= wf_TableCell($attrControls); $rows .= wf_TableRow($cells, 'row5'); } $result .= wf_TableBody($rows, '100%', 0, 'sortable'); } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('cant detect data columns'), 'warning'); } } else { $result .= $this->messages->getStyledMessage(__('Nothing found'), 'info'); } } } else { $result .= $this->messages->getStyledMessage(__('Nothing found'), 'warning'); } $result .= wf_delimiter(0); $result .= wf_BackLink(self::URL_ME . '&username=' . $userLogin); return($result); } /** * Deletes some user attribute from some scenario by its ID * * @param int $attributeId * @param string $scenario * * @return void/string on error */ public function deleteUserAttribute($attributeId, $scenario) { $result = ''; if (isset($this->scenarios[$scenario])) { $scenarioTable = self::SCENARIO_PREFIX . $scenario; $scenarioDb = new NyanORM($scenarioTable); $scenarioDb->where('id', '=', $attributeId); $scenarioDb->delete(); log_register('MULTIGEN DELETE SCENARIO `' . $scenario . '` ATTRIBUTE [' . $attributeId . ']'); } else { $result .= __('Something went wrong') . ': ' . __('Scenario') . ' ' . $scenario . ' ' . __('Not exists'); } return($result); } /** * Executes manual PoD sending if its possilble * * @return void/string on error */ public function runManualPod() { $result = ''; if (wf_CheckPost(array('manualpod', 'manualpodlogin', 'manualpodnasid'))) { $nasId = vf($_POST['manualpodnasid'], 3); $userLogin = $_POST['manualpodlogin']; if (empty($this->allUserData)) { //preloading userdata $this->loadUserData(); //loading data required for QinQ users if ((isset($this->altCfg[self::OPTION_SWASSIGN])) AND ( isset($this->altCfg[self::OPTION_QINQ]))) { if (($this->altCfg[self::OPTION_SWASSIGN]) AND ( $this->altCfg[self::OPTION_QINQ])) { $this->loadSwitches(); $this->loadSwithchAssigns(); $this->loadAllQinQ(); } } //preloading culpa instance if ($this->meaCulpaFlag) { $this->loadMeaCulpa(); } } if (isset($this->allUserData[$userLogin])) { $userData = $this->allUserData[$userLogin]; if (isset($this->allNas[$nasId])) { $nasData = $this->allNas[$nasId]; if (isset($this->nasOptions[$nasId])) { $nasOptions = $this->nasOptions[$nasId]; $userName = $this->getLoginUsername($userLogin, $userData, $nasOptions['usernametype']); if (!empty($userName)) { //try to use custom PoD service or default with username if (!empty($this->services[$nasId]['pod'])) { $podCommand = $this->services[$nasId]['pod']; } else { $podCommand = '{PRINTF} "User-Name= {USERNAME}" | {SUDO} {RADCLIENT} {NASIP}:{NASPORT} disconnect {NASSECRET}'; } $podCommand = $this->getAttributeValue($userLogin, $userName, $nasId, $podCommand); shell_exec($podCommand); $this->logEvent('POD MANUAL ' . $userLogin . ' AS ' . $userName, 3); log_register('MULTIGEN POD MANUAL (' . $userLogin . ') AS `' . $userName . '` NASID [' . $nasId . ']'); } else { $result .= __('Something went wrong') . ': ' . __('cant detect username for') . ' ' . $userLogin; } } else { $result .= __('No') . ' ' . __('NAS options') . ': ' . $nasId; } } else { $result .= __('NAS not exists') . ': ' . $nasId; } } else { $result .= __('User not exists') . ': ' . $userLogin; } } else { //what? } return ($result); } /** * Renders multigen logs control * * @global object $ubillingConfig * * @return string */ public function renderLogControl() { global $ubillingConfig; $result = ''; $logData = array(); $renderData = ''; $rows = ''; $recordsLimit = 200; $prevTime = ''; $curTimeTime = ''; $diffTime = ''; if (file_exists(self::LOG_PATH)) { $billCfg = $ubillingConfig->getBilling(); $tailCmd = $billCfg['TAIL']; $runCmd = $tailCmd . ' -n ' . $recordsLimit . ' ' . self::LOG_PATH; $rawResult = shell_exec($runCmd); $renderData .= __('Showing') . ' ' . $recordsLimit . ' ' . __('last events') . wf_tag('br'); $renderData .= wf_Link(self::URL_ME . '&dlmultigenlog=true', wf_img('skins/icon_download.png', __('Download')) . ' ' . __('Download full log'), true); if (!empty($rawResult)) { $logData = explodeRows($rawResult); $logData = array_reverse($logData); //from new to old list if (!empty($logData)) { $cells = wf_TableCell(__('Date')); $cells .= wf_TableCell(__('Event')); $rows .= wf_TableRow($cells, 'row1'); foreach ($logData as $io => $each) { if (!empty($each)) { $eachEntry = explode(' ', $each); $cells = wf_TableCell($eachEntry[0] . ' ' . $eachEntry[1]); $cells .= wf_TableCell(str_replace(($eachEntry[0] . ' ' . $eachEntry[1]), '', $each)); $rows .= wf_TableRow($cells, 'row3'); } } $renderData .= wf_TableBody($rows, '100%', 0, 'sortable'); } } else { $renderData .= $this->messages->getStyledMessage(__('Nothing found'), 'warning'); } $result = wf_modal(wf_img('skins/log_icon_small.png', __('Attributes regeneration log')), __('Attributes regeneration log'), $renderData, '', '1280', '600'); } return ($result); } /** * Performs downloading of log * * @return void */ public function logDownload() { if (file_exists(self::LOG_PATH)) { zb_DownloadFile(self::LOG_PATH); } else { show_error(__('Something went wrong') . ': EX_FILE_NOT_FOUND ' . self::LOG_PATH); } } /** * Loads existing aggregated traffic data from database * * @return void */ protected function loadAcctTraffData() { $query = "select * from `" . self::NAS_TRAFFIC . "`;"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->previousTraffic[$each['login']] = $each; } } if ($this->ishimuraFlag) { $query = "select * from `" . self::NAS_ISHIMURA . "` WHERE `year`='" . curyear() . "' AND `month`='" . date("n") . "';"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->trafficArchive[$each['login']] = $each; } } } } /** * Loads existing aggregated traffic data from database * * @return void */ protected function loadUserTraffData() { $trafficDataTable = (!$this->ishimuraFlag) ? 'users' : self::NAS_ISHIMURA; $query = "SELECT `login`,`D0`,`U0` FROM `" . $trafficDataTable . "`;"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $this->usersTraffic[$each['login']]['D0'] = $each['D0']; $this->usersTraffic[$each['login']]['U0'] = $each['U0']; } } } /** * Performs preprocessing of current accounting traffic and stores it into database * * @return void */ public function aggregateTraffic() { $this->loadAcctTraffData(); $this->loadUserTraffData(); if ($this->ishimuraFlag) { $this->loadUserCash(); } $currentTimestamp = time(); $dateTo = date("Y-m-d H:i:s", $currentTimestamp); $lastRunTimestamp = $this->cache->get('MLG_TRAFFLASTRUN', 2592000); if (empty($lastRunTimestamp)) { $lastRunTimestamp = $currentTimestamp - 3600; } $dateFrom = date("Y-m-d H:i:s", $lastRunTimestamp); $allUserNames = $this->getAllUserNames(); $this->cache->set('MLG_TRAFFLASTRUN', $currentTimestamp, 2592000); $query = "SELECT `username`,`acctoutputoctets`,`acctinputoctets`,`acctupdatetime`,`acctstoptime` from `" . self::NAS_ACCT . "`" . " WHERE `acctupdatetime` BETWEEN '" . $dateFrom . "' AND '" . $dateTo . "' ORDER BY `radacctid` DESC;"; $all = simple_queryall($query); if (!empty($all)) { foreach ($all as $io => $each) { $loginDetect = $this->getUserLogin($each['username'], $allUserNames); if (!empty($loginDetect)) { $activity = (empty($each['acctstoptime'])) ? 1 : 0; if (isset($this->currentTraffic[$loginDetect])) { $this->currentTraffic[$loginDetect]['down'] += $each['acctoutputoctets']; $this->currentTraffic[$loginDetect]['up'] += $each['acctinputoctets']; } else { $this->currentTraffic[$loginDetect]['down'] = $each['acctoutputoctets']; $this->currentTraffic[$loginDetect]['up'] = $each['acctinputoctets']; $this->currentTraffic[$loginDetect]['activity'] = $activity; } } } if (!empty($this->currentTraffic)) { foreach ($this->currentTraffic as $changedLogin => $currentTrafficData) { //preventing first run issues if ($this->ishimuraFlag) { if (!isset($this->usersTraffic[$changedLogin])) { $this->usersTraffic[$changedLogin]['D0'] = 0; $this->usersTraffic[$changedLogin]['U0'] = 0; } } if (isset($this->usersTraffic[$changedLogin])) { $stgDownTraffic = $this->usersTraffic[$changedLogin]['D0']; $stgUpTraffic = $this->usersTraffic[$changedLogin]['U0']; if (isset($this->previousTraffic[$changedLogin])) { $previousDownTraffic = $this->previousTraffic[$changedLogin]['down']; $previousUpTraffic = $this->previousTraffic[$changedLogin]['up']; } else { $previousDownTraffic = 0; $previousUpTraffic = 0; } $lastActivity = $currentTrafficData['activity']; $diffDownTraffic = $currentTrafficData['down'] - $previousDownTraffic; $diffUpTraffic = $currentTrafficData['up'] - $previousUpTraffic; $newDownTraffic = $stgDownTraffic + $diffDownTraffic; $newUpTraffic = $stgUpTraffic + $diffUpTraffic; if (($diffDownTraffic != 0) OR ( $diffUpTraffic != 0)) { $this->saveTrafficData($changedLogin, $newDownTraffic, $newUpTraffic); $newPreviousDown = $previousDownTraffic + $diffDownTraffic; $newPreviousUp = $previousUpTraffic + $diffUpTraffic; $this->savePreviousTraffic($changedLogin, $newPreviousDown, $newPreviousUp, $lastActivity); $this->logEvent('MULTIGEN TRAFFIC SAVE (' . $changedLogin . ') ' . $newDownTraffic . '/' . $newUpTraffic, 4); } } } } } } /** * Sets traffic value via stargazer configurator or ishimura ne configurator, lol * * @param string $login * @param int $trafficDown * @param int $trafficUp * * @return void */ protected function saveTrafficData($login, $trafficDown, $trafficUp) { if (!$this->ishimuraFlag) { $command = $this->billCfg['SGCONF'] . ' set -s ' . $this->billCfg['STG_HOST'] . ' -p ' . $this->billCfg['STG_PORT'] . ' -a ' . $this->billCfg['STG_LOGIN'] . ' -w ' . $this->billCfg['STG_PASSWD'] . ' -u ' . $login . ' --d0 ' . $trafficDown . ' --u0 ' . $trafficUp; shell_exec($command); } else { $curyear = curyear(); $curmonth = date("n"); $currentCash = (isset($this->allUsersCash[$login])) ? $this->allUsersCash[$login] : 0; if (isset($this->trafficArchive[$login])) { $where = "WHERE `login`='" . $login . "' AND `year`='" . $curyear . "' AND `month`='" . $curmonth . "'"; simple_update_field(self::NAS_ISHIMURA, 'D0', $trafficDown, $where); simple_update_field(self::NAS_ISHIMURA, 'U0', $trafficUp, $where); simple_update_field(self::NAS_ISHIMURA, 'cash', $currentCash, $where); } else { $query = "INSERT INTO `" . self::NAS_ISHIMURA . "` (`login`,`month`,`year`,`U0`,`D0`,`cash`) VALUES" . "('" . $login . "','" . $curmonth . "','" . $curyear . "','" . $trafficUp . "','" . $trafficDown . "','" . $currentCash . "');"; nr_query($query); } } } /** * Saves current run traffic data into database * * @param string $login * @param int $trafficDown * @param int $trafficUp * @param int $activity * * @return void */ protected function savePreviousTraffic($login, $trafficDown, $trafficUp, $activity) { $login = mysql_real_escape_string($login); if (isset($this->previousTraffic[$login])) { $query = "UPDATE `" . self::NAS_TRAFFIC . "` SET `down`='" . $trafficDown . "', `up`='" . $trafficUp . "', `act`='" . $activity . "' WHERE `login`='" . $login . "';"; nr_query($query); } else { //new user appeared $query = "INSERT INTO `" . self::NAS_TRAFFIC . "` (`login`,`down`,`up`,`act`) VALUES " . "('" . $login . "','" . $trafficDown . "','" . $trafficUp . "'," . $activity . ");"; nr_query($query); } } /** * Performs check of multigen-rebuild lock * * @return bool */ public function isMultigenRunning() { return($this->stardust->isRunning()); } /** * Locks Multigen regeneration * * @return void */ public function runPidStart() { $this->stardust->start(); } /** * Releases Multigen regeneration lock * * @return void */ public function runPidEnd() { $this->stardust->stop(); } } |