38 #include <sys/param.h>
40 #include <sys/types.h>
67 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute);
69 #define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
71 #define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
73 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; return 0;}
75 #define ACC_PGO 0x0001
108 dbpath = strdup(
"/opt/xrd/etc/Authfile");
132 int retc, NoGo = 0, Cold = (Database == 0);
137 Eroute.
Say(
"++++++ Authorization system initialization started.");
142 || (NoGo = ConfigFile(Eroute, cfn))
152 Eroute.Emsg(
"ConfigDB",retc,
"start refresh thread.");
157 var = (NoGo > 0 ? (
char *)
"failed." : (
char *)
"completed.");
158 Eroute.
Say(
"------ Authorization system initialization ", var);
176 int retc, anum = 0, NoGo = 0;
183 else if (Warm && !Database->
Changed(dbpath))
return 0;
187 if (!Database || !Database->
Open(Eroute, dbpath))
return 1;
198 {Eroute.
Emsg(
"ConfigDB",
"Insufficient storage for id tables.");
199 Database->
Close();
return 1;
205 while((retc = ConfigDBrec(Eroute, tabs))) {NoGo |= retc < 0; anum++;}
206 snprintf(buff,
sizeof(buff),
"%d auth entries processed in ", anum);
207 Eroute.
Say(
"Config ", buff, dbpath);
211 if (!Database->
Close() || NoGo)
return 1;
240 int XrdAccConfig::ConfigFile(
XrdSysError &Eroute,
const char *ConfigFN) {
251 int cfgFD, retc, NoGo = 0, recs = 0;
257 if( !ConfigFN || !*ConfigFN)
258 {Eroute.
Emsg(
"Config",
"Authorization configuration file not specified.");
264 if (!strcmp(ConfigFN,
"none"))
265 {Eroute.
Emsg(
"Config",
"Authorization system deactivated.");
271 if ( (cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
272 {Eroute.
Emsg(
"Config", errno,
"open config file", ConfigFN);
275 Eroute.
Emsg(
"Config",
"Authorization system using configuration in",ConfigFN);
280 static const char *cvec[] = {
"*** acc plugin config:", 0 };
283 while((var =
Config.GetMyFirstWord()))
284 {
if (!strncmp(var,
"acc.", 2))
286 if (ConfigXeq(var+4,
Config, Eroute)) {
Config.Echo(); NoGo = 1;}
292 if ((retc =
Config.LastError()))
293 NoGo = Eroute.
Emsg(
"Config",-retc,
"read config file",ConfigFN);
294 else {
char buff[128];
295 snprintf(buff,
sizeof(buff),
296 "%d authorization directives processed in ", recs);
297 Eroute.
Say(
"Config ", buff, ConfigFN);
314 void XrdAccConfig::ConfigDefaults()
331 TS_Xeq(
"authrefresh", xart);
333 TS_Xeq(
"gidlifetime", xglt);
334 TS_Xeq(
"gidretran", xgrt);
335 TS_Xeq(
"nisdomain", xnis);
337 TS_Xeq(
"spacechar", xspc);
341 Eroute.
Emsg(
"Config",
"unknown directive", var);
350 void XrdAccConfig::subSpace(
char *
id)
354 while((spc = index(
id, spChar)))
379 static struct auditopts {
const char *opname;
int opval;} audopts[] =
384 int i, audval = 0, numopts =
sizeof(audopts)/
sizeof(
struct auditopts);
389 {Eroute.
Emsg(
"Config",
"audit option not specified");
return 1;}
390 while (val && val[0])
391 {
if (!strcmp(val,
"none")) audval = (
int)
audit_none;
392 else for (i = 0; i < numopts; i++)
393 {
if (!strcmp(val, audopts[i].opname))
394 {audval |= audopts[i].opval;
break;}
396 {Eroute.
Emsg(
"Config",
"invalid audit option -",val);
426 {Eroute.
Emsg(
"Config",
"authrefresh value not specified");
return 1;}
451 if (!(val =
Config.GetWord()) || *val == 0)
452 {Eroute.
Emsg(
"Config",
"encoding argument not specified");
return 1;}
454 do{
if (!strcmp(val,
"pct"))
455 {
if (!(val =
Config.GetWord()))
456 {Eroute.
Emsg(
"Config",
"pct argument not specified");
459 if (strcmp(val,
"path"))
460 {Eroute.
Emsg(
"Config",val,
"pct encoding not supported");
465 else if (!strcmp(val,
"space"))
466 {
if (!(val =
Config.GetWord()))
467 {Eroute.
Emsg(
"Config",
"space argument not specified");
470 if (strlen(val) != 1)
471 {Eroute.
Emsg(
"Config",
"invalid space argument -", val);
476 }
while((val =
Config.GetWord()) && *val);
501 {Eroute.
Emsg(
"Config",
"authdb path not specified");
return 1;}
502 dbpath = strdup(val);
526 {Eroute.
Emsg(
"Config",
"gidlifetime value not specified");
return 1;}
554 {Eroute.
Emsg(
"Config",
"gidretran value not specified");
return 1;}
556 while (val && val[0])
559 {Eroute.
Emsg(
"Config",
"to many gidretran gid's");
return 1;}
584 {Eroute.
Emsg(
"Config",
"nisdomain value not specified");
return 1;}
608 {Eroute.
Emsg(
"Config",
"spacechar argument not specified");
return 1;}
609 if (strlen(val) != 1)
610 {Eroute.
Emsg(
"Config",
"invalid spacechar argument -", val);
return 1;}
627 enum DB_RecType { Group_ID =
'g',
639 char *authid, rtype, *path, *privs;
640 int alluser = 0, anyuser = 0, domname = 0, NoGo = 0;
648 bool istmplt, isDup, xclsv =
false;
652 if (!(rtype = Database->
getRec(&authid)))
return 0;
653 rectype = (DB_RecType)rtype;
658 {
case Group_ID: hp = tabs.
G_Hash;
660 if (spChar) subSpace(authid);
662 case Host_ID: hp = tabs.
H_Hash;
663 domname = (authid[0] ==
'.');
667 case Netgrp_ID: hp = tabs.
N_Hash;
670 case Org_ID: hp = tabs.
O_Hash;
671 if (spChar) subSpace(authid);
673 case Role_ID: hp = tabs.
R_Hash;
674 if (spChar) subSpace(authid);
676 case Template_ID: hp = tabs.
T_Hash;
678 case User_ID: hp = tabs.
U_Hash;
679 alluser = (authid[0] ==
'*' && !authid[1]);
680 anyuser = (authid[0] ==
'=' && !authid[1]);
681 if (!alluser && !anyuser && spChar) subSpace(authid);
683 case Xxx_ID: hp = 0; xclsv =
true;
685 case Def_ID:
return idDef(Eroute, tabs, authid);
687 default:
char badtype[2] = {rtype,
'\0'};
688 Eroute.
Emsg(
"ConfigXeq",
"Invalid id type -",
699 else if (alluser) isDup = tabs.
Z_List != 0;
700 else if (anyuser) isDup = tabs.
X_List != 0;
701 else if (hp) isDup = hp->
Find(authid) != 0;
703 {Eroute.
Emsg(
"ConfigXeq",
"Missing id definition -", authid);
706 isDup = sp->
caps != 0;
707 sp->
rule = (xclsv ? rulenum++ : -1);
711 {Eroute.
Emsg(
"ConfigXeq",
"duplicate rule for id -", authid);
722 if (!Database->
getPP(&path, &privs, istmplt))
break;
728 else {Eroute.
Emsg(
"ConfigXeq",
"Missing template -", path);
733 {Eroute.
Emsg(
"ConfigXeq",
"Missing privs for path", path);
736 if (!PrivsConvert(privs, xprivs))
737 {Eroute.
Emsg(
"ConfigXeq",
"Invalid privs -", privs);
741 {
int plen = strlen(path);
742 char *decp = (
char *)alloca(plen+1);
747 lastcap->
Add(currcap);
758 {Eroute.
Emsg(
"ConfigXeq",
"no capabilities specified for", authid);
767 {Eroute.
Emsg(
"ConfigXeq",
"unable to add id",authid);
return -1;}
774 else hp->
Add(authid, mycap.Next());
790 std::map<int, XrdAccAccess_ID *> idMap;
797 {idPN = idList->
next;
798 if (idList->
caps == 0)
799 Eroute.
Say(
"Config ",
"Warning, unused identifier definition '",
801 else if (idList->
rule >= 0) idMap[idList->
rule] = idList;
802 else {idList->
next = yList; yList = idList;}
809 std::map<int,XrdAccAccess_ID *>::reverse_iterator rit;
810 for (rit = idMap.rbegin(); rit != idMap.rend(); ++rit)
811 {rit->second->
next = xList;
830 char *idname, buff[80], idType;
831 bool haveID =
false, idDup =
false;
836 {
if (!(idType = Database->
getID(&idname)))
break;
839 {
case 'g':
if (spChar) subSpace(idname);
840 if (theID.grp) idDup =
true;
841 else{theID.grp = strdup(idname);
842 theID.glen = strlen(idname);
845 case 'h':
if (theID.host) idDup =
true;
846 else{theID.host = strdup(idname);
847 theID.hlen = strlen(idname);
850 case 'o':
if (theID.org) idDup =
true;
851 else {
if (spChar) subSpace(idname);
852 theID.org = strdup(idname);
855 case 'r':
if (theID.role) idDup =
true;
856 else {
if (spChar) subSpace(idname);
857 theID.role = strdup(idname);
860 case 'u':
if (theID.user) idDup =
true;
861 else {
if (spChar) subSpace(idname);
862 theID.user = strdup(idname);
865 default: snprintf(buff,
sizeof(buff),
"'%c: %s' for",
867 Eroute.
Emsg(
"ConfigXeq",
"Invalid id selector -",
873 {snprintf(buff,
sizeof(buff),
874 "id selector '%c' specified twice for", idType);
875 Eroute.
Emsg(
"ConfigXeq", buff, theID.name);
883 {Eroute.
Emsg(
"ConfigXeq",
"No id selectors specified for", theID.name);
891 {Eroute.
Emsg(
"ConfigXeq",
"duplicate id definition -",theID.name);
947 case Neg_Priv:
if (i)
return 0; i++;
break;
XrdAccAuthDB * XrdAccAuthDBObject(XrdSysError *erp)
void * XrdAccConfig_Refresh(void *start_data)
XrdAccConfig XrdAccConfiguration
int open(const char *path, int oflag,...)
void SwapTabs(struct XrdAccAccess_Tables &newtab)
void setAudit(XrdAccAudit_Options aops)
virtual int Changed(const char *path=0)=0
virtual int getPP(char **path, char **priv, bool &istmplt)=0
virtual char getRec(char **recname)=0
virtual int Open(XrdSysError &eroute, const char *path=0)=0
virtual char getID(char **id)=0
void Add(XrdAccCapName *cnp)
XrdAccCapability * Find(const char *name)
XrdAccCapability * Next()
void Add(XrdAccCapability *newcap)
int Configure(XrdSysError &Eroute, const char *cfn)
XrdAccAccess * Authorization
int ConfigDB(int Warm, XrdSysError &Eroute)
char * AddName(const XrdAccGroupType gtype, const char *name)
int Retran(const gid_t gid)
void SetOptions(XrdAccGroups_Options opts)
void SetLifetime(const int seconds)
void SetDomain(const char *dname)
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
T * Find(const char *KeyVal, time_t *KeyTime=0)
static int Decode(const char *src, int len, char *dst)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
XrdAccAccess_ID * Export()
XrdOucHash< XrdAccCapability > * U_Hash
XrdOucHash< XrdAccCapability > * G_Hash
XrdOucHash< XrdAccCapability > * N_Hash
XrdAccCapability * X_List
XrdAccCapability * Z_List
XrdOucHash< XrdAccCapability > * T_Hash
XrdOucHash< XrdAccCapability > * O_Hash
XrdOucHash< XrdAccCapability > * H_Hash
XrdOucHash< XrdAccAccess_ID > * S_Hash
XrdOucHash< XrdAccCapability > * R_Hash