OSDN Git Service

modified comments
[opengatem/opengatem.git] / mngsrc / getparam.c
1 /**************************************************
2 OpengateM - MAC address authentication system 
3  module for getting parameters from conf file in XML form
4  ezxml library(by Aaron Voisine) is used for handling XML
5
6 Copyright (C) 2006 Opengate Project Team
7 Written by Yoshiaki Watanabe
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 Email: watanaby@is.saga-u.ac.jp
24
25 Programmed by Yoshiaki WATANABE
26
27 **************************************************/
28 #include "opengatemmng.h"
29 #include "../ezxml/ezxml.h"
30
31 #define CONFIG_VERSION "0.7.5"   /* compared to the value in conf file */
32 #define SEPARATOR "/"            /* separator used in XML tree description */
33
34 int debug=0;
35 static ezxml_t xmlRoot=NULL;
36 static ezxml_t xmlExtraSet=NULL;
37 static ezxml_t xmlAuthServer=NULL;
38 static ezxml_t xml=NULL;
39 static ezxml_t xmlSave=NULL;
40
41 char *getConfValueExtra(char *name);
42 char *getConfValue(char *name);
43 char *convertToFacilityRaw(char *pValue);
44 int selectNextAuthServer(void);
45 char *GetConfAuthServer(char *name);
46
47 /**************************************************/
48 /* Prepare Conf file to use                       */
49 /* this is called before syslog setup             */
50 /**************************************************/
51 int openConfFile(void){
52   char buff[BUFFMAXLN];
53   char *s;
54   char *errMsg;
55
56   /* parse file and make tree */
57   if((xmlRoot = ezxml_parse_file(CONFIGFILE))==NULL){
58
59     /* as the syslog is not prepared, error is send to web*/
60     strlcpy(buff, "<H3>Error: Opengate configuration file ",BUFFMAXLN);
61     strlcat(buff, CONFIGFILE,BUFFMAXLN);
62     strlcat(buff, " is not found. Call the administrator.</H3><BR>",BUFFMAXLN);
63     PutMessageToClient(buff);
64
65     return -1;
66   }
67
68   /* to check error, convert to xml */
69   s=ezxml_toxml(xmlRoot);  free(s);
70   
71   /* if failed, show error message */
72   errMsg=(char *)ezxml_error(xmlRoot);
73   if(*errMsg!='\0'){
74     
75     /* as the syslog is not prepared, error is send to web*/
76     strlcpy(buff, "<H3>Error: Opengate configuration file ",BUFFMAXLN);
77     strlcat(buff, CONFIGFILE,BUFFMAXLN);
78     strlcat(buff, " is illegal. Call the administrator.</H3><HR>",BUFFMAXLN);
79     strlcat(buff, "XML parser message: ", BUFFMAXLN);
80     strlcat(buff, errMsg, BUFFMAXLN);
81     strlcat(buff, "<HR>", BUFFMAXLN);
82     PutMessageToClient(buff);
83
84     return -1;
85   }
86
87   /* check compatibility between conf file and this program (compare version number) */ 
88   if(isNull(ezxml_attr(xmlRoot, "ConfigVersion"))||
89      (strcmp(CONFIG_VERSION, ezxml_attr(xmlRoot, "ConfigVersion"))!=0)){
90     strlcpy(buff, "<H3>Error: Opengate configuration file ",BUFFMAXLN);
91     strlcat(buff, CONFIGFILE, BUFFMAXLN);
92     strlcat(buff, " has mismatch version.<br> Please update it with ",BUFFMAXLN);
93     strlcat(buff, CONFIGFILE, BUFFMAXLN);
94     strlcat(buff, ".sample.",BUFFMAXLN);
95     PutMessageToClient(buff);
96
97     return -1;
98   }
99
100   /* check the syslog setting */
101   if(atoi(GetConfValue("Syslog/Enable")) &&
102      atoi(GetConfValue("Syslog/Facility"))==0){
103
104     /* as the syslog is not prepared, error is send to web*/
105     strlcpy(buff, "<H3>Error: correct SYSLOG setting(local0-local7) is not found in Opengate configuration file ",BUFFMAXLN);
106     strlcat(buff, CONFIGFILE,BUFFMAXLN);
107     strlcat(buff, ". Call the administrator.</H3><BR>",BUFFMAXLN);
108     PutMessageToClient(buff);
109
110     return -1;
111   }
112
113   return 0;
114 }
115
116 /**************************************************/
117 /*  initialize the Config                         */
118 /**************************************************/
119 void initConf(void){
120   
121   /* as debug flag is used many times, put it in static variable */
122   debug=atoi(getConfValue("Debug"));
123 }
124
125 /**************************************************/
126 /* Finish Config file usage                       */
127 /**************************************************/
128 void closeConfFile(void){
129   if(xmlRoot!=NULL)ezxml_free(xmlRoot);
130 }
131
132 /**************************************************/
133 /* Setup pointer to the matched ExtraSet          */ 
134 /**************************************************/
135 void setupConfExtra(char *userId, char *extraId){
136   char* progName;
137   char useridfull[USERMAXLN]; /* userid@extraid */
138
139   /* setup long userid (userid@extraid) */
140   ConcatUserId(useridfull, userId, extraId);
141
142   /* init as non-ExtraSet */
143   xmlExtraSet=NULL;
144
145   /* search the matching extra set (first match is employed) */
146   for(xml=ezxml_child(xmlRoot, "ExtraSet"); xml; xml=xml->next){
147     
148     /* if ExtraId is exist, check it */
149     if(!isNull(ezxml_attr(xml, "ExtraId"))){
150
151       /* if not match, go to next ExtraSet */
152       /* ('default' indicated in conf matchs to Null-extraId) */
153       if(isNull(extraId)){
154         if(strcmp("default", ezxml_attr(xml, "ExtraId"))!=0)continue;
155       }else{
156         if(strcmp(extraId, ezxml_attr(xml, "ExtraId"))!=0)continue;
157       }
158     }
159
160     /* if userID pattern is exist, check it */
161     if(!isNull(ezxml_attr(xml, "UserIdPattern"))){
162
163       /* if not matched, go to next ExtraSet. last-arg 0 means ingore-case */
164       if(RegExMatch(userId,ezxml_attr(xml,"UserIdPattern"),0)==FALSE){
165         continue;
166       }
167     }
168
169     /* if UserExtraPattern is exist, check it */
170     /*  UserExtraPattern = REGEX pattern matching to "userid@extraid" */
171     if(!isNull(ezxml_attr(xml, "UserExtraPattern"))){
172
173       /* if not matched, go to next ExtraSet. last-arg 0 means ingore-case */
174       if(RegExMatch(useridfull,ezxml_attr(xml,"UserExtraPattern"),0)==FALSE){
175         continue;
176       }
177     }
178
179     /* if UserExtraPtternNot is exist, check it */
180     /*  UserExtraPatternNot = REGEX pattern NOT matching to "userid@extraid" */
181     if(!isNull(ezxml_attr(xml, "UserExtraPatternNot"))){
182
183       /* if matched, go to next ExtraSet. last-arg 0 means ingore-case */
184       if(RegExMatch(useridfull,ezxml_attr(xml,"UserExtraPatternNot"),0)==TRUE){
185         continue;
186       }
187     }
188
189     /* found matched ExtraSet */
190     break;
191   }
192
193   /* if found a matched ExtraSet, save the pointer */
194   if(xml!=NULL) xmlExtraSet=xml;
195
196   /* change syslog setting */
197   errToSyslog(atoi(GetConfValue("Syslog/Enable")));
198   progName=getProgramName();
199   openlog(progName, LOG_PID, atoi(GetConfValue("Syslog/Facility")));
200
201   /* reset config setting */
202   InitConf();
203 }
204
205 /****************************************************/
206 /* regular expression matching                      */
207 /*  inStr : (in) string to match                    */
208 /*  regEx : (in) regular expression                 */
209 /*  caseSensitive : (in) 0=ignore case, 1=sensitive */
210 /*  return value : TRUE=match, FALSE=unmatch        */
211 /****************************************************/
212 int regExMatch(const char *inStr, const char *regEx, int caseSensitive){
213   regex_t reg;
214   int errcode;
215   int match;
216   char errbuff[WORDMAXLN];
217
218   /* compile regex */
219   if(caseSensitive){
220     errcode=regcomp(&reg, regEx, REG_NOSUB|REG_EXTENDED);
221   }else{
222     errcode=regcomp(&reg, regEx, REG_NOSUB|REG_EXTENDED|REG_ICASE);
223   }
224
225   /* if error, return false */
226   if(errcode!=0){
227     regerror(errcode, &reg, errbuff, WORDMAXLN);
228     err_msg("ERR at %s#%d: regex message=%s",__FILE__,__LINE__,errbuff);
229     match=FALSE;
230   }
231   
232   /* if compile is success, check the input string */
233   else{
234     if(regexec(&reg, inStr, (size_t)0, NULL, 0)==0) match=TRUE;
235     else match=FALSE;
236   }
237
238   /* free memory for the compiled regex */
239   regfree(&reg);
240
241   return match;
242 }
243
244 /**************************************************/
245 /*  get a value for name from Conf file           */
246 /*  the name[aa/bb/cc] means the path in xml      */
247 /*  extraSet value is overlayed, if exists        */
248 /**************************************************/
249 char *getConfValue(char *name){
250   char *pValue;
251   char *pValueExtra;
252   char *pStr;
253   char buff[BUFFMAXLN];
254
255   /* AuthServer setting is done in other routine */
256   if(strstr(name,"AuthServer/")==name) return GetConfAuthServer(name);
257
258   /* copy name to work area */
259   strlcpy(buff,name,BUFFMAXLN);
260
261   /* get first token */
262   pStr=strtok(buff, SEPARATOR);
263
264   /* set search start to root of tree */
265   xml=xmlRoot;
266
267   /* search the tree node for the name */
268   while(pStr!=NULL){
269     xml=ezxml_child(xml, pStr);
270     pStr=strtok(NULL, SEPARATOR);
271   }
272
273   /* get the node value */
274   pValue= ezxml_txt(xml);
275
276   /* if not get, write error message */
277   if(pValue==NULL){
278     err_msg("ERR at %s#%d: cannot get %s from conf file",__FILE__,__LINE__,name);
279   }
280
281   /* get value in extra set matched to name                     */
282   /* if name is matched in first level, reset all child setting */
283   /*****************************************************************
284   in the following, <CmdPath> and <Timing> for 'user1' is NOT defined 
285      <Mail>
286          <CmdPath>/bin/rmail</CmdPath>
287          <Content>/etc/opengate/warningmail</Content>
288          <Timing>date(now())=date(........)</Timing>
289     </Mail>
290     <ExtraSet ExtraId="default" UserIdPattern="^user1$|^user2$">        
291         <Mail>
292             <Content>/etc/opengate/warningmail-special</Content>
293        </Mail>
294     </ExtraSet>
295   *****************************************************************/
296   if(!isNull(pValueExtra=getConfValueExtra(name))){
297     pValue=pValueExtra;
298   }
299
300   /* if syslog facility, the id is converted to raw value */
301   if(strcmp(name,"Syslog/Facility")==0){
302     pValue=convertToFacilityRaw(pValue);
303   }
304
305   /* return found value */
306   return pValue;
307 }
308
309 /************************************************/
310 /* get the value in extra set matched to name   */
311 /************************************************/
312 char *getConfValueExtra(char *name){
313   char *pStr;
314   char buff[BUFFMAXLN];
315   ezxml_t xml;
316
317   if(xmlExtraSet==NULL) return "";
318
319   /* extract first token in name */
320   strlcpy(buff,name,BUFFMAXLN);
321   pStr=strtok(buff, SEPARATOR);  
322
323   /* get a first level matched node in extra set */
324   /* the first level is not included in the following loop */
325   /* as to prevent partial overlay of sub level value */
326   /* (see 40-lines above) */
327   xml=ezxml_child(xmlExtraSet, pStr);
328   if(xml==NULL) return "";
329
330   /* search the node matched to name */
331   pStr=strtok(NULL, SEPARATOR);
332   while(pStr!=NULL){
333     xml=ezxml_child(xml, pStr);
334     pStr=strtok(NULL, SEPARATOR);
335   }
336
337   /* return the found value */
338   return ezxml_txt(xml);
339 }
340
341
342 /***************************************************/
343 /*  get a value for AuthServer param from Conf file*/
344 /*  the name[AuthServer/bb/cc] means the xml path  */
345 /***************************************************/
346 char *getConfAuthServer(char *name)
347 {
348   char *pValue;
349   char *pStr;
350   char buff[BUFFMAXLN];
351   ezxml_t xml;
352
353   /* copy name to work area */
354   strlcpy(buff,name,BUFFMAXLN);
355
356   /* get first token */
357   pStr=strtok(buff, SEPARATOR);
358
359   /* it must be AuthServer. if not return */
360   if(strcmp(pStr, "AuthServer")!=0)return NULL;
361
362   /* if authserver pointer is not set, set it */
363   if(xmlAuthServer==NULL){
364     if(!selectNextAuthServer()) return NULL;
365   }
366
367   /* set search start to the saved pointer */
368   xml=xmlAuthServer;
369
370   /* search the tree node for the name */
371   pStr=strtok(NULL, SEPARATOR);
372   while(pStr!=NULL){
373     xml=ezxml_child(xml, pStr);
374     pStr=strtok(NULL, SEPARATOR);
375   }
376
377   /* get the node value */
378   pValue= ezxml_txt(xml);
379
380   /* if not get Protocol, write error message */
381   if(isNull(pValue)
382      && (strcmp(name,"AuthServer/Protocol")==0) ){
383     err_msg("ERR at %s#%d: cannot get %s from conf file",__FILE__,__LINE__,name);
384   }
385
386   /* return found value */
387   return pValue;
388 }
389
390 /*****************************************************************/
391 /* select next authserver setting                                */
392 /* at first call, this selects the first server setting          */
393 /* and form second call, this selects the next server setting    */
394 /* ResetAuthServerPointer() returns the pointer to first setting */
395 /*****************************************************************/
396 int selectNextAuthServer(void){
397
398   ezxml_t xmlTmp; /* temporary variable */
399
400   /* first call (initialize) */
401   /* xmlAuthPointer is the static variable to save authserver pointer */
402   if(xmlAuthServer==NULL){
403
404     /* if not set, search the first authserver pointer */
405      xmlAuthServer=ezxml_child(xmlRoot, "AuthServer");
406      
407      /* if authserver is found in extra set, pointer is moved to it */ 
408      if(xmlExtraSet!=NULL){
409        xmlTmp=ezxml_child(xmlExtraSet, "AuthServer");
410        if(xmlTmp!=NULL){
411          xmlAuthServer=xmlTmp;
412        }
413      }
414   }
415
416   /* successive calls */
417   /* pointer is moved to next */
418   else{
419     xmlAuthServer=ezxml_next(xmlAuthServer);
420   }
421
422   /* if not found return False */
423   if(xmlAuthServer==NULL){
424     return FALSE;
425   }else{
426     return TRUE;
427   }
428 }
429
430 /*********************************************/
431 /* reset pointer for auth server list        */
432 /*********************************************/
433 void resetAuthServerPointer(void){
434   xmlAuthServer=NULL;
435 }
436
437 /************************************************************/
438 /* Convart the syslog facility id(string) to raw value(int) */
439 /************************************************************/
440 char *convertToFacilityRaw(char *pValue){
441   static char facility[WORDMAXLN];
442   int rawValue;
443
444   if     (strcmp(pValue, "local0")==0) rawValue=LOG_LOCAL0;
445   else if(strcmp(pValue, "local1")==0) rawValue=LOG_LOCAL1;
446   else if(strcmp(pValue, "local2")==0) rawValue=LOG_LOCAL2;
447   else if(strcmp(pValue, "local3")==0) rawValue=LOG_LOCAL3;
448   else if(strcmp(pValue, "local4")==0) rawValue=LOG_LOCAL4;
449   else if(strcmp(pValue, "local5")==0) rawValue=LOG_LOCAL5;
450   else if(strcmp(pValue, "local6")==0) rawValue=LOG_LOCAL6;
451   else if(strcmp(pValue, "local7")==0) rawValue=LOG_LOCAL7;
452   else rawValue=0;
453
454   snprintf(facility, WORDMAXLN, "%d", rawValue);
455
456   return facility;
457 }
458
459 /**************************************************/
460 /*  get the first value matched to name           */
461 /*  (first node of matched lowest level of tree)  */  
462 /**************************************************/
463 char *getFirstConfValue(char* name){
464    char *pValue;
465    pValue=GetConfValue(name);
466
467   /* save the pointer now */
468    xmlSave=xml;
469
470   /* return found value */
471   return pValue;
472 }
473
474 /**************************************************/
475 /*  get the value in sibling of previous get      */
476 /*  (next node of the lowest level of tree)       */  
477 /**************************************************/
478 char *getNextConfValue(void){
479   char *pValue;
480
481   /* recover previous pointer */
482   xml=xmlSave;
483
484   /* get next node */
485   if(xml==NULL) return "";
486   xml = ezxml_next(xml);
487
488   /* save for next call */
489   xmlSave=xml;
490
491   /* get the node value */
492   pValue= ezxml_txt(xml);
493
494   /* if not get, write error message */
495   if(pValue==NULL) return "";
496
497   /* return found value */
498   return pValue;
499 }
500
501
502 /***********************************************/
503 /***********************************************/
504 int OpenConfFile(void){
505   int ret;
506   if(debug>1) err_msg("DEBUG:=>openConfFile( )");
507   ret = openConfFile();
508   if(debug>1) err_msg("DEBUG:(%d)<=openConfFile( )",ret);
509   return ret;
510 }
511
512 void CloseConfFile(void){
513   if(debug>1) err_msg("DEBUG:=>closeConfFile( )");
514   closeConfFile();
515   if(debug>1) err_msg("DEBUG:<=closeConfFile( )");
516 }
517
518 void SetupConfExtra(char *userId, char *extraId){
519   if(debug>1) err_msg("DEBUG:=>setupConfExtra(%s,%s)",userId, extraId);
520   setupConfExtra(userId, extraId);
521   if(debug>1) err_msg("DEBUG:<=setupConfExtra( )");
522 }
523
524 char *GetConfValue(char *name){
525   char *ret;
526   if(debug>1) err_msg("DEBUG:=>getConfValue(%s)",name);
527   ret=getConfValue(name);
528   if(debug>1) err_msg("DEBUG:(%s)<=getConfValue( )",ret);
529   return ret;
530 }
531
532 char *GetConfValueExtra(char *name){
533   char *ret;
534   if(debug>1) err_msg("DEBUG:=>getConfValueExtra(%s)",name);
535   ret=getConfValueExtra(name);
536   if(debug>1) err_msg("DEBUG:(%s)<=getConfValueExtra( )",ret);
537   return ret;
538 }
539
540 char *GetConfAuthServer(char *name){
541   char *ret;
542   if(debug>1) err_msg("DEBUG:=>getConfAuthServer(%s)",name);
543   ret=getConfAuthServer(name);
544   if(debug>1) err_msg("DEBUG:(%s)<=getConfAuthServer( )",ret);
545   return ret;
546 }
547
548 int SelectNextAuthServer(void){
549   int ret;
550   if(debug>1) err_msg("DEBUG:=>selectNextAuthServer( )");
551   ret=selectNextAuthServer();
552   if(debug>1) err_msg("DEBUG:(%d)<=selectNextAuthServer( )",ret);
553   return ret;
554 }
555
556 void InitConf(void){
557   if(debug>1) err_msg("DEBUG:=>initConf( )");
558   initConf();
559   if(debug>1) err_msg("DEBUG:<=initConf( )");
560 }
561
562 int RegExMatch(const char *inStr, const char *regEx, int caseSensitive){
563   int ret;
564   if(debug>1) err_msg("DEBUG:=>regExMatch(%s,%s)",inStr,regEx,caseSensitive);
565   ret=regExMatch(inStr, regEx,caseSensitive);
566   if(debug>1) err_msg("DEBUG:(%d)<=regExMatch( )",ret);
567   return ret;
568 }
569   
570 void ResetAuthServerPointer(void){
571   if(debug>1) err_msg("DEBUG:=>resetAuthServerPointer( )");
572   resetAuthServerPointer();
573   if(debug>1) err_msg("DEBUG:<=resetAuthServerPointer( )");
574 }
575
576 char *GetFirstConfValue(char* name){
577   char *ret;
578   if(debug>1) err_msg("DEBUG:=>getFirstConfValue( )");
579   ret=getFirstConfValue(name);
580   if(debug>1) err_msg("DEBUG:(%s)<=getFirstConfValue( )",ret);
581   return ret;
582 }
583
584 char *GetNextConfValue(){
585   char *ret;
586   if(debug>1) err_msg("DEBUG:=>getNextConfValue( )");
587   ret=getNextConfValue();
588   if(debug>1) err_msg("DEBUG:(%s)<=getNextConfValue( )",ret);
589   return ret;
590 }
591