24 #if ROOTXRDVERS < ROOT_OldXrdOuc
25 # define XPD_LOG_01 OUC_LOG_01
27 # define XPD_LOG_01 SYS_LOG_01
32 #include "Xrd/XrdBuffer.hh"
34 #include "XrdNet/XrdNetAddrInfo.hh"
36 #include "XrdOuc/XrdOucErrInfo.hh"
37 #include "XrdOuc/XrdOucStream.hh"
38 #include "XrdSec/XrdSecInterface.hh"
39 #include "XrdSys/XrdSysPlugin.hh"
53 static XpdManagerCron_t fManagerCron;
56 typedef XrdSecService *(*XrdSecServLoader_t)(XrdSysLogger *,
const char *cfn);
68 void *XrdProofdClientCron(
void *p)
70 XPDLOC(CMGR,
"ClientCron")
72 XpdManagerCron_t *mc = (XpdManagerCron_t *)p;
73 XrdProofdClientMgr *mgr = mc->fClientMgr;
75 TRACE(REQ,
"undefined client manager: cannot start");
78 XrdProofdProofServMgr *smgr = mc->fSessionMgr;
80 TRACE(REQ,
"undefined session manager: cannot start");
85 int lastcheck = time(0), ckfreq = mgr->CheckFrequency(), deltat = 0;
88 if ((deltat = ckfreq - (time(0) - lastcheck)) <= 0)
90 int pollRet = mgr->Pipe()->Poll(deltat);
96 if ((rc = mgr->Pipe()->Recv(msg)) != 0) {
97 XPDERR(
"problems receiving message; errno: "<<-rc);
102 if (msg.Type() == XrdProofdClientMgr::kClientDisconnect) {
104 TRACE(XERR,
"obsolete type: XrdProofdClientMgr::kClientDisconnect");
106 TRACE(XERR,
"unknown type: "<<msg.Type());
124 XrdProofdClientMgr::XrdProofdClientMgr(XrdProofdManager *mgr,
125 XrdProtocol_Config *pi, XrdSysError *e)
126 : XrdProofdConfig(pi->ConfigFN, e), fSecPlugin(0)
128 XPDLOC(CMGR,
"XrdProofdClientMgr")
130 fMutex = new XrdSysRecMutex;
134 fReconnectTimeOut = 300;
136 fActivityTimeOut = 1200;
137 fCheckFrequency = 60;
140 if (!fPipe.IsValid()) {
141 TRACE(XERR,
"unable to generate the pipe");
146 RegisterDirectives();
152 void XrdProofdClientMgr::RegisterDirectives()
154 Register(
"clientmgr",
new XrdProofdDirective(
"clientmgr",
this, &DoDirectiveClass));
155 Register(
"seclib",
new XrdProofdDirective(
"seclib",
156 (
void *)&fSecLib, &DoDirectiveString, 0));
157 Register(
"reconnto",
new XrdProofdDirective(
"reconnto",
158 (
void *)&fReconnectTimeOut, &DoDirectiveInt));
164 int XrdProofdClientMgr::DoDirective(XrdProofdDirective *d,
165 char *val, XrdOucStream *cfg,
bool rcf)
167 XPDLOC(SMGR,
"ClientMgr::DoDirective")
173 if (d->fName == "clientmgr") {
174 return DoDirectiveClientMgr(val, cfg, rcf);
176 TRACE(XERR,
"unknown directive: "<<d->fName);
184 int XrdProofdClientMgr::DoDirectiveClientMgr(
char *val, XrdOucStream *cfg,
bool)
186 XPDLOC(SMGR,
"ClientMgr::DoDirectiveClientMgr")
196 XrdOucString tok(val);
197 if (tok.beginswith(
"checkfq:")) {
198 tok.replace(
"checkfq:",
"");
199 checkfq = strtol(tok.c_str(), 0, 10);
200 }
else if (tok.beginswith(
"activityto:")) {
201 tok.replace(
"activityto:",
"");
202 activityto = strtol(tok.c_str(), 0, 10);
205 val = cfg->GetWord();
209 if (fMgr->Host() && cfg)
210 if (XrdProofdAux::CheckIf(cfg, fMgr->Host()) == 0)
214 fCheckFrequency = (XPD_LONGOK(checkfq) && checkfq > 0) ? checkfq : fCheckFrequency;
215 fActivityTimeOut = (XPD_LONGOK(activityto) && activityto > 0) ? activityto : fActivityTimeOut;
218 XPDFORM(msg,
"checkfq: %d s, activityto: %d s", fCheckFrequency, fActivityTimeOut);
228 int XrdProofdClientMgr::Config(
bool rcf)
230 XPDLOC(CMGR,
"ClientMgr::Config")
233 if (XrdProofdConfig::Config(rcf) != 0) {
234 XPDERR(
"problems parsing file ");
239 msg = (rcf) ?
"re-configuring" :
"configuring";
240 TRACE(ALL, msg.c_str());
243 fClntAdminPath = fMgr->AdminPath();
244 fClntAdminPath +=
"/clients";
248 XrdProofdAux::GetUserInfo(fMgr->EffectiveUser(), ui);
249 if (XrdProofdAux::AssertDir(fClntAdminPath.c_str(), ui, 1) != 0) {
250 XPDERR(
"unable to assert the clients admin path: "<<fClntAdminPath);
254 TRACE(ALL,
"clients admin path set to: "<<fClntAdminPath);
257 if (ParsePreviousClients(msg) != 0) {
258 XPDERR(
"problems parsing previous active clients: "<<msg);
263 if (fSecLib.length() <= 0) {
264 TRACE(ALL,
"XRD seclib not specified; strong authentication disabled");
266 if (!(fCIA = LoadSecurity())) {
267 XPDERR(
"unable to load security system.");
270 TRACE(ALL,
"security library loaded");
276 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
277 std::list<XrdProofdClient *>::iterator pci;
278 for (pci = fProofdClients.begin(); pci != fProofdClients.end(); ++pci)
279 (*pci)->SetGroup(fMgr->GroupsMgr()->GetUserGroup((*pci)->User())->Name());
287 fManagerCron.fClientMgr =
this;
288 fManagerCron.fSessionMgr = fMgr->SessionMgr();
289 if (XrdSysThread::Run(&tid, XrdProofdClientCron,
290 (
void *)&fManagerCron, 0,
"ClientMgr cron thread") != 0) {
291 XPDERR(
"could not start cron thread");
294 TRACE(ALL,
"cron thread started");
304 int XrdProofdClientMgr::Login(XrdProofdProtocol *p)
306 XPDLOC(CMGR,
"ClientMgr::Login")
309 XPD_SETRESP(p, "Login");
311 TRACEP(p, HDBG, "enter");
315 if (p->Request()->login.role[0] != 'i' &&
316 (fMgr->SrvType() == kXPD_MasterWorker || fMgr->SrvType() == kXPD_Master)) {
317 if (!fMgr->CheckMaster(p->Link()->Host())) {
318 TRACEP(p, XERR,
"master not allowed to connect - "
319 "ignoring request ("<<p->Link()->Host()<<
")");
320 response->Send(kXR_InvalidRequest,
321 "master not allowed to connect - request ignored");
328 XrdOucString uname, gname, emsg;
331 if (p->Status() == XPD_NEED_MAP) {
339 if ((rccc = CheckClient(p, 0, emsg)) != 0) {
340 TRACEP(p, XERR, emsg);
341 XErrorCode rcode = (rccc == -2) ? (XErrorCode) kXR_NotAuthorized
342 : (XErrorCode) kXR_InvalidRequest;
343 response->Send(rcode, emsg.c_str());
344 response->Send(kXR_InvalidRequest, emsg.c_str());
350 p->SetStatus(XPD_LOGGEDIN);
351 return MapClient(p, 0);
355 if ((p->Status() & XPD_LOGGEDIN)) {
356 response->Send(kXR_InvalidRequest,
"duplicate login; already logged in");
360 TRACE(ALL,
" hostname: '"<<p->Link()->Host()<<
"'");
363 bool anyserver = (fMgr->SrvType() == kXPD_AnyServer ||
364 !strcmp(p->Link()->Host(),
"localhost") ||
365 !strcmp(p->Link()->Host(),
"127.0.0.0")) ? 1 : 0;
369 bool ismaster = (fMgr->SrvType() == kXPD_TopMaster || fMgr->SrvType() == kXPD_Master) ? 1 : 0;
370 switch (p->Request()->login.role[0]) {
372 p->SetConnType(kXPD_Admin);
373 response->SetTag(
"adm");
376 p->SetConnType(kXPD_Internal);
377 response->SetTag(
"int");
380 if (anyserver || ismaster) {
381 p->SetConnType(kXPD_ClientMaster);
383 response->SetTag(
"m2c");
385 TRACEP(p, XERR,
"top master mode not allowed - ignoring request");
386 response->Send(kXR_InvalidRequest,
387 "Server not allowed to be top master - ignoring request");
392 if (anyserver || ismaster) {
393 p->SetConnType(kXPD_MasterMaster);
395 response->SetTag(
"m2m");
397 TRACEP(p, XERR,
"submaster mode not allowed - ignoring request");
398 response->Send(kXR_InvalidRequest,
399 "Server not allowed to be submaster - ignoring request");
404 if (fMgr->SrvType() == kXPD_AnyServer || fMgr->RemotePLite()) {
405 p->SetConnType(kXPD_MasterMaster);
407 response->SetTag(
"m2l");
408 p->Request()->login.role[0] =
'm';
410 TRACEP(p, XERR,
"PLite submaster mode not allowed - ignoring request");
411 response->Send(kXR_InvalidRequest,
412 "Server not allowed to be PLite submaster - ignoring request");
417 if (anyserver || fMgr->SrvType() == kXPD_MasterWorker) {
418 p->SetConnType(kXPD_MasterWorker);
420 response->SetTag(
"w2m");
422 TRACEP(p, XERR,
"worker mode not allowed - ignoring request");
423 response->Send(kXR_InvalidRequest,
424 "Server not allowed to be worker - ignoring request");
429 TRACEP(p, XERR,
"unknown mode: '" << p->Request()->login.role[0] <<
"'");
430 response->Send(kXR_InvalidRequest,
"Server type: invalide mode");
433 response->SetTraceID();
436 pid = (int)ntohl(p->Request()->login.pid);
441 for (i = 0; i < (int)
sizeof(un)-1; i++) {
442 if (p->Request()->login.username[i] ==
'\0' || p->Request()->login.username[i] ==
' ')
444 un[i] = p->Request()->login.username[i];
450 if (uname ==
"?>buf") {
452 char *buf = p->Argp()->buff;
453 int len = p->Request()->login.dlen;
455 uname.assign(buf,0,len-1);
456 int iusr = uname.find(
"|usr:");
458 TRACEP(p, XERR,
"long user name not found");
459 response->Send(kXR_InvalidRequest,
"long user name not found");
462 uname.erase(0,iusr+5);
463 uname.erase(uname.find(
"|"));
467 int ig = uname.find(
":");
469 gname.assign(uname, ig+1);
471 TRACEP(p, DBG,
"requested group: "<<gname);
473 p->SetGroupIn(gname.c_str());
477 p->SetUserIn(uname.c_str());
480 p->Link()->setID(uname.c_str(), pid);
482 response->SetTraceID();
483 p->SetClntCapVer(p->Request()->login.capver[0]);
488 if (needauth && fCIA) {
490 const char *pp = fCIA->getParms(i, (XrdNetAddrInfo *) p->Link()->NetAddr());
492 const char *pp = fCIA->getParms(i, p->Link()->Name());
495 response->SendI((kXR_int32)XPROOFD_VERSBIN, (
void *)pp, i);
496 p->SetStatus((XPD_NEED_MAP | XPD_NEED_AUTH));
505 if ((rccc = CheckClient(p, p->UserIn(), emsg)) != 0) {
506 TRACEP(p, XERR, emsg);
507 XErrorCode rcode = (rccc == -2) ? (XErrorCode) kXR_NotAuthorized
508 : (XErrorCode) kXR_InvalidRequest;
509 response->Send(rcode, emsg.c_str());
512 rc = response->SendI((kXR_int32)XPROOFD_VERSBIN);
513 p->SetStatus(XPD_LOGGEDIN);
516 return MapClient(p, 1);
524 int XrdProofdClientMgr::CheckClient(XrdProofdProtocol *p,
525 const char *user, XrdOucString &emsg)
527 XPDLOC(CMGR,
"ClientMgr::CheckClient")
530 emsg =
"protocol object undefined!";
534 XrdOucString uname(user), gname(p->GroupIn());
536 if (p && p->AuthProt() && strlen(p->AuthProt()->Entity.name) > 0) {
537 uname = p->AuthProt()->Entity.name;
539 emsg =
"username not passed and not available in the protocol security entity - failing";
545 XrdProofGroup *g = 0;
546 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
547 if (gname.length() > 0) {
548 g = fMgr->GroupsMgr()->GetGroup(gname.c_str());
550 XPDFORM(emsg,
"group unknown: %s", gname.c_str());
552 }
else if (strncmp(g->Name(),
"default",7) &&
553 !g->HasMember(uname.c_str())) {
554 XPDFORM(emsg,
"user %s is not member of group %s", uname.c_str(), gname.c_str());
558 TRACEP(p, DBG,
"group: "<<gname<<
" found");
563 g = fMgr->GroupsMgr()->GetUserGroup(uname.c_str());
564 gname = g ? g->Name() :
"default";
572 if (fMgr->CheckUser(uname.c_str(), gname.c_str(), ui, emsg, su) != 0) {
573 if (emsg.length() <= 0)
574 XPDFORM(emsg,
"Controlled access: user '%s', group '%s' not allowed to connect",
575 uname.c_str(), gname.c_str());
581 TRACEP(p, DBG,
"request from entity: "<<uname<<
":"<<gname<<
" (privileged)");
583 TRACEP(p, DBG,
"request from entity: "<<uname<<
":"<<gname);
588 XrdProofdClient *c = GetClient(uname.c_str(), gname.c_str());
591 c->SetROOT(fMgr->ROOTMgr()->DefaultVersion());
594 c->SetGroup(gname.c_str());
597 emsg =
"unable to instantiate object for client ";
611 int XrdProofdClientMgr::MapClient(XrdProofdProtocol *p,
bool all)
613 XPDLOC(CMGR,
"ClientMgr::MapClient")
616 XPD_SETRESP(p, "MapClient");
620 TRACEP(p, HDBG, "all: "<< all);
623 XrdProofdClient *pc = p->Client();
626 if (!pc || !pc->IsValid()) {
629 XrdSysMutexHelper mh(fMutex);
630 fProofdClients.remove(pc);
635 TRACEP(p, DBG,
"cannot find valid instance of XrdProofdClient");
636 response->Send(kXP_ServerError,
637 "MapClient: cannot find valid instance of XrdProofdClient");
642 bool proofsrv = ((p->ConnType() == kXPD_Internal) && all) ? 1 : 0;
647 short int clientvers = -1;
649 memcpy(&psid, (
const void *)&(p->Request()->login.reserved[0]), 2);
651 TRACEP(p, XERR,
"proofsrv callback: sent invalid session id");
652 response->Send(kXR_InvalidRequest,
653 "MapClient: proofsrv callback: sent invalid session id");
656 protver = p->Request()->login.capver[0];
657 TRACEP(p, DBG,
"proofsrv callback for session: " <<psid);
660 memcpy(&clientvers, (
const void *)&(p->Request()->login.reserved[0]), 2);
661 TRACEP(p, DBG,
"PROOF version run by client: " <<clientvers);
666 XrdProofdProofServ *psrv = pc->GetServer(psid);
668 TRACEP(p, XERR,
"proofsrv callback: wrong target session: "<<psid<<
" : protocol error");
669 response->Send(kXP_nosession,
"MapClient: proofsrv callback:"
670 " wrong target session: protocol error");
674 psrv->SetProtVer(protver);
676 XrdProofdResponse *resp = p->Response(1);
678 TRACEP(p, XERR,
"proofsrv callback: could not get XrdProofdResponse object");
679 response->Send(kXP_nosession,
"MapClient: proofsrv callback: memory issue?");
682 psrv->SetConnection(resp);
686 XPDFORM(tid,
"xrd->%s", psrv->Ordinal());
687 resp->SetTag(tid.c_str());
689 TRACEI(resp->TraceID(), DBG,
"proofsrv callback: link assigned to target session "<<psid);
694 XrdSysMutexHelper mhc(pc->Mutex());
698 p->SetProofProtocol(clientvers);
703 if ((cid = CheckAdminPath(p, cpath, msg)) >= 0) {
705 pc->SetClientID(cid, p);
709 XrdOucString discpath(cpath, 0, cpath.rfind(
"/cid"));
710 discpath +=
"/disconnected";
711 if (unlink(discpath.c_str()) != 0) {
712 XPDFORM(msg,
"warning: could not remove %s (errno: %d)", discpath.c_str(), errno);
713 TRACEP(p, XERR, msg.c_str());
716 if(fNDisconnected) fNDisconnected--;
720 p->SetCID(pc->GetClientID(p));
722 if (CreateAdminPath(p, cpath, msg) != 0) {
723 TRACEP(p, XERR, msg.c_str());
724 fProofdClients.remove(pc);
727 response->Send(kXP_ServerError, msg.c_str());
731 p->SetAdminPath(cpath.c_str());
732 XPDFORM(msg,
"client ID and admin paths created: %s", cpath.c_str());
733 TRACEP(p, DBG, msg.c_str());
735 TRACEP(p, DBG,
"CID: "<<p->CID()<<
", size: "<<pc->Size());
739 if (!(p->Status() & XPD_NEED_AUTH)) {
740 const char *srvtype[6] = {
"ANY",
"MasterWorker",
"MasterMaster",
741 "ClientMaster",
"Internal",
"Admin"};
742 XPDFORM(msg,
"user %s logged-in%s; type: %s", pc->User(),
743 p->SuperUser() ?
" (privileged)" :
"", srvtype[p->ConnType()+1]);
744 TRACEP(p, LOGIN, msg);
754 int XrdProofdClientMgr::CreateAdminPath(XrdProofdProtocol *p,
755 XrdOucString &cpath, XrdOucString &emsg)
757 if (!p || !p->Link()) {
758 XPDFORM(emsg,
"invalid inputs (p: %p)", p);
764 XPDFORM(lid,
"%s.%d", p->Link()->Host(), p->Pid());
767 XPDFORM(cpath,
"%s/%s", p->Client()->AdminPath(), lid.c_str());
769 XrdProofdAux::GetUserInfo(fMgr->EffectiveUser(), ui);
770 if (XrdProofdAux::AssertDir(cpath.c_str(), ui, 1) != 0) {
771 XPDFORM(emsg,
"error creating client admin path: %s", cpath.c_str());
776 FILE *fcid = fopen(cpath.c_str(),
"w");
778 fprintf(fcid,
"%d", p->CID());
781 XPDFORM(emsg,
"error creating file for client id: %s", cpath.c_str());
792 int XrdProofdClientMgr::CheckAdminPath(XrdProofdProtocol *p,
793 XrdOucString &cidpath, XrdOucString &emsg)
797 XPDFORM(emsg,
"CheckAdminPath: invalid inputs (p: %p)", p);
803 XPDFORM(lid,
"%s.%d", p->Link()->Host(), p->Pid());
806 XPDFORM(cidpath,
"%s/%s/cid", p->Client()->AdminPath(), lid.c_str());
809 XrdOucString discpath;
810 XPDFORM(discpath,
"%s/%s/disconnected", p->Client()->AdminPath(), lid.c_str());
813 bool expired =
false;
815 int rc = stat(discpath.c_str(), &st);
816 if (rc != 0) rc = stat(cidpath.c_str(), &st);
817 if (rc != 0 || (expired = ((
int)(time(0) - st.st_atime) > fReconnectTimeOut))) {
818 if (expired || (rc != 0 && errno != ENOENT)) {
820 cidpath.replace(
"/cid",
"");
822 XPDFORM(emsg,
"CheckAdminPath: reconnection timeout expired: remove %s ",
825 XPDFORM(emsg,
"CheckAdminPath: problems stat'ing %s (errno: %d): remove ",
826 cidpath.c_str(), errno);
827 if (XrdProofdAux::RmDir(cidpath.c_str()) != 0)
828 emsg +=
": failure!";
830 XPDFORM(emsg,
"CheckAdminPath: no such file %s", cidpath.c_str());
836 return XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg);
842 int XrdProofdClientMgr::ParsePreviousClients(XrdOucString &emsg)
844 XPDLOC(CMGR,
"ClientMgr::ParsePreviousClients")
849 DIR *dir = opendir(fClntAdminPath.c_str());
851 TRACE(XERR,
"cannot open dir "<<fClntAdminPath<<
" ; error: "<<errno);
854 TRACE(DBG,
"creating holders for active clients ...");
857 XrdOucString usrpath, cidpath, discpath, usr, grp;
858 struct dirent *ent = 0;
859 while ((ent = (
struct dirent *)readdir(dir))) {
861 if (!strcmp(ent->d_name,
".") || !strcmp(ent->d_name,
".."))
continue;
862 XPDFORM(usrpath,
"%s/%s", fClntAdminPath.c_str(), ent->d_name);
865 if (stat(usrpath.c_str(), &st) == 0) {
868 usr.erase(usr.find(
'.'));
869 grp.erase(0, grp.find(
'.')+1);
870 TRACE(DBG,
"found usr: "<<usr<<
", grp: "<<grp);
872 XrdProofdClient *c = GetClient(usr.c_str(), grp.c_str());
874 XPDFORM(emsg,
"ParsePreviousClients: could not get client instance"
875 " for {%s, %s}", usr.c_str(), grp.c_str());
880 if (!rm && !(subdir = opendir(usrpath.c_str()))) {
881 TRACE(XERR,
"cannot open dir "<<usrpath<<
" ; error: "<<errno);
886 struct dirent *sent = 0;
887 while ((sent = (
struct dirent *)readdir(subdir))) {
889 if (!strcmp(sent->d_name,
".") || !strcmp(sent->d_name,
".."))
continue;
890 if (!strcmp(sent->d_name,
"xpdsock"))
continue;
891 XPDFORM(cidpath,
"%s/%s/cid", usrpath.c_str(), sent->d_name);
893 if (stat(cidpath.c_str(), &st) != 0 ||
894 (
int)(time(0) - st.st_atime) > fReconnectTimeOut) {
898 int cid = (!xrm) ? XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg) : -1;
902 if (!xrm && c->ReserveClientID(cid) != 0)
906 XPDFORM(discpath,
"%s/%s/disconnected", usrpath.c_str(), sent->d_name);
907 FILE *fd = fopen(discpath.c_str(),
"w");
909 TRACE(XERR,
"unable to create path: " <<discpath);
919 TRACE(DBG,
"removing path: " <<cidpath);
920 cidpath.replace(
"/cid",
"");
921 XPDFORM(emsg,
"ParsePreviousClients: failure: remove %s ", cidpath.c_str());
922 if (XrdProofdAux::RmDir(cidpath.c_str()) != 0)
923 emsg +=
": failure!";
934 TRACE(DBG,
"removing path: " <<usrpath);
935 XPDFORM(emsg,
"ParsePreviousClients: failure: remove %s ", usrpath.c_str());
936 if (XrdProofdAux::RmDir(usrpath.c_str()) != 0)
937 emsg +=
": failure!";
944 TRACE(DBG,
"found "<<fNDisconnected<<
" active clients");
953 int XrdProofdClientMgr::CheckClients()
955 XPDLOC(CMGR,
"ClientMgr::CheckClients")
958 DIR *dir = opendir(fClntAdminPath.c_str());
960 TRACE(XERR,
"cannot open dir "<<fClntAdminPath<<
" ; error: "<<errno);
963 TRACE(REQ,
"checking active clients ...");
967 XrdOucString usrpath, cidpath, discpath;
968 struct dirent *ent = 0;
969 while ((ent = (
struct dirent *)readdir(dir))) {
971 if (!strcmp(ent->d_name,
".") || !strcmp(ent->d_name,
".."))
continue;
972 XPDFORM(usrpath,
"%s/%s", fClntAdminPath.c_str(), ent->d_name);
974 XrdProofdClient *c = 0;
976 if (stat(usrpath.c_str(), &xst) == 0) {
978 XrdOucString usr, grp;
979 XrdProofdAux::ParseUsrGrp(ent->d_name, usr, grp);
980 if (!(c = GetClient(usr.c_str(), grp.c_str(), 0))) {
981 TRACE(XERR,
"instance for client "<<ent->d_name<<
" not found!");
986 if (!rm && !(subdir = opendir(usrpath.c_str()))) {
987 TRACE(XERR,
"cannot open dir "<<usrpath<<
" ; error: "<<errno);
991 bool xrm = 0, xclose = 0;
992 struct dirent *sent = 0;
993 while ((sent = (
struct dirent *)readdir(subdir))) {
995 if (!strcmp(sent->d_name,
".") || !strcmp(sent->d_name,
".."))
continue;
996 if (!strcmp(sent->d_name,
"xpdsock"))
continue;
997 XPDFORM(discpath,
"%s/%s/disconnected", usrpath.c_str(), sent->d_name);
999 XPDFORM(cidpath,
"%s/%s/cid", usrpath.c_str(), sent->d_name);
1001 if (stat(cidpath.c_str(), &st) == 0) {
1003 if (stat(discpath.c_str(), &xst) == 0) {
1004 if ((
int)(time(0) - st.st_atime) > fReconnectTimeOut) {
1011 if (fActivityTimeOut > 0 &&
1012 (
int)(time(0) - st.st_atime) > fActivityTimeOut) {
1013 if (c->Touch() == 1) {
1029 int cid = XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg);
1032 XrdProofdProtocol *p = c->GetProtocol(cid);
1033 if (p && p->Link()) {
1036 c->SkipSessionsCheck(0, emsg);
1040 TRACE(XERR,
"protocol or link associated with ID "<<cid<<
" are invalid");
1044 TRACE(XERR,
"could not resolve client id from "<<cidpath);
1050 discpath.replace(
"/disconnected",
"");
1051 TRACE(DBG,
"removing path "<<discpath);
1052 if ((rc = XrdProofdAux::RmDir(discpath.c_str())) != 0) {
1053 TRACE(XERR,
"problems removing "<<discpath<<
"; error: "<<-rc);
1065 TRACE(DBG,
"removing path: " <<usrpath);
1066 if ((rc = XrdProofdAux::RmDir(usrpath.c_str())) != 0) {
1067 TRACE(XERR,
"problems removing "<<usrpath<<
"; error: "<<-rc);
1081 int XrdProofdClientMgr::Auth(XrdProofdProtocol *p)
1083 XPDLOC(CMGR,
"ClientMgr::Auth")
1085 XrdSecCredentials cred;
1086 XrdSecParameters *parm = 0;
1090 XPD_SETRESP(p, "Auth");
1092 TRACEP(p, REQ, "enter");
1096 return response->Send();
1097 cred.size = p->Request()->header.dlen;
1098 cred.buffer = p->Argp()->buff;
1101 if (!p->AuthProt()) {
1102 XrdSecProtocol *ap = 0;
1104 XrdNetAddr netaddr(p->Link()->NetAddr());
1106 struct sockaddr netaddr;
1107 p->Link()->Name(&netaddr);
1109 if (!(ap = fCIA->getProtocol(p->Link()->Host(), netaddr, &cred, &eMsg))) {
1110 eText = eMsg.getErrText(rc);
1111 TRACEP(p, XERR,
"user authentication failed; "<<eText);
1112 response->Send(kXR_NotAuthorized, eText);
1116 p->AuthProt()->Entity.tident = p->Link()->ID;
1119 size_t len = strlen(
"XrdSecLOGINUSER=")+strlen(p->UserIn())+2;
1120 char *u =
new char[len];
1121 snprintf(u, len,
"XrdSecLOGINUSER=%s", p->UserIn());
1126 if (!(rc = p->AuthProt()->Authenticate(&cred, &parm, &eMsg))) {
1129 if (p->AuthProt()->Entity.name && strlen(p->AuthProt()->Entity.name) > 0) {
1130 if (p->UserIn() && strlen(p->UserIn()) > 0) {
1131 XrdOucString usrs(p->AuthProt()->Entity.name);
1132 SafeFree(p->AuthProt()->Entity.name);
1134 int from = 0, rcmtc = -1;
1135 while ((from = usrs.tokenize(usr, from,
',')) != STR_NPOS) {
1137 if (!(p->AuthProt()->Entity.name))
1138 p->AuthProt()->Entity.name = strdup(usr.c_str());
1139 if ((usr == p->UserIn())) {
1140 free(p->AuthProt()->Entity.name);
1141 p->AuthProt()->Entity.name = strdup(usr.c_str());
1147 namsg =
"logging as '";
1148 namsg += p->AuthProt()->Entity.name;
1149 namsg +=
"' instead of '";
1150 namsg += p->UserIn();
1151 namsg +=
"' following admin settings";
1152 TRACEP(p, LOGIN, namsg.c_str());
1153 namsg.insert(
"Warning: ", 0);
1154 response->Send(kXR_attn, kXPD_srvmsg, 2, (
char *) namsg.c_str(), namsg.length());
1157 TRACEP(p, XERR,
"user name is empty: protocol error?");
1160 TRACEP(p, XERR,
"name of the authenticated entity is empty: protocol error?");
1165 const char *msg = (p->Status() & XPD_ADMINUSER) ?
" admin login as " :
" login as ";
1166 rc = response->Send();
1167 char status = p->Status();
1168 status &= ~XPD_NEED_AUTH;
1169 p->SetStatus(status);
1170 p->SetAuthEntity(&(p->AuthProt()->Entity));
1171 if (p->AuthProt()->Entity.name) {
1172 TRACEP(p, LOGIN, p->Link()->ID << msg << p->AuthProt()->Entity.name);
1174 TRACEP(p, LOGIN, p->Link()->ID << msg <<
" nobody");
1182 TRACEP(p, DBG,
"more auth requested; sz: " <<(parm ? parm->size : 0));
1184 rc = response->Send(kXR_authmore, parm->buffer, parm->size);
1188 if (p->AuthProt()) {
1189 p->AuthProt()->Delete();
1192 TRACEP(p, XERR,
"security requested additional auth w/o parms!");
1193 response->Send(kXP_ServerError,
"invalid authentication exchange");
1198 if (p->AuthProt()) {
1199 p->AuthProt()->Delete();
1202 eText = (namsg.length() > 0) ? namsg.c_str() : eMsg.getErrText(rc);
1203 TRACEP(p, XERR,
"user authentication failed; "<<eText);
1204 response->Send(kXR_NotAuthorized, eText);
1211 XrdSecService *XrdProofdClientMgr::LoadSecurity()
1213 XPDLOC(CMGR,
"ClientMgr::LoadSecurity")
1215 TRACE(REQ, "LoadSecurity");
1217 const
char *cfn = CfgFile();
1218 const
char *seclib = fSecLib.c_str();
1222 TRACE(XERR,
"config file not specified");
1227 if (!(fSecPlugin =
new XrdSysPlugin((fEDest ? fEDest : (XrdSysError *)0), seclib))) {
1228 TRACE(XERR,
"could not create plugin instance for "<<seclib);
1229 return (XrdSecService *)0;
1233 XrdSecServLoader_t ep = (XrdSecServLoader_t) fSecPlugin->getPlugin(
"XrdSecgetService");
1235 TRACE(XERR,
"could not find 'XrdSecgetService()' in "<<seclib);
1236 return (XrdSecService *)0;
1242 char *rcfn = FilterSecConfig(nd);
1244 SafeDelete(fSecPlugin);
1247 TRACE(XERR,
"no security directives: strong authentication disabled");
1251 TRACE(XERR,
"creating temporary config file");
1256 XrdSecService *cia = 0;
1257 if (!(cia = (*ep)((fEDest ? fEDest->logger() : (XrdSysLogger *)0), rcfn))) {
1258 TRACE(XERR,
"Unable to create security service object via " << seclib);
1259 SafeDelete(fSecPlugin);
1265 TRACE(ALL,
"strong authentication enabled");
1285 char *XrdProofdClientMgr::FilterSecConfig(
int &nd)
1287 XPDLOC(CMGR,
"ClientMgr::FilterSecConfig")
1289 static const
char *pfx[] = {
"xpd.sec.",
"sec.protparm",
"sec.protocol",
"set" };
1292 TRACE(REQ,
"enter");
1294 const char *cfn = CfgFile();
1299 if (!cfn || !(fin = fopen(cfn,
"r"))) {
1300 nd = (errno > 0) ? -errno : -1;
1308 while (fgets(lin,
sizeof(lin),fin)) {
1309 if (!strncmp(lin, pfx[0], strlen(pfx[0])) ||
1310 !strncmp(lin, pfx[1], strlen(pfx[1])) ||
1311 !strncmp(lin, pfx[2], strlen(pfx[2])) ||
1312 !strncmp(lin, pfx[3], strlen(pfx[3]))) {
1317 size_t len = strlen(fMgr->TMPdir()) + strlen(
"/xpdcfn_XXXXXX") + 2;
1318 rcfn =
new char[len];
1319 snprintf(rcfn, len,
"%s/xpdcfn_XXXXXX", fMgr->TMPdir());
1320 mode_t oldum = umask(022);
1321 if ((fd = mkstemp(rcfn)) < 0) {
1323 nd = (errno > 0) ? -errno : -1;
1326 oldum = umask(oldum);
1329 oldum = umask(oldum);
1331 XrdOucString slin = lin;
1333 if (slin.beginswith(
"xpd.")) slin.replace(
"xpd.",
"");
1335 fMgr->ResolveKeywords(slin, 0);
1337 XrdProofdAux::Write(fd, slin.c_str(), slin.length());
1343 if (fd >= 0) close(fd);
1353 XrdProofdClient *XrdProofdClientMgr::GetClient(
const char *usr,
const char *grp,
1356 XPDLOC(CMGR,
"ClientMgr::GetClient")
1358 TRACE(DBG, "usr: "<< (usr ? usr : "undef")<<", grp:"<<(grp ? grp : "undef"));
1360 XrdOucString dmsg, emsg;
1361 XrdProofdClient *c = 0;
1363 std::list<XrdProofdClient *>::iterator i;
1365 { XrdSysMutexHelper mh(fMutex);
1366 for (i = fProofdClients.begin(); i != fProofdClients.end(); ++i) {
1367 if ((c = *i) && c->Match(usr,grp))
break;
1376 if (fMgr->CheckUser(usr, grp, ui, emsg, su) == 0) {
1381 bool full = (fMgr->SrvType() != kXPD_Worker) ? 1 : 0;
1382 c =
new XrdProofdClient(ui, full, fMgr->ChangeOwn(), fEDest, fClntAdminPath.c_str(), fReconnectTimeOut);
1384 bool freeclient = 1;
1385 if (c && c->IsValid()) {
1387 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
1388 XrdProofGroup *g = fMgr->GroupsMgr()->GetUserGroup(usr, grp);
1390 c->SetGroup(g->Name());
1391 }
else if (TRACING(XERR)) {
1392 emsg =
"group = "; emsg += grp; emsg +=
" nor found";
1395 { XrdSysMutexHelper mh(fMutex);
1396 XrdProofdClient *nc = 0;
1397 for (i = fProofdClients.begin(); i != fProofdClients.end(); ++i) {
1398 if ((nc = *i) && nc->Match(usr,grp))
break;
1404 fProofdClients.push_back(c);
1410 }
else if (TRACING(DBG)) {
1411 XPDFORM(dmsg,
"instance for {client, group} = {%s, %s} created"
1412 " and added to the list (%p)", usr, grp, c);
1415 if (TRACING(XERR)) {
1416 XPDFORM(dmsg,
"instance for {client, group} = {%s, %s} is invalid", usr, grp);
1421 if (TRACING(XERR)) {
1422 XPDFORM(dmsg,
"client '%s' unknown or unauthorized: %s", usr, emsg.c_str());
1428 if (c && !newclient) {
1429 if (c->TrimSessionDirs() != 0) {
1430 if (TRACING(XERR)) {
1431 XPDFORM(dmsg,
"problems trimming client '%s' sandbox", usr);
1436 if (dmsg.length() > 0) {
1440 if (emsg.length() > 0) TRACE(XERR, emsg);
1453 void XrdProofdClientMgr::Broadcast(XrdProofdClient *clnt,
const char *msg)
1456 std::list<XrdProofdClient *> *clnts;
1459 clnts = &fProofdClients;
1461 clnts =
new std::list<XrdProofdClient *>;
1462 clnts->push_back(clnt);
1466 XrdProofdClient *c = 0;
1467 std::list<XrdProofdClient *>::iterator i;
1468 XrdSysMutexHelper mh(fMutex);
1469 for (i = clnts->begin(); i != clnts->end(); ++i) {
1475 if (clnt)
delete clnts;
1482 void XrdProofdClientMgr::TerminateSessions(XrdProofdClient *clnt,
const char *msg,
1485 XPDLOC(CMGR,
"ClientMgr::TerminateSessions")
1489 std::list<XrdProofdClient *> *clnts;
1492 clnts = &fProofdClients;
1495 clnts =
new std::list<XrdProofdClient *>;
1496 clnts->push_back(clnt);
1501 XrdProofdClient *c = 0;
1502 std::list<XrdProofdClient *>::iterator i;
1503 XrdSysMutexHelper mh(fMutex);
1504 for (i = clnts->begin(); i != clnts->end(); ++i) {
1511 TRACE(DBG,
"cleaning "<<all);
1513 if (fMgr && fMgr->SessionMgr()) {
1516 XPDFORM(buf,
"%s %d", (all ?
"all" : clnt->User()), srvtype);
1517 TRACE(DBG,
"posting: "<<buf);
1518 if ((rc = fMgr->SessionMgr()->Pipe()->Post(XrdProofdProofServMgr::kCleanSessions,
1519 buf.c_str())) != 0) {
1520 TRACE(XERR,
"problem posting the pipe; errno: "<<-rc);
1525 for (i = clnts->begin(); i != clnts->end(); ++i) {
1531 if (clnt)
delete clnts;