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;}
113 const char *dbpath_defaults[] = {
114 "/opt/xrd/etc/Authfile",
119 for (
const char *path : dbpath_defaults)
120 if (
access(path, R_OK) == 0)
121 dbpath = strdup(path);
141 int retc, NoGo = 0, Cold = (Database == 0);
146 Eroute.
Say(
"++++++ Authorization system initialization started.");
151 || (NoGo = ConfigFile(Eroute, cfn))
161 Eroute.Emsg(
"ConfigDB",retc,
"start refresh thread.");
166 var = (NoGo > 0 ? (
char *)
"failed." : (
char *)
"completed.");
167 Eroute.
Say(
"------ Authorization system initialization ", var);
185 int retc, anum = 0, NoGo = 0;
192 else if (Warm && !Database->Changed(dbpath))
return 0;
196 if (!Database || !Database->Open(Eroute, dbpath))
return 1;
207 {Eroute.
Emsg(
"ConfigDB",
"Insufficient storage for id tables.");
208 Database->Close();
return 1;
214 while((retc = ConfigDBrec(Eroute, tabs))) {NoGo |= retc < 0; anum++;}
215 snprintf(buff,
sizeof(buff),
"%d auth entries processed in ", anum);
216 Eroute.
Say(
"Config ", buff, dbpath);
220 if (!Database->Close() || NoGo)
return 1;
249int XrdAccConfig::ConfigFile(
XrdSysError &Eroute,
const char *ConfigFN) {
260 int cfgFD, retc, NoGo = 0, recs = 0;
262 XrdOucStream Config(&Eroute, getenv(
"XRDINSTANCE"), &myEnv,
"=====> ");
266 if( !ConfigFN || !*ConfigFN)
267 {Eroute.
Emsg(
"Config",
"Authorization configuration file not specified.");
273 if (!strcmp(ConfigFN,
"none"))
274 {Eroute.
Emsg(
"Config",
"Authorization system deactivated.");
280 if ( (cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
281 {Eroute.
Emsg(
"Config", errno,
"open config file", ConfigFN);
284 Eroute.
Emsg(
"Config",
"Authorization system using configuration in",ConfigFN);
289 static const char *cvec[] = {
"*** acc plugin config:", 0 };
292 while((var =
Config.GetMyFirstWord()))
293 {
if (!strncmp(var,
"acc.", 2))
295 if (ConfigXeq(var+4, Config, Eroute)) {
Config.Echo(); NoGo = 1;}
301 if ((retc =
Config.LastError()))
302 NoGo = Eroute.
Emsg(
"Config",-retc,
"read config file",ConfigFN);
303 else {
char buff[128];
304 snprintf(buff,
sizeof(buff),
305 "%d authorization directives processed in ", recs);
306 Eroute.
Say(
"Config ", buff, ConfigFN);
323void XrdAccConfig::ConfigDefaults()
340 TS_Xeq(
"authrefresh", xart);
342 TS_Xeq(
"gidlifetime", xglt);
343 TS_Xeq(
"gidretran", xgrt);
344 TS_Xeq(
"nisdomain", xnis);
346 TS_Xeq(
"spacechar", xspc);
350 Eroute.
Emsg(
"Config",
"unknown directive", var);
359void XrdAccConfig::subSpace(
char *
id)
363 while((spc = index(
id, spChar)))
388 static struct auditopts {
const char *opname;
int opval;} audopts[] =
393 int i, audval = 0, numopts =
sizeof(audopts)/
sizeof(
struct auditopts);
398 {Eroute.
Emsg(
"Config",
"audit option not specified");
return 1;}
399 while (val && val[0])
400 {
if (!strcmp(val,
"none")) audval = (int)
audit_none;
401 else for (i = 0; i < numopts; i++)
402 {
if (!strcmp(val, audopts[i].opname))
403 {audval |= audopts[i].opval;
break;}
405 {Eroute.
Emsg(
"Config",
"invalid audit option -",val);
435 {Eroute.
Emsg(
"Config",
"authrefresh value not specified");
return 1;}
460 if (!(val =
Config.GetWord()) || *val == 0)
461 {Eroute.
Emsg(
"Config",
"encoding argument not specified");
return 1;}
463do{
if (!strcmp(val,
"pct"))
464 {
if (!(val =
Config.GetWord()))
465 {Eroute.
Emsg(
"Config",
"pct argument not specified");
468 if (strcmp(val,
"path"))
469 {Eroute.
Emsg(
"Config",val,
"pct encoding not supported");
474 else if (!strcmp(val,
"space"))
475 {
if (!(val =
Config.GetWord()))
476 {Eroute.
Emsg(
"Config",
"space argument not specified");
479 if (strlen(val) != 1)
480 {Eroute.
Emsg(
"Config",
"invalid space argument -", val);
485 }
while((val =
Config.GetWord()) && *val);
510 {Eroute.
Emsg(
"Config",
"authdb path not specified");
return 1;}
511 dbpath = strdup(val);
535 {Eroute.
Emsg(
"Config",
"gidlifetime value not specified");
return 1;}
563 {Eroute.
Emsg(
"Config",
"gidretran value not specified");
return 1;}
565 while (val && val[0])
568 {Eroute.
Emsg(
"Config",
"to many gidretran gid's");
return 1;}
593 {Eroute.
Emsg(
"Config",
"nisdomain value not specified");
return 1;}
617 {Eroute.
Emsg(
"Config",
"spacechar argument not specified");
return 1;}
618 if (strlen(val) != 1)
619 {Eroute.
Emsg(
"Config",
"invalid spacechar argument -", val);
return 1;}
636 enum DB_RecType { Group_ID =
'g',
648 char *authid, rtype, *path, *privs;
649 int alluser = 0, anyuser = 0, domname = 0, NoGo = 0;
651 XrdAccAccess_ID *sp = 0;
652 XrdOucHash<XrdAccCapability> *hp;
654 XrdAccPrivCaps xprivs;
655 XrdAccCapability mycap((
char *)
"", xprivs), *currcap, *lastcap = &mycap;
657 bool istmplt, isDup, xclsv =
false;
661 if (!(rtype = Database->getRec(&authid)))
return 0;
662 rectype = (DB_RecType)rtype;
667 {
case Group_ID: hp = tabs.
G_Hash;
669 if (spChar) subSpace(authid);
671 case Host_ID: hp = tabs.
H_Hash;
672 domname = (authid[0] ==
'.');
676 case Netgrp_ID: hp = tabs.
N_Hash;
679 case Org_ID: hp = tabs.
O_Hash;
680 if (spChar) subSpace(authid);
682 case Role_ID: hp = tabs.
R_Hash;
683 if (spChar) subSpace(authid);
685 case Template_ID: hp = tabs.
T_Hash;
687 case User_ID: hp = tabs.
U_Hash;
688 alluser = (authid[0] ==
'*' && !authid[1]);
689 anyuser = (authid[0] ==
'=' && !authid[1]);
690 if (!alluser && !anyuser && spChar) subSpace(authid);
692 case Xxx_ID: hp = 0; xclsv =
true;
694 case Def_ID:
return idDef(Eroute, tabs, authid);
696 default:
char badtype[2] = {rtype,
'\0'};
697 Eroute.
Emsg(
"ConfigXeq",
"Invalid id type -",
708 else if (alluser) isDup = tabs.
Z_List != 0;
709 else if (anyuser) isDup = tabs.
X_List != 0;
710 else if (hp) isDup = hp->
Find(authid) != 0;
712 {Eroute.
Emsg(
"ConfigXeq",
"Missing id definition -", authid);
715 isDup = sp->
caps != 0;
716 sp->
rule = (xclsv ? rulenum++ : -1);
720 {Eroute.
Emsg(
"ConfigXeq",
"duplicate rule for id -", authid);
726 if (gtype)
GroupMaster.AddName(gtype, (
const char *)authid);
731 if (!Database->getPP(&path, &privs, istmplt))
break;
736 currcap =
new XrdAccCapability(currcap);
737 else {Eroute.
Emsg(
"ConfigXeq",
"Missing template -", path);
742 {Eroute.
Emsg(
"ConfigXeq",
"Missing privs for path", path);
745 if (!PrivsConvert(privs, xprivs))
746 {Eroute.
Emsg(
"ConfigXeq",
"Invalid privs -", privs);
750 {
int plen = strlen(path);
751 char *decp = (
char *)alloca(plen+1);
753 currcap =
new XrdAccCapability(decp, xprivs);
754 }
else currcap =
new XrdAccCapability(path, xprivs);
756 lastcap->
Add(currcap);
767 {Eroute.
Emsg(
"ConfigXeq",
"no capabilities specified for", authid);
775 {
if (!(ncp =
new XrdAccCapName(authid, mycap.Next())))
776 {Eroute.
Emsg(
"ConfigXeq",
"unable to add id",authid);
return -1;}
783 else hp->
Add(authid, mycap.Next());
787 mycap.Add((XrdAccCapability *)0);
799 std::map<int, XrdAccAccess_ID *> idMap;
800 XrdAccAccess_ID *idPN, *xList = 0, *yList = 0;
806 {idPN = idList->
next;
807 if (idList->
caps == 0)
808 Eroute.
Say(
"Config ",
"Warning, unused identifier definition '",
810 else if (idList->
rule >= 0) idMap[idList->
rule] = idList;
811 else {idList->
next = yList; yList = idList;}
818 std::map<int,XrdAccAccess_ID *>::reverse_iterator rit;
819 for (rit = idMap.rbegin(); rit != idMap.rend(); ++rit)
820 {rit->second->next = xList;
838 XrdAccAccess_ID *xID, theID(idName);
839 char *idname, buff[80], idType;
840 bool haveID =
false, idDup =
false;
845 {
if (!(idType = Database->getID(&idname)))
break;
848 {
case 'g':
if (spChar) subSpace(idname);
849 if (theID.grp) idDup =
true;
850 else{theID.grp = strdup(idname);
851 theID.glen = strlen(idname);
854 case 'h':
if (theID.host) idDup =
true;
855 else{theID.host = strdup(idname);
856 theID.hlen = strlen(idname);
859 case 'o':
if (theID.org) idDup =
true;
860 else {
if (spChar) subSpace(idname);
861 theID.org = strdup(idname);
864 case 'r':
if (theID.role) idDup =
true;
865 else {
if (spChar) subSpace(idname);
866 theID.role = strdup(idname);
869 case 'u':
if (theID.user) idDup =
true;
870 else {
if (spChar) subSpace(idname);
871 theID.user = strdup(idname);
874 default: snprintf(buff,
sizeof(buff),
"'%c: %s' for",
876 Eroute.
Emsg(
"ConfigXeq",
"Invalid id selector -",
882 {snprintf(buff,
sizeof(buff),
883 "id selector '%c' specified twice for", idType);
884 Eroute.
Emsg(
"ConfigXeq", buff, theID.name);
892 {Eroute.
Emsg(
"ConfigXeq",
"No id selectors specified for", theID.name);
898 if (!tabs.
S_Hash) tabs.
S_Hash =
new XrdOucHash<XrdAccAccess_ID>;
900 {Eroute.
Emsg(
"ConfigXeq",
"duplicate id definition -",theID.name);
956 case Neg_Priv:
if (i)
return 0; i++;
break;
XrdAccConfig XrdAccConfiguration
XrdAccAuthDB * XrdAccAuthDBObject(XrdSysError *erp)
void * XrdAccConfig_Refresh(void *start_data)
void Add(XrdAccCapName *cnp)
XrdAccCapability * Find(const char *name)
void Add(XrdAccCapability *newcap)
XrdAccCapability * Next()
int Configure(XrdSysError &Eroute, const char *cfn)
XrdAccAccess * Authorization
int ConfigDB(int Warm, XrdSysError &Eroute)
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