38 #include <sys/param.h>
40 #include <sys/types.h>
60 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(cFile);
79 struct pTV {
const char *pfx;
88 static const int pNum = 4;
106 char buff[4096], *afile, *var;
114 if (!(var = getenv(
"XRDADMINPATH")) || (n = strlen(var)) >= MAXPATHLEN)
115 {
eDest->
Emsg(
"Config",
"Unable to deterine adminpath!");
122 if (buff[n-1] !=
'/') {buff[n] =
'/'; n++;}
123 strcpy(buff+n,
".xrd/=/%s");
124 fnTmplt = strdup(buff);
129 if (snprintf(buff,
sizeof(buff), fnTmplt,
"conf/etc") < (
int)
sizeof(buff))
134 if(!parms || !*parms)
135 {
eDest->
Emsg(
"Config",
"DigFS parameters not specified.");
142 if (n >= (
int)
sizeof(buff))
143 {
eDest->
Emsg(
"Config",
"DigFS parm string is too long.");
151 if (!(afile = cParms.
GetToken()) || !afile[0])
152 {
eDest->
Emsg(
"Config",
"DigFS authfile not specified.");
158 if (cFN && *cFN) isOK = ConfigProc(cFN);
171 stat(
"/", &rootStat);
175 for (n = 0; n < pNum; n++)
176 {sprintf(buff, fnTmplt, pTab[n].pfx);
177 pTab[n].isOK =
stat(buff, &
Stat) == 0;
199 if (aMax < 1)
return -1;
207 for (i = (
int)
sizeof(aOK)-1; i >= 0 && n < aMax; i--)
209 if (aOK[i] && pTab[i].isOK) aList[n++] = pTab[i].pfx;
214 if (!hasAcc)
return -1;
218 if (!n) {aList[0] =
"."; n = 1;}
237 if (!client) {rc = EPERM;
return 0;}
241 for (i = 0; i < pNum; i++)
242 {
if (!strncmp(pTab[i].pfx, fname, pTab[i].pfxlen)
243 && (*(fname+pTab[i].pfxlen) ==
'/' || !*(fname+pTab[i].pfxlen)))
break;
248 if (i >= pNum || !pTab[i].isOK) {rc = ENOENT;
return 0;}
253 {
if (lfnType == isFile && logRej) Audit(client,
"denied", opname, fname);
262 {
if (logRej && rc == EPERM) Audit(client,
"denied", opname, fname);
268 if (lfnType == isFile && logAcc) Audit(client,
"allowed", opname, fname);
272 i = (lfnType == isDir ? 1 : 0);
273 n = snprintf(path,
sizeof(path), fnTmplt, fname);
274 if (n >= (
int)
sizeof(path)-1) {rc = ENAMETOOLONG;
return 0;}
278 if (lfnType == isDir && path[n-1] !=
'/') {path[n] =
'/'; path[n+1] = 0;}
308 memcpy(sP, &rootStat,
sizeof(
struct stat));
319 const char *tpd,
const char *tfn)
322 char *pP, tBuff[MAXPATHLEN], pBuff[MAXPATHLEN], nBuff[MAXNAMELEN];
327 if (*src !=
'/' || *(src+1) == 0)
return "not absolute path";
332 {
case isFile:
if (!S_ISREG(
Stat.st_mode))
return "not a file";
334 case isDir:
if (!S_ISDIR(
Stat.st_mode))
return "not a directory";
342 {
const char *tbeg = (strncmp(src,
"/etc/", 5) ? src+1 : src+5);
344 while(strlen(tbeg) >=
sizeof(nBuff)/2 && (tfn = index(tbeg,
'/')))
346 if (!tfn) tfn = rindex(src,
'/')+1;
347 else {strcpy(nBuff, tbeg); tfn = pP = nBuff;
348 while((pP = index(pP,
'/'))) *pP++ =
'.';
351 if (!(*tfn))
return "invalid derived target name";
355 if (snprintf(tBuff,
sizeof(tBuff),
"%s%s", tpd, tfn) > (
int)
sizeof(tBuff))
356 return "target name too long";
357 if (snprintf(pBuff,
sizeof(pBuff), fnTmplt, tBuff) > (
int)
sizeof(pBuff))
358 return "target path too long";
370 void XrdDigConfig::Audit(
const XrdSecEntity *client,
const char *what,
371 const char *opn,
const char *trg)
373 const char *name = (client->
name ? client->
name :
"anon");
374 char hbuff[512], buff[1024];
383 snprintf(buff,
sizeof(buff),
"%s@%s %s", name, hbuff, what);
391 bool XrdDigConfig::ConfigProc(
const char *ConfigFN)
394 int cfgFD, retc, NoGo = 0;
400 if ( (cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
401 {
eDest->
Emsg(
"Config", errno,
"open config file", ConfigFN);
405 static const char *cvec[] = {
"*** digfs plugin config:", 0 };
410 while((var = cFile.GetMyFirstWord()))
411 {
if (!strncmp(var,
"dig.", 4))
412 if (!ConfigXeq(var+4, cFile)) {cFile.Echo(); NoGo = 1;}
417 if ((retc = cFile.LastError()))
418 NoGo =
eDest->
Emsg(
"Config", retc,
"read config file", ConfigFN);
430 bool XrdDigConfig::ConfigXeq(
char *var,
XrdOucStream &cFile)
444 void XrdDigConfig::Empty(
const char *path)
448 char pBuff[MAXPATHLEN+8], *pB;
453 if ((n = snprintf(pBuff,
sizeof(pBuff),
"%s/",path)) >= (
int)
sizeof(pBuff))
455 bLeft =
sizeof(pBuff) - n - 1;
460 if (!(dh =
opendir(path)))
return;
465 {
if (bLeft > (
int)strlen(dP->d_name))
466 {strcpy(pB, dP->d_name);
480 void XrdDigConfig::SetLocResp()
484 char *pP, buff[512], *bp = buff+2;
485 int myPort, bsz =
sizeof(buff)-2;
490 myPort = (pP = getenv(
"XRDPORT")) ? strtol(pP, (
char **)NULL, 10) : 0;
497 locRespHP = strdup(buff); locRlenHP = strlen(buff)+1;
502 locRespV6 = locRespV4 = strdup(buff); locRlenV6 = locRlenV4 = strlen(buff)+1;
513 locRespV4 = strdup(buff); locRlenV4 = strlen(buff)+1;
523 int XrdDigConfig::ValProc(
const char *path)
526 char *Slash, cpath[1040], ppath[1040];
531 n = snprintf(ppath,
sizeof(ppath),
"%s", path);
532 if (n >= (
int)
sizeof(ppath)-2)
return ENAMETOOLONG;
533 if (ppath[n-1] !=
'/') {ppath[n] =
'/'; ppath[n+1] = 0;}
537 if (!(Slash = index(ppath,
'/')) || !(Slash = index(Slash+1,
'/'))
538 || !(Slash = index(Slash+1,
'/')))
return 0;
544 n = snprintf(cpath,
sizeof(cpath), fnTmplt, ppath);
545 if (n >= (
int)
sizeof(cpath))
return ENAMETOOLONG;
547 if (!S_ISDIR(
Stat.st_mode) && !S_ISREG(
Stat.st_mode))
return EPERM;
549 Slash = index(Slash+1,
'/');
575 char *val, src[MAXPATHLEN+8];
579 if (!(val = cFile.
GetWord()) || !val[0])
580 {
eDest->
Emsg(
"Config",
"addconf path not specified.");
return false;}
584 if (strlen(val) >=
sizeof(src))
585 {
eDest->
Emsg(
"Config",
"addconf path is too long.");
return false;}
590 if (!(val = cFile.
GetWord()) || !val[0]) val = 0;
591 else {
if (index(val,
'/'))
592 {
eDest->
Emsg(
"Config",
"invalid addconf fname -", val);
599 if ((eTxt = AddPath(isFile, src,
"conf/etc/", val)))
601 snprintf(eBuff,
sizeof(eBuff),
"- %s", eTxt);
602 eDest->
Emsg(
"Config",
"Unable to addconf" , src, eBuff);
633 if (!(val = cFile.
GetWord()) || !val[0])
634 {
eDest->
Emsg(
"Config",
"log parameter not specified");
return false;}
638 logAcc = logRej =
false;
639 do {
if (!strcmp(
"grant", val)) logAcc =
true;
640 else if (!strcmp(
"deny", val)) logRej =
true;
641 else if (!strcmp(
"none", val)) logRej = logAcc =
false;
642 else {
eDest->
Emsg(
"Config",
"invalid log option -",val);
return false;}
644 }
while(val && *val);
int stat(const char *path, struct stat *buf)
struct dirent * readdir(DIR *dirp)
int open(const char *path, int oflag,...)
int fstat(int fildes, struct stat *buf)
int lstat(const char *path, struct stat *buf)
int unlink(const char *path)
int rmdir(const char *path)
DIR * opendir(const char *path)
const char * XrdSysE2T(int errcode)
bool Authorize(const XrdSecEntity *client, XrdDigAuthEnt::aType aType, bool aVec[XrdDigAuthEnt::aNum]=0)
bool Configure(const char *aFN)
int GenAccess(const XrdSecEntity *client, const char *aList[], int aMax)
char * GenPath(int &rc, const XrdSecEntity *client, const char *opname, const char *lfn, pType lfnType=isAny)
static void StatRoot(struct stat *sP)
void GetLocResp(XrdOucErrInfo &eInfo, bool nameok)
bool Configure(const char *cFN, const char *parms)
static const int noPort
Do not add port number.
static const int old6Map4
Use deprecated IPV6 mapped format.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
@ fmtName
Hostname if it is resolvable o/w use fmtAddr.
static const char * GetAddrs(const char *hSpec, XrdNetAddr *aListP[], int &aListN, AddrOpts opts=allIPMap, int pNum=PortInSpec)
int setErrInfo(int code, const char *emsg)
char * GetWord(int lowcase=0)
char * GetToken(char **rest=0, int lowcase=0)
static int ReLink(const char *path, const char *target, mode_t mode=0)
XrdNetAddrInfo * addrInfo
Entity's connection details.
const char * tident
Trace identifier always preset.
char * name
Entity's name.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
static const int uIPv4
ucap: Supports read redirects