30 int XrdProofdSandbox::fgMaxOldSessions = 10;
31 XrdOucString XrdProofdSandbox::fgWorkdir =
"";
32 XrdProofUI XrdProofdSandbox::fgUI;
47 XrdProofdSandbox::XrdProofdSandbox(XrdProofUI ui,
bool full,
bool changeown)
48 : fChangeOwn(changeown), fUI(ui)
50 XPDLOC(CMGR,
"XrdProofdSandbox")
56 XrdProofdAux::GetUserInfo(getuid(), fgUI);
59 XrdOucString defdir = fgUI.fHomeDir;
60 if (!defdir.endswith('/')) defdir += "/";
62 XrdOucString initus = ui.fUser[0];
64 if (fgWorkdir.length() > 0) {
67 if (fDir.find(
"<user>") == STR_NPOS) {
68 if (!fDir.endswith(
'/')) fDir +=
"/";
72 fDir.replace(
"<workdir>", defdir);
74 iph = fDir.find(
"<effuser>");
75 int iu = fDir.find(
"<u>");
76 int ius = fDir.find(
"<user>");
78 if ((iph != STR_NPOS && iu < iph) || (iph == STR_NPOS)) iph = iu;
80 if ((iph != STR_NPOS && ius < iph) || (iph == STR_NPOS)) iph = ius;
82 fDir.replace(
"<effuser>", fgUI.fUser);
83 fDir.replace(
"<u>", initus);
84 fDir.replace(
"<user>", ui.fUser);
86 if (changeown || ui.fUser == fgUI.fUser) {
89 if (!fDir.endswith(
'/'))
95 if (!fDir.endswith(
'/'))
101 TRACE(REQ,
"work dir = " << fDir);
106 XrdOucString path, sb;
107 path.assign(fDir, 0, iph - 1);
109 while ((from = fDir.tokenize(sb, from,
'/')) != -1) {
111 if (XrdProofdAux::AssertDir(path.c_str(), ui, changeown) == -1) {
112 fErrMsg +=
"unable to create work dir: ";
114 TRACE(XERR, fErrMsg);
120 if (XrdProofdAux::AssertDir(fDir.c_str(), ui, changeown) == -1) {
121 fErrMsg +=
"unable to create work dir: ";
123 TRACE(XERR, fErrMsg);
129 const char *basicdirs[4] = {
"/cache",
"/packages",
"/.creds",
"/queries" };
131 int n = (full) ? 4 : 3;
132 for (i = 0; i < n; i++) {
133 XrdOucString dir = fDir;
135 if (XrdProofdAux::AssertDir(dir.c_str(), ui, changeown) == -1) {
136 fErrMsg +=
"unable to create dir: ";
138 TRACE(XERR, fErrMsg);
153 bool XpdSessionTagComp(XrdOucString *&lhs, XrdOucString *&rhs)
159 XrdOucString ll(*lhs);
160 ll.erase(ll.rfind(
'-'));
161 ll.erase(0, ll.rfind(
'-')+1);
162 int tl = strtol(ll.c_str(), 0, 10);
165 XrdOucString rr(*rhs);
166 rr.erase(rr.rfind(
'-'));
167 rr.erase(0, rr.rfind(
'-')+1);
168 int tr = strtol(rr.c_str(), 0, 10);
171 return ((tl < tr) ? 0 : 1);
181 static void Sort(std::list<XrdOucString *> *lst)
192 XrdOucString **ta =
new XrdOucString *[lst->size()];
193 std::list<XrdOucString *>::iterator i;
195 for (i = lst->begin(); i != lst->end(); ++i)
199 XrdOucString *tmp = 0;
205 if (XpdSessionTagComp(ta[j], ta[j+1]))
213 XPDSWAP(ta[j], ta[j+1], tmp);
216 if (!XpdSessionTagComp(ta[k], ta[k-1])) {
217 XPDSWAP(ta[k], ta[k-1], tmp);
231 lst->push_back(ta[n]);
252 int XrdProofdSandbox::GetSessionDirs(
int opt, std::list<XrdOucString *> *sdirs,
255 XPDLOC(CMGR,
"Sandbox::GetSessionDirs")
258 opt = (opt >= 0 && opt <= 3) ? opt : 0;
261 if ((opt < 3 && !sdirs) || (opt == 3 && !tag)) {
262 TRACE(XERR,
"invalid inputs");
266 TRACE(DBG,
"opt: "<<opt<<
", dir: "<<fDir);
269 DIR *dir = opendir(fDir.c_str());
271 TRACE(XERR,
"cannot open dir "<<fDir<<
" (errno: "<<errno<<
")");
278 struct dirent *ent = 0;
279 while ((ent = (
struct dirent *)readdir(dir))) {
280 if (!strncmp(ent->d_name,
"session-", 8)) {
282 if (opt == 3 && tag->length() > 0) {
283 if (strstr(ent->d_name, tag->c_str())) {
289 XrdOucString fterm(fDir.c_str());
291 fterm += ent->d_name;
292 fterm +=
"/.terminated";
293 int rc = access(fterm.c_str(), F_OK);
294 if ((opt == 1 && rc == 0) || (opt == 2 && rc != 0))
298 TRACE(HDBG,
"found entry "<<ent->d_name<<
", keep: "<<keep);
300 sdirs->push_back(
new XrdOucString(ent->d_name));
310 sdirs->sort(&XpdSessionTagComp);
316 return ((opt == 3 && found) ? 1 : 0);
324 int XrdProofdSandbox::AddSession(
const char *tag)
326 XPDLOC(CMGR,
"Sandbox::AddSession")
330 XPDPRT(
"invalid input");
333 TRACE(DBG,
"tag:"<<tag);
335 XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
336 if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
337 TRACE(XERR,
"could not get privileges");
342 XrdOucString fn = fDir;
346 FILE *fact = fopen(fn.c_str(),
"a+");
348 TRACE(XERR,
"cannot open file "<<fn<<
" for appending (errno: "<<errno<<
")");
353 lseek(fileno(fact), 0, SEEK_SET);
354 if (lockf(fileno(fact), F_LOCK, 0) == -1) {
355 TRACE(XERR,
"cannot lock file "<<fn<<
" (errno: "<<errno<<
")");
363 std::list<XrdOucString *> actln;
365 while (fgets(ln,
sizeof(ln), fact)) {
367 if (ln[strlen(ln)-1] ==
'\n')
368 ln[strlen(ln)-1] =
'\0';
370 if (strlen(ln) <= 0 || ln[0] ==
'#')
379 lseek(fileno(fact), 0, SEEK_END);
380 fprintf(fact,
"%s\n", tag);
384 lseek(fileno(fact), 0, SEEK_SET);
385 if (lockf(fileno(fact), F_ULOCK, 0) == -1)
386 TRACE(XERR,
"cannot unlock file "<<fn<<
" (errno: "<<errno<<
")");
401 int XrdProofdSandbox::GuessTag(XrdOucString &tag,
int ridx)
403 XPDLOC(CMGR,
"Sandbox::GuessTag")
405 TRACE(DBG, "tag: "<<tag);
408 bool last = (tag == "last") ? 1 : 0;
410 if (!last && tag.length() > 0) {
412 XrdOucString fn = fDir;
416 FILE *fact = fopen(fn.c_str(),
"a+");
419 if (lockf(fileno(fact), F_LOCK, 0) == 0) {
422 while (fgets(ln,
sizeof(ln), fact)) {
424 if (ln[strlen(ln)-1] ==
'\n')
425 ln[strlen(ln)-1] =
'\0';
427 if (strlen(ln) <= 0 || ln[0] ==
'#')
430 if (!strstr(ln, tag.c_str())) {
437 lseek(fileno(fact), 0, SEEK_SET);
438 if (lockf(fileno(fact), F_ULOCK, 0) == -1)
439 TRACE(DBG,
"cannot unlock file "<<fn<<
" ; fact: "<<fact<<
440 ", fd: "<< fileno(fact) <<
" (errno: "<<errno<<
")");
443 TRACE(DBG,
"cannot lock file: "<<fn<<
" ; fact: "<<fact<<
444 ", fd: "<< fileno(fact) <<
" (errno: "<<errno<<
")");
450 TRACE(DBG,
"cannot open file "<<fn<<
451 " for reading (errno: "<<errno<<
")");
458 std::list<XrdOucString *> staglst;
460 int rc = GetSessionDirs(3, &staglst, &tag);
462 TRACE(XERR,
"cannot scan dir "<<fDir);
465 found = (rc == 1) ? 1 : 0;
467 if (!found && !staglst.empty()) {
470 tag = staglst.front()->c_str();
476 std::list<XrdOucString *>::iterator i;
477 for (i = staglst.begin(); i != staglst.end(); ++i) {
492 tag.replace(
"session-",
"");
494 TRACE(DBG,
"tag "<<tag<<
" not found in dir");
499 return ((found) ? 0 : -1);
508 int XrdProofdSandbox::RemoveSession(
const char *tag)
510 XPDLOC(CMGR,
"Sandbox::RemoveSession")
516 TRACE(XERR,
"invalid input");
519 TRACE(DBG,
"tag:"<<tag);
521 XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
522 if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
523 TRACE(XERR,
"could not get privileges");
528 XrdOucString fna = fDir;
532 FILE *fact = fopen(fna.c_str(),
"a+");
534 TRACE(XERR,
"cannot open file "<<fna<<
" (errno: "<<errno<<
")");
539 if (lockf(fileno(fact), F_LOCK, 0) == -1) {
540 TRACE(XERR,
"cannot lock file "<<fna<<
" (errno: "<<errno<<
")");
546 std::list<XrdOucString *> actln;
547 while (fgets(ln,
sizeof(ln), fact)) {
549 if (ln[strlen(ln)-1] ==
'\n')
550 ln[strlen(ln)-1] =
'\0';
552 if (strlen(ln) <= 0 || ln[0] ==
'#')
555 if (!strstr(ln, tag))
556 actln.push_back(
new XrdOucString(ln));
560 if (ftruncate(fileno(fact), 0) == -1) {
561 TRACE(XERR,
"cannot truncate file "<<fna<<
" (errno: "<<errno<<
")");
562 lseek(fileno(fact), 0, SEEK_SET);
563 if (lockf(fileno(fact), F_ULOCK, 0) != 0)
564 TRACE(XERR,
"cannot lockf file "<<fna<<
" (errno: "<<errno<<
")");
571 if (!actln.empty()) {
573 std::list<XrdOucString *>::iterator i;
574 for (i = actln.begin(); i != actln.end(); ++i) {
575 fprintf(fact,
"%s\n", (*i)->c_str());
581 lseek(fileno(fact), 0, SEEK_SET);
582 if (lockf(fileno(fact), F_ULOCK, 0) == -1)
583 TRACE(DBG,
"cannot unlock file "<<fna<<
" (errno: "<<errno<<
")");
590 if (unlink(fna.c_str()) == -1)
591 TRACE(DBG,
"cannot unlink file "<<fna<<
" (errno: "<<errno<<
")");
594 XrdOucString fterm = fDir;
595 fterm += (strstr(tag,
"session-")) ?
"/" :
"/session-";
597 fterm +=
"/.terminated";
599 FILE *ft = fopen(fterm.c_str(),
"w");
601 TRACE(XERR,
"cannot open file "<<fterm<<
" (errno: "<<errno<<
")");
617 int XrdProofdSandbox::TrimSessionDirs()
619 XPDLOC(CMGR,
"Sandbox::TrimSessionDirs")
621 TRACE(DBG, "maxold:"<<fgMaxOldSessions);
624 XrdOucString tobemv, fnact = fDir;
625 fnact += "/.sessions";
626 FILE *f = fopen(fnact.c_str(), "r");
629 while (fgets(ln,
sizeof(ln), f)) {
630 if (ln[strlen(ln)-1] ==
'\n')
631 ln[strlen(ln)-1] = 0;
632 char *p = strrchr(ln,
'-');
634 int pid = strtol(p+1, 0, 10);
635 if (!XrdProofdAux::VerifyProcessByID(pid)) {
644 XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
645 if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
646 TRACE(XERR,
"could not get privileges to trim directories");
651 if (tobemv.length() > 0) {
655 while ((from = tobemv.tokenize(tag, from, del)) != -1) {
656 if (RemoveSession(tag.c_str()) == -1)
657 TRACE(XERR,
"problems tagging session as old in sandbox");
662 if (fgMaxOldSessions > 0) {
665 std::list<XrdOucString *> staglst;
667 if (GetSessionDirs(2, &staglst) != 0) {
668 TRACE(XERR,
"cannot get list of dirs ");
671 TRACE(DBG,
"number of working dirs: "<<staglst.size());
674 std::list<XrdOucString *>::iterator i;
675 for (i = staglst.begin(); i != staglst.end(); ++i) {
676 TRACE(HDBG,
"found "<<(*i)->c_str());
681 while ((
int)staglst.size() > fgMaxOldSessions) {
682 XrdOucString *s = staglst.back();
684 TRACE(HDBG,
"removing "<<s->c_str());
686 XrdOucString rmcmd =
"/bin/rm -rf ";
690 if (system(rmcmd.c_str()) == -1)
691 TRACE(XERR,
"cannot invoke system("<<rmcmd<<
") (errno: "<<errno<<
")");