00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "XrdProofdPlatform.h"
00022
00023 #ifdef OLDXRDOUC
00024 # include "XrdOuc/XrdOucError.hh"
00025 # define XPD_LOG_01 OUC_LOG_01
00026 #else
00027 # include "XrdSys/XrdSysError.hh"
00028 # define XPD_LOG_01 SYS_LOG_01
00029 #endif
00030
00031 #include "Xrd/XrdBuffer.hh"
00032 #include "XrdOuc/XrdOucErrInfo.hh"
00033 #include "XrdOuc/XrdOucStream.hh"
00034 #include "XrdSec/XrdSecInterface.hh"
00035
00036 #include "XrdProofdClient.h"
00037 #include "XrdProofdClientMgr.h"
00038 #include "XrdProofdManager.h"
00039 #include "XrdProofdProtocol.h"
00040 #include "XrdProofGroup.h"
00041 #include "XrdProofdProofServ.h"
00042 #include "XrdProofdProofServMgr.h"
00043 #include "XrdROOT.h"
00044
00045
00046 #include "XrdProofdTrace.h"
00047
00048 static XpdManagerCron_t fManagerCron;
00049
00050
00051 typedef XrdSecService *(*XrdSecServLoader_t)(XrdSysLogger *, const char *cfn);
00052
00053
00054
00055
00056
00057
00058
00059
00060 void *XrdProofdClientCron(void *p)
00061 {
00062
00063
00064 XPDLOC(CMGR, "ClientCron")
00065
00066 XpdManagerCron_t *mc = (XpdManagerCron_t *)p;
00067 XrdProofdClientMgr *mgr = mc->fClientMgr;
00068 if (!(mgr)) {
00069 TRACE(REQ, "undefined client manager: cannot start");
00070 return (void *)0;
00071 }
00072 XrdProofdProofServMgr *smgr = mc->fSessionMgr;
00073 if (!(mgr)) {
00074 TRACE(REQ, "undefined session manager: cannot start");
00075 return (void *)0;
00076 }
00077
00078
00079 int lastcheck = time(0), ckfreq = mgr->CheckFrequency(), deltat = 0;
00080 while(1) {
00081
00082 if ((deltat = ckfreq - (time(0) - lastcheck)) <= 0)
00083 deltat = ckfreq;
00084 int pollRet = mgr->Pipe()->Poll(deltat);
00085
00086 if (pollRet > 0) {
00087
00088 XpdMsg msg;
00089 int rc = 0;
00090 if ((rc = mgr->Pipe()->Recv(msg)) != 0) {
00091 XPDERR("problems receiving message; errno: "<<-rc);
00092 continue;
00093 }
00094
00095 XrdOucString buf;
00096 if (msg.Type() == XrdProofdClientMgr::kClientDisconnect) {
00097
00098 XrdOucString adminpath;
00099 rc = msg.Get(adminpath);
00100 void *cp = 0;
00101 rc = (rc == 0) ? msg.Get(&cp) : rc;
00102 XrdProofdClient *c = (XrdProofdClient *)cp;
00103 int cid = -1;
00104 rc = (rc == 0) ? msg.Get(cid) : rc;
00105 int pid = -1;
00106 rc = (rc == 0) ? msg.Get(pid) : rc;
00107 if (rc != 0) {
00108 TRACE(XERR, "kClientDisconnect: problems parsing message: '"<<
00109 msg.Buf()<<"'; errno: "<<-rc);
00110 continue;
00111 }
00112 TRACE(DBG, "kClientDisconnect: got: '"<<adminpath<<"', "<<c<<", "<<cid);
00113 if (c) {
00114
00115 c->ResetClientSlot(cid);
00116 } else {
00117 TRACE(XERR, "kClientDisconnect: problems getting pointer to client instance: "<<c);
00118 }
00119
00120
00121 if (adminpath != "????") {
00122 adminpath.erase(adminpath.rfind("/cid"));
00123 if ((rc = XrdProofdAux::RmDir(adminpath.c_str())) != 0) {
00124 TRACE(XERR, "kClientDisconnect: problems removing admin path; errno: "<<-rc);
00125 continue;
00126 }
00127 }
00128
00129
00130 XPDFORM(buf, "%d", pid);
00131 smgr->Pipe()->Post(XrdProofdProofServMgr::kClientDisconnect, buf.c_str());
00132 TRACE(DBG,"sending to ProofServMgr: "<<buf);
00133
00134 } else {
00135 TRACE(XERR, "unknown type: "<<msg.Type());
00136 continue;
00137 }
00138 } else {
00139
00140 mgr->CheckClients();
00141
00142 lastcheck = time(0);
00143 }
00144 }
00145
00146
00147 return (void *)0;
00148 }
00149
00150
00151 XrdProofdClientMgr::XrdProofdClientMgr(XrdProofdManager *mgr,
00152 XrdProtocol_Config *pi, XrdSysError *e)
00153 : XrdProofdConfig(pi->ConfigFN, e)
00154 {
00155
00156 XPDLOC(CMGR, "XrdProofdClientMgr")
00157
00158 fMutex = new XrdSysRecMutex;
00159 fMgr = mgr;
00160 fCIA = 0;
00161 fNDisconnected = 0;
00162 fReconnectTimeOut = 300;
00163
00164 fActivityTimeOut = 1200;
00165 fCheckFrequency = 60;
00166
00167
00168 if (!fPipe.IsValid()) {
00169 TRACE(XERR, "unable to generate the pipe");
00170 return;
00171 }
00172
00173
00174 RegisterDirectives();
00175 }
00176
00177
00178 void XrdProofdClientMgr::RegisterDirectives()
00179 {
00180
00181
00182 Register("clientmgr", new XrdProofdDirective("clientmgr", this, &DoDirectiveClass));
00183 Register("seclib", new XrdProofdDirective("seclib",
00184 (void *)&fSecLib, &DoDirectiveString, 0));
00185 Register("reconnto", new XrdProofdDirective("reconnto",
00186 (void *)&fReconnectTimeOut, &DoDirectiveInt));
00187 }
00188
00189
00190 int XrdProofdClientMgr::DoDirective(XrdProofdDirective *d,
00191 char *val, XrdOucStream *cfg, bool rcf)
00192 {
00193
00194 XPDLOC(SMGR, "ClientMgr::DoDirective")
00195
00196 if (!d)
00197
00198 return -1;
00199
00200 if (d->fName == "clientmgr") {
00201 return DoDirectiveClientMgr(val, cfg, rcf);
00202 }
00203 TRACE(XERR,"unknown directive: "<<d->fName);
00204 return -1;
00205 }
00206
00207
00208 int XrdProofdClientMgr::DoDirectiveClientMgr(char *val, XrdOucStream *cfg, bool)
00209 {
00210
00211
00212 XPDLOC(SMGR, "ClientMgr::DoDirectiveClientMgr")
00213
00214 if (!val || !cfg)
00215
00216 return -1;
00217
00218 int checkfq = -1;
00219 int activityto = -1;
00220
00221 while (val) {
00222 XrdOucString tok(val);
00223 if (tok.beginswith("checkfq:")) {
00224 tok.replace("checkfq:", "");
00225 checkfq = strtol(tok.c_str(), 0, 10);
00226 } else if (tok.beginswith("activityto:")) {
00227 tok.replace("activityto:", "");
00228 activityto = strtol(tok.c_str(), 0, 10);
00229 }
00230
00231 val = cfg->GetWord();
00232 }
00233
00234
00235 if (fMgr->Host() && cfg)
00236 if (XrdProofdAux::CheckIf(cfg, fMgr->Host()) == 0)
00237 return 0;
00238
00239
00240 fCheckFrequency = (XPD_LONGOK(checkfq) && checkfq > 0) ? checkfq : fCheckFrequency;
00241 fActivityTimeOut = (XPD_LONGOK(activityto) && activityto > 0) ? activityto : fActivityTimeOut;
00242
00243 XrdOucString msg;
00244 XPDFORM(msg, "checkfq: %d s, activityto: %d s", fCheckFrequency, fActivityTimeOut);
00245 TRACE(ALL, msg);
00246
00247 return 0;
00248 }
00249
00250
00251 int XrdProofdClientMgr::Config(bool rcf)
00252 {
00253
00254
00255 XPDLOC(CMGR, "ClientMgr::Config")
00256
00257
00258 if (XrdProofdConfig::Config(rcf) != 0) {
00259 XPDERR("problems parsing file ");
00260 return -1;
00261 }
00262
00263 XrdOucString msg;
00264 msg = (rcf) ? "re-configuring" : "configuring";
00265 TRACE(ALL, msg.c_str());
00266
00267
00268 fClntAdminPath = fMgr->AdminPath();
00269 fClntAdminPath += "/clients";
00270
00271
00272 XrdProofUI ui;
00273 XrdProofdAux::GetUserInfo(fMgr->EffectiveUser(), ui);
00274 if (XrdProofdAux::AssertDir(fClntAdminPath.c_str(), ui, 1) != 0) {
00275 XPDERR("unable to assert the clients admin path: "<<fClntAdminPath);
00276 fClntAdminPath = "";
00277 return -1;
00278 }
00279 TRACE(ALL, "clients admin path set to: "<<fClntAdminPath);
00280
00281
00282 if (ParsePreviousClients(msg) != 0) {
00283 XPDERR("problems parsing previous active clients: "<<msg);
00284 }
00285
00286
00287 if (!rcf) {
00288 if (fSecLib.length() <= 0) {
00289 TRACE(ALL, "XRD seclib not specified; strong authentication disabled");
00290 } else {
00291 if (!(fCIA = LoadSecurity())) {
00292 XPDERR("unable to load security system.");
00293 return -1;
00294 }
00295 TRACE(ALL, "security library loaded");
00296 }
00297 }
00298
00299 if (rcf) {
00300
00301 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
00302 std::list<XrdProofdClient *>::iterator pci;
00303 for (pci = fProofdClients.begin(); pci != fProofdClients.end(); ++pci)
00304 (*pci)->SetGroup(fMgr->GroupsMgr()->GetUserGroup((*pci)->User())->Name());
00305 }
00306 }
00307
00308 if (!rcf) {
00309
00310 pthread_t tid;
00311
00312 fManagerCron.fClientMgr = this;
00313 fManagerCron.fSessionMgr = fMgr->SessionMgr();
00314 if (XrdSysThread::Run(&tid, XrdProofdClientCron,
00315 (void *)&fManagerCron, 0, "ClientMgr cron thread") != 0) {
00316 XPDERR("could not start cron thread");
00317 return 0;
00318 }
00319 TRACE(ALL, "cron thread started");
00320 }
00321
00322
00323 return 0;
00324 }
00325
00326
00327 int XrdProofdClientMgr::Login(XrdProofdProtocol *p)
00328 {
00329
00330 XPDLOC(CMGR, "ClientMgr::Login")
00331
00332 int rc = 0;
00333 XPD_SETRESP(p, "Login");
00334
00335 TRACEP(p, HDBG, "enter");
00336
00337
00338
00339 if (p->Request()->login.role[0] != 'i' &&
00340 (fMgr->SrvType() == kXPD_MasterWorker || fMgr->SrvType() == kXPD_Master)) {
00341 if (!fMgr->CheckMaster(p->Link()->Host())) {
00342 TRACEP(p, XERR,"master not allowed to connect - "
00343 "ignoring request ("<<p->Link()->Host()<<")");
00344 response->Send(kXR_InvalidRequest,
00345 "master not allowed to connect - request ignored");
00346 return 0;
00347 }
00348 }
00349
00350
00351 if (p->Status() == XPD_NEED_MAP) {
00352
00353 response->Send();
00354 p->SetStatus(XPD_LOGGEDIN);
00355 return MapClient(p, 0);
00356 }
00357
00358
00359 if ((p->Status() & XPD_LOGGEDIN)) {
00360 response->Send(kXR_InvalidRequest, "duplicate login; already logged in");
00361 return 0;
00362 }
00363
00364
00365 bool needauth = 0;
00366 bool ismaster = (fMgr->SrvType() == kXPD_TopMaster || fMgr->SrvType() == kXPD_Master) ? 1 : 0;
00367 switch (p->Request()->login.role[0]) {
00368 case 'A':
00369 p->SetConnType(kXPD_Admin);
00370 response->SetTag("adm");
00371 break;
00372 case 'i':
00373 p->SetConnType(kXPD_Internal);
00374 response->SetTag("int");
00375 break;
00376 case 'M':
00377 if (fMgr->SrvType() == kXPD_AnyServer || ismaster) {
00378 p->SetConnType(kXPD_ClientMaster);
00379 needauth = 1;
00380 response->SetTag("m2c");
00381 } else {
00382 TRACEP(p, XERR,"top master mode not allowed - ignoring request");
00383 response->Send(kXR_InvalidRequest,
00384 "Server not allowed to be top master - ignoring request");
00385 return 0;
00386 }
00387 break;
00388 case 'm':
00389 if (fMgr->SrvType() == kXPD_AnyServer || ismaster) {
00390 p->SetConnType(kXPD_MasterMaster);
00391 needauth = 1;
00392 response->SetTag("m2m");
00393 } else {
00394 TRACEP(p, XERR,"submaster mode not allowed - ignoring request");
00395 response->Send(kXR_InvalidRequest,
00396 "Server not allowed to be submaster - ignoring request");
00397 return 0;
00398 }
00399 break;
00400 case 's':
00401 if (fMgr->SrvType() == kXPD_AnyServer || fMgr->SrvType() == kXPD_MasterWorker) {
00402 p->SetConnType(kXPD_MasterWorker);
00403 needauth = 1;
00404 response->SetTag("w2m");
00405 } else {
00406 TRACEP(p, XERR,"worker mode not allowed - ignoring request");
00407 response->Send(kXR_InvalidRequest,
00408 "Server not allowed to be worker - ignoring request");
00409 return 0;
00410 }
00411 break;
00412 default:
00413 TRACEP(p, XERR, "unknown mode: '" << p->Request()->login.role[0] <<"'");
00414 response->Send(kXR_InvalidRequest, "Server type: invalide mode");
00415 return rc;
00416 }
00417 response->SetTraceID();
00418
00419
00420 int i, pid;
00421 XrdOucString uname, gname;
00422
00423
00424 pid = (int)ntohl(p->Request()->login.pid);
00425 p->SetPid(pid);
00426
00427
00428 char un[9];
00429 for (i = 0; i < (int)sizeof(un)-1; i++) {
00430 if (p->Request()->login.username[i] == '\0' || p->Request()->login.username[i] == ' ')
00431 break;
00432 un[i] = p->Request()->login.username[i];
00433 }
00434 un[i] = '\0';
00435 uname = un;
00436
00437
00438 if (uname == "?>buf") {
00439
00440 char *buf = p->Argp()->buff;
00441 int len = p->Request()->login.dlen;
00442
00443 uname.assign(buf,0,len-1);
00444 int iusr = uname.find("|usr:");
00445 if (iusr == -1) {
00446 TRACEP(p, XERR,"long user name not found");
00447 response->Send(kXR_InvalidRequest, "long user name not found");
00448 return 0;
00449 }
00450 uname.erase(0,iusr+5);
00451 uname.erase(uname.find("|"));
00452 }
00453
00454
00455 int ig = uname.find(":");
00456 if (ig != -1) {
00457 gname.assign(uname, ig+1);
00458 uname.erase(ig);
00459 TRACEP(p, DBG, "requested group: "<<gname);
00460 }
00461
00462
00463
00464 XrdOucString emsg;
00465 XrdProofUI ui;
00466 bool su;
00467 if (fMgr->CheckUser(uname.c_str(), ui, emsg, su) != 0) {
00468 XPDFORM(emsg, "username not allowed: %s", uname.c_str());
00469 TRACEP(p, XERR, emsg);
00470 response->Send(kXR_InvalidRequest, emsg.c_str());
00471 return 0;
00472 }
00473 if (su) {
00474
00475 p->SetSuperUser(su);
00476 TRACEP(p, DBG, "request from entity: "<<uname<<":"<<gname<<" (privileged)");
00477 } else {
00478 TRACEP(p, DBG, "request from entity: "<<uname<<":"<<gname);
00479 }
00480
00481
00482 XrdProofGroup *g = 0;
00483 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
00484 if (gname.length() > 0) {
00485 g = fMgr->GroupsMgr()->GetGroup(gname.c_str());
00486 if (!g) {
00487 XPDFORM(emsg, "group unknown: %s", gname.c_str());
00488 TRACEP(p, XERR, emsg);
00489 response->Send(kXR_InvalidRequest, emsg.c_str());
00490 return 0;
00491 } else if (strncmp(g->Name(),"default",7) &&
00492 !g->HasMember(uname.c_str())) {
00493 XPDFORM(emsg, "user %s is not member of group %s", uname.c_str(), gname.c_str());
00494 TRACEP(p, XERR, emsg);
00495 response->Send(kXR_InvalidRequest, emsg.c_str());
00496 return 0;
00497 } else {
00498 if (TRACING(DBG)) {
00499 TRACEP(p, DBG,"group: "<<gname<<" found");
00500 g->Print();
00501 }
00502 }
00503 } else {
00504 g = fMgr->GroupsMgr()->GetUserGroup(uname.c_str());
00505 gname = g ? g->Name() : "default";
00506 }
00507 }
00508 ui.fGroup = gname;
00509
00510
00511
00512 XrdProofdClient *c = GetClient(uname.c_str(), gname.c_str());
00513 if (c) {
00514 if (!c->ROOT())
00515 c->SetROOT(fMgr->ROOTMgr()->DefaultVersion());
00516 if (c->IsValid()) {
00517
00518 c->SetGroup(g->Name());
00519 }
00520 } else {
00521 emsg = "unable to instantiate object for client ";
00522 emsg += uname;
00523 TRACEP(p, XERR, emsg.c_str());
00524 response->Send(kXR_InvalidRequest, emsg.c_str());
00525 return 0;
00526 }
00527
00528 p->SetClient(c);
00529
00530
00531 p->Link()->setID(uname.c_str(), pid);
00532 p->SetTraceID();
00533 response->SetTraceID();
00534 p->SetClntCapVer(p->Request()->login.capver[0]);
00535
00536
00537
00538
00539 if (needauth && fCIA) {
00540 const char *pp = fCIA->getParms(i, p->Link()->Name());
00541 if (pp && i ) {
00542 response->SendI((kXR_int32)XPROOFD_VERSBIN, (void *)pp, i);
00543 p->SetStatus((XPD_NEED_MAP | XPD_NEED_AUTH));
00544 return 0;
00545 } else {
00546 response->SendI((kXR_int32)XPROOFD_VERSBIN);
00547 p->SetStatus(XPD_LOGGEDIN);
00548 if (pp)
00549 p->SetAuthEntity();
00550 }
00551 } else {
00552 rc = response->SendI((kXR_int32)XPROOFD_VERSBIN);
00553 p->SetStatus(XPD_LOGGEDIN);
00554 }
00555
00556
00557 return MapClient(p, 1);
00558 }
00559
00560
00561 int XrdProofdClientMgr::MapClient(XrdProofdProtocol *p, bool all)
00562 {
00563
00564 XPDLOC(CMGR, "ClientMgr::MapClient")
00565
00566 int rc = 0;
00567 XPD_SETRESP(p, "MapClient");
00568
00569 XrdOucString msg;
00570
00571 TRACEP(p, HDBG, "all: "<< all);
00572
00573
00574 XrdProofdClient *pc = p->Client();
00575
00576
00577 if (!pc || !pc->IsValid()) {
00578 if (pc) {
00579 {
00580 XrdSysMutexHelper mh(fMutex);
00581 fProofdClients.remove(pc);
00582 }
00583 SafeDelete(pc);
00584 p->SetClient(0);
00585 }
00586 TRACEP(p, DBG, "cannot find valid instance of XrdProofdClient");
00587 response->Send(kXP_ServerError,
00588 "MapClient: cannot find valid instance of XrdProofdClient");
00589 return 0;
00590 }
00591
00592
00593 bool proofsrv = ((p->ConnType() == kXPD_Internal) && all) ? 1 : 0;
00594
00595
00596 short int psid = -1;
00597 char protver = -1;
00598 short int clientvers = -1;
00599 if (proofsrv) {
00600 memcpy(&psid, (const void *)&(p->Request()->login.reserved[0]), 2);
00601 if (psid < 0) {
00602 TRACEP(p, XERR, "proofsrv callback: sent invalid session id");
00603 response->Send(kXR_InvalidRequest,
00604 "MapClient: proofsrv callback: sent invalid session id");
00605 return 0;
00606 }
00607 protver = p->Request()->login.capver[0];
00608 TRACEP(p, DBG, "proofsrv callback for session: " <<psid);
00609 } else {
00610
00611 memcpy(&clientvers, (const void *)&(p->Request()->login.reserved[0]), 2);
00612 TRACEP(p, DBG, "PROOF version run by client: " <<clientvers);
00613 }
00614
00615
00616 if (proofsrv) {
00617 XrdProofdProofServ *psrv = pc->GetServer(psid);
00618 if (!psrv) {
00619 TRACEP(p, XERR, "proofsrv callback: wrong target session: "<<psid<<" : protocol error");
00620 response->Send(kXP_nosession, "MapClient: proofsrv callback:"
00621 " wrong target session: protocol error");
00622 return -1;
00623 } else {
00624
00625 psrv->SetProtVer(protver);
00626
00627 XrdProofdResponse *resp = p->Response(1);
00628 psrv->SetConnection(resp);
00629 psrv->SetValid(1);
00630
00631 XrdOucString tid;
00632 XPDFORM(tid, "xrd->%s", psrv->Ordinal());
00633 resp->SetTag(tid.c_str());
00634 resp->SetTraceID();
00635 TRACEI(resp->TraceID(), DBG, "proofsrv callback: link assigned to target session "<<psid);
00636 }
00637 } else {
00638
00639
00640 XrdSysMutexHelper mhc(pc->Mutex());
00641
00642
00643
00644 p->SetProofProtocol(clientvers);
00645
00646
00647 XrdOucString cpath;
00648 int cid = -1;
00649 if ((cid = CheckAdminPath(p, cpath, msg)) >= 0) {
00650
00651 pc->SetClientID(cid, p);
00652
00653 p->SetCID(cid);
00654
00655 XrdOucString discpath(cpath, 0, cpath.rfind("/cid"));
00656 discpath += "/disconnected";
00657 if (unlink(discpath.c_str()) != 0) {
00658 XPDFORM(msg, "warning: could not remove %s (errno: %d)", discpath.c_str(), errno);
00659 TRACEP(p, XERR, msg.c_str());
00660 }
00661
00662 fNDisconnected--;
00663
00664 } else {
00665
00666 p->SetCID(pc->GetClientID(p));
00667
00668 if (CreateAdminPath(p, cpath, msg) != 0) {
00669 TRACEP(p, XERR, msg.c_str());
00670 fProofdClients.remove(pc);
00671 SafeDelete(pc);
00672 p->SetClient(0);
00673 response->Send(kXP_ServerError, msg.c_str());
00674 return 0;
00675 }
00676 }
00677 p->SetAdminPath(cpath.c_str());
00678 XPDFORM(msg, "client ID and admin paths created: %s", cpath.c_str());
00679 TRACEP(p, DBG, msg.c_str());
00680
00681 TRACEP(p, DBG, "CID: "<<p->CID()<<", size: "<<pc->Size());
00682 }
00683
00684
00685 if (!(p->Status() & XPD_NEED_AUTH)) {
00686 const char *srvtype[6] = {"ANY", "MasterWorker", "MasterMaster",
00687 "ClientMaster", "Internal", "Admin"};
00688 XPDFORM(msg, "user %s logged-in%s; type: %s", pc->User(),
00689 p->SuperUser() ? " (privileged)" : "", srvtype[p->ConnType()+1]);
00690 TRACEP(p, LOGIN, msg);
00691 }
00692
00693
00694 return 0;
00695 }
00696
00697
00698 int XrdProofdClientMgr::CreateAdminPath(XrdProofdProtocol *p,
00699 XrdOucString &cpath, XrdOucString &emsg)
00700 {
00701
00702
00703 if (!p || !p->Link()) {
00704 XPDFORM(emsg, "invalid inputs (p: %p)", p);
00705 return -1;
00706 }
00707
00708
00709 XrdOucString lid;
00710 XPDFORM(lid, "%s.%d", p->Link()->Host(), p->Pid());
00711
00712
00713 XPDFORM(cpath, "%s/%s", p->Client()->AdminPath(), lid.c_str());
00714 XrdProofUI ui;
00715 XrdProofdAux::GetUserInfo(fMgr->EffectiveUser(), ui);
00716 if (XrdProofdAux::AssertDir(cpath.c_str(), ui, 1) != 0) {
00717 XPDFORM(emsg, "error creating client admin path: %s", cpath.c_str());
00718 return -1;
00719 }
00720
00721 cpath += "/cid";
00722 FILE *fcid = fopen(cpath.c_str(), "w");
00723 if (fcid) {
00724 fprintf(fcid, "%d", p->CID());
00725 fclose(fcid);
00726 } else {
00727 XPDFORM(emsg, "error creating file for client id: %s", cpath.c_str());
00728 return -1;
00729 }
00730
00731 return 0;
00732 }
00733
00734
00735 int XrdProofdClientMgr::CheckAdminPath(XrdProofdProtocol *p,
00736 XrdOucString &cidpath, XrdOucString &emsg)
00737 {
00738
00739
00740
00741 emsg = "";
00742 if (!p) {
00743 XPDFORM(emsg, "CheckAdminPath: invalid inputs (p: %p)", p);
00744 return -1;
00745 }
00746
00747
00748 XrdOucString lid;
00749 XPDFORM(lid, "%s.%d", p->Link()->Host(), p->Pid());
00750
00751
00752 XPDFORM(cidpath, "%s/%s/cid", p->Client()->AdminPath(), lid.c_str());
00753
00754
00755 int rc = 0;
00756 bool expired = false;
00757 struct stat st;
00758 if ((rc = stat(cidpath.c_str(), &st)) != 0 ||
00759 (expired = ((int)(time(0) - st.st_atime) > fReconnectTimeOut))) {
00760 if (expired || (rc != 0 && errno != ENOENT)) {
00761
00762 cidpath.replace("/cid", "");
00763 if (expired)
00764 XPDFORM(emsg, "CheckAdminPath: reconnection timeout expired: remove %s ",
00765 cidpath.c_str());
00766 else
00767 XPDFORM(emsg, "CheckAdminPath: problems stat'ing %s (errno: %d): remove ",
00768 cidpath.c_str(), errno);
00769 if (XrdProofdAux::RmDir(cidpath.c_str()) != 0)
00770 emsg += ": failure!";
00771 } else {
00772 XPDFORM(emsg, "CheckAdminPath: no such file %s", cidpath.c_str());
00773 }
00774 return -1;
00775 }
00776
00777
00778 return XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg);
00779 }
00780
00781
00782 int XrdProofdClientMgr::ParsePreviousClients(XrdOucString &emsg)
00783 {
00784
00785 XPDLOC(CMGR, "ClientMgr::ParsePreviousClients")
00786
00787 emsg = "";
00788
00789
00790 DIR *dir = opendir(fClntAdminPath.c_str());
00791 if (!dir) {
00792 TRACE(XERR, "cannot open dir "<<fClntAdminPath<<" ; error: "<<errno);
00793 return -1;
00794 }
00795 TRACE(DBG, "creating holders for active clients ...");
00796
00797
00798 XrdOucString usrpath, cidpath, discpath, usr, grp;
00799 struct dirent *ent = 0;
00800 while ((ent = (struct dirent *)readdir(dir))) {
00801
00802 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue;
00803 XPDFORM(usrpath, "%s/%s", fClntAdminPath.c_str(), ent->d_name);
00804 bool rm = 0;
00805 struct stat st;
00806 if (stat(usrpath.c_str(), &st) == 0) {
00807 usr = ent->d_name;
00808 grp = usr;
00809 usr.erase(usr.find('.'));
00810 grp.erase(0, grp.find('.')+1);
00811 TRACE(DBG, "found usr: "<<usr<<", grp: "<<grp);
00812
00813 XrdProofdClient *c = GetClient(usr.c_str(), grp.c_str());
00814 if (!c) {
00815 XPDFORM(emsg, "ParsePreviousClients: could not get client instance"
00816 " for {%s, %s}", usr.c_str(), grp.c_str());
00817 rm = 1;
00818 }
00819
00820 DIR *subdir = 0;
00821 if (!rm && !(subdir = opendir(usrpath.c_str()))) {
00822 TRACE(XERR, "cannot open dir "<<usrpath<<" ; error: "<<errno);
00823 rm = 1;
00824 }
00825 if (!rm) {
00826 bool xrm = 0;
00827 struct dirent *sent = 0;
00828 while ((sent = (struct dirent *)readdir(subdir))) {
00829
00830 if (!strcmp(sent->d_name, ".") || !strcmp(sent->d_name, "..")) continue;
00831 if (!strcmp(sent->d_name, "xpdsock")) continue;
00832 XPDFORM(cidpath, "%s/%s/cid", usrpath.c_str(), sent->d_name);
00833
00834 if (stat(cidpath.c_str(), &st) != 0 ||
00835 (int)(time(0) - st.st_atime) > fReconnectTimeOut) {
00836 xrm = 1;
00837 }
00838
00839 int cid = (!xrm) ? XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg) : -1;
00840 if (cid < 0)
00841 xrm = 1;
00842
00843 if (!xrm && c->ReserveClientID(cid) != 0)
00844 xrm = 1;
00845
00846 if (!xrm) {
00847 XPDFORM(discpath, "%s/%s/disconnected", usrpath.c_str(), sent->d_name);
00848 FILE *fd = fopen(discpath.c_str(), "w");
00849 if (!fd) {
00850 TRACE(XERR, "unable to create path: " <<discpath);
00851 xrm = 1;
00852 }
00853 fclose(fd);
00854 if (!xrm)
00855 fNDisconnected++;
00856 }
00857
00858 if (xrm) {
00859 TRACE(DBG, "removing path: " <<cidpath);
00860 cidpath.replace("/cid", "");
00861 XPDFORM(emsg, "ParsePreviousClients: failure: remove %s ", cidpath.c_str());
00862 if (XrdProofdAux::RmDir(cidpath.c_str()) != 0)
00863 emsg += ": failure!";
00864 }
00865 }
00866 }
00867 if (subdir)
00868 closedir(subdir);
00869 } else {
00870 rm = 1;
00871 }
00872
00873 if (rm) {
00874 TRACE(DBG, "removing path: " <<usrpath);
00875 XPDFORM(emsg, "ParsePreviousClients: failure: remove %s ", usrpath.c_str());
00876 if (XrdProofdAux::RmDir(usrpath.c_str()) != 0)
00877 emsg += ": failure!";
00878 }
00879 }
00880
00881 closedir(dir);
00882
00883
00884 TRACE(DBG, "found "<<fNDisconnected<<" active clients");
00885
00886
00887 return 0;
00888 }
00889
00890
00891 int XrdProofdClientMgr::CheckClients()
00892 {
00893
00894 XPDLOC(CMGR, "ClientMgr::CheckClients")
00895
00896
00897 DIR *dir = opendir(fClntAdminPath.c_str());
00898 if (!dir) {
00899 TRACE(XERR, "cannot open dir "<<fClntAdminPath<<" ; error: "<<errno);
00900 return -1;
00901 }
00902 TRACE(REQ, "checking active clients ...");
00903
00904
00905 int rc = 0;
00906 XrdOucString usrpath, cidpath, discpath;
00907 struct dirent *ent = 0;
00908 while ((ent = (struct dirent *)readdir(dir))) {
00909
00910 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue;
00911 XPDFORM(usrpath, "%s/%s", fClntAdminPath.c_str(), ent->d_name);
00912 bool rm = 0;
00913 XrdProofdClient *c = 0;
00914 struct stat st, xst;
00915 if (stat(usrpath.c_str(), &xst) == 0) {
00916
00917 XrdOucString usr, grp;
00918 XrdProofdAux::ParseUsrGrp(ent->d_name, usr, grp);
00919 if (!(c = GetClient(usr.c_str(), grp.c_str(), 0))) {
00920 TRACE(XERR, "instance for client "<<ent->d_name<<" not found!");
00921 rm = 1;
00922 }
00923
00924 DIR *subdir = 0;
00925 if (!rm && !(subdir = opendir(usrpath.c_str()))) {
00926 TRACE(XERR, "cannot open dir "<<usrpath<<" ; error: "<<errno);
00927 rm = 1;
00928 }
00929 if (!rm) {
00930 bool xrm = 0, xclose = 0;
00931 struct dirent *sent = 0;
00932 while ((sent = (struct dirent *)readdir(subdir))) {
00933
00934 if (!strcmp(sent->d_name, ".") || !strcmp(sent->d_name, "..")) continue;
00935 if (!strcmp(sent->d_name, "xpdsock")) continue;
00936 XPDFORM(discpath, "%s/%s/disconnected", usrpath.c_str(), sent->d_name);
00937
00938 XPDFORM(cidpath, "%s/%s/cid", usrpath.c_str(), sent->d_name);
00939
00940 if (stat(cidpath.c_str(), &st) == 0) {
00941
00942 if (stat(discpath.c_str(), &xst) == 0) {
00943 if ((int)(time(0) - st.st_atime) > fReconnectTimeOut) {
00944 xrm = 1;
00945 }
00946 } else {
00947
00948
00949
00950 if (fActivityTimeOut > 0 &&
00951 (int)(time(0) - st.st_atime) > fActivityTimeOut) {
00952 if (c->Touch() == 1) {
00953
00954
00955
00956 xclose = 1;
00957
00958 FILE *fd = fopen(discpath.c_str(), "w");
00959 if (!fd) {
00960 TRACE(XERR, "unable to create path: " <<discpath);
00961 } else {
00962 fclose(fd);
00963 }
00964 }
00965 }
00966 }
00967 } else {
00968
00969 xrm = 1;
00970 }
00971
00972 if (xrm) {
00973 discpath.replace("/disconnected", "");
00974 TRACE(DBG, "removing path "<<discpath);
00975 if ((rc = XrdProofdAux::RmDir(discpath.c_str())) != 0) {
00976 TRACE(XERR, "problems removing "<<discpath<<"; error: "<<-rc);
00977 }
00978 }
00979
00980 if (xclose) {
00981
00982 XrdOucString emsg;
00983 int cid = XrdProofdAux::GetIDFromPath(cidpath.c_str(), emsg);
00984 if (cid >= 0) {
00985
00986 XrdProofdProtocol *p = c->GetProtocol(cid);
00987 if (p && p->Link()) {
00988
00989
00990 c->SkipSessionsCheck(0, emsg);
00991
00992 p->Link()->Close();
00993 } else {
00994 TRACE(XERR, "protocol or link associated with ID "<<cid<<" are invalid");
00995 }
00996 } else {
00997 TRACE(XERR, "could not resolve client id from "<<cidpath);
00998 }
00999
01000 discpath.replace("/disconnected", "");
01001 TRACE(DBG, "removing path "<<discpath);
01002 if ((rc = XrdProofdAux::RmDir(discpath.c_str())) != 0) {
01003 TRACE(XERR, "problems removing "<<discpath<<"; error: "<<-rc);
01004 }
01005 }
01006 }
01007 }
01008 if (subdir)
01009 closedir(subdir);
01010 } else {
01011 rm = 1;
01012 }
01013
01014 if (rm) {
01015 TRACE(DBG, "removing path: " <<usrpath);
01016 if ((rc = XrdProofdAux::RmDir(usrpath.c_str())) != 0) {
01017 TRACE(XERR, "problems removing "<<usrpath<<"; error: "<<-rc);
01018 }
01019 }
01020 }
01021
01022 closedir(dir);
01023
01024
01025 return 0;
01026 }
01027
01028
01029 int XrdProofdClientMgr::Auth(XrdProofdProtocol *p)
01030 {
01031
01032 XPDLOC(CMGR, "ClientMgr::Auth")
01033
01034 struct sockaddr netaddr;
01035 XrdSecCredentials cred;
01036 XrdSecParameters *parm = 0;
01037 XrdOucErrInfo eMsg;
01038 const char *eText;
01039 int rc = 1;
01040 XPD_SETRESP(p, "Auth");
01041
01042 TRACEP(p, REQ, "enter");
01043
01044
01045 if (!fCIA)
01046 return response->Send();
01047 cred.size = p->Request()->header.dlen;
01048 cred.buffer = p->Argp()->buff;
01049
01050
01051 if (!p->AuthProt()) {
01052 p->Link()->Name(&netaddr);
01053 XrdSecProtocol *ap = 0;
01054 if (!(ap = fCIA->getProtocol(p->Link()->Host(), netaddr, &cred, &eMsg))) {
01055 eText = eMsg.getErrText(rc);
01056 TRACEP(p, XERR, "user authentication failed; "<<eText);
01057 response->Send(kXR_NotAuthorized, eText);
01058 return -EACCES;
01059 }
01060 p->SetAuthProt(ap);
01061 p->AuthProt()->Entity.tident = p->Link()->ID;
01062 }
01063
01064 char *u = new char[strlen("XrdSecLOGINUSER=")+strlen(p->Client()->User())+2];
01065 sprintf(u, "XrdSecLOGINUSER=%s", p->Client()->User());
01066 putenv(u);
01067
01068
01069 XrdOucString namsg;
01070 if (!(rc = p->AuthProt()->Authenticate(&cred, &parm, &eMsg))) {
01071
01072
01073 if (p->AuthProt()->Entity.name && strlen(p->AuthProt()->Entity.name) > 0) {
01074 rc = -1;
01075 if (p->Client() && p->Client()->User() && strlen(p->Client()->User()) > 0) {
01076 XrdOucString usrs(p->AuthProt()->Entity.name);
01077 XrdOucString usr;
01078 int from = 0;
01079 while ((from = usrs.tokenize(usr, from, ',')) != STR_NPOS) {
01080 if ((usr == p->Client()->User())) {
01081 free(p->AuthProt()->Entity.name);
01082 p->AuthProt()->Entity.name = strdup(usr.c_str());
01083 rc = 0;
01084 break;
01085 }
01086 }
01087 if (rc != 0) {
01088 namsg = "user ";
01089 namsg += p->Client()->User();
01090 namsg += " not authorized to connect";
01091 TRACEP(p, XERR, namsg.c_str());
01092 }
01093 } else {
01094 TRACEP(p, XERR, "user name is empty: protocol error?");
01095 }
01096 } else {
01097 TRACEP(p, XERR, "name of the authenticated entity is empty: protocol error?");
01098 rc = -1;
01099 }
01100
01101 if (rc == 0) {
01102 const char *msg = (p->Status() & XPD_ADMINUSER) ? " admin login as " : " login as ";
01103 rc = response->Send();
01104 char status = p->Status();
01105 status &= ~XPD_NEED_AUTH;
01106 p->SetStatus(status);
01107 p->SetAuthEntity(&(p->AuthProt()->Entity));
01108 if (p->AuthProt()->Entity.name) {
01109 TRACEP(p, LOGIN, p->Link()->ID << msg << p->AuthProt()->Entity.name);
01110 } else {
01111 TRACEP(p, LOGIN, p->Link()->ID << msg << " nobody");
01112 }
01113 return rc;
01114 }
01115 }
01116
01117
01118 if (rc > 0) {
01119 TRACEP(p, DBG, "more auth requested; sz: " <<(parm ? parm->size : 0));
01120 if (parm) {
01121 rc = response->Send(kXR_authmore, parm->buffer, parm->size);
01122 delete parm;
01123 return rc;
01124 }
01125 if (p->AuthProt()) {
01126 p->AuthProt()->Delete();
01127 p->SetAuthProt(0);
01128 }
01129 TRACEP(p, XERR, "security requested additional auth w/o parms!");
01130 response->Send(kXP_ServerError, "invalid authentication exchange");
01131 return -EACCES;
01132 }
01133
01134
01135 if (p->AuthProt()) {
01136 p->AuthProt()->Delete();
01137 p->SetAuthProt(0);
01138 }
01139 eText = (namsg.length() > 0) ? namsg.c_str() : eMsg.getErrText(rc);
01140 TRACEP(p, XERR, "user authentication failed; "<<eText);
01141 response->Send(kXR_NotAuthorized, eText);
01142 return -EACCES;
01143 }
01144
01145
01146 XrdSecService *XrdProofdClientMgr::LoadSecurity()
01147 {
01148
01149 XPDLOC(CMGR, "ClientMgr::LoadSecurity")
01150
01151 TRACE(REQ, "LoadSecurity");
01152
01153 const char *cfn = CfgFile();
01154 const char *seclib = fSecLib.c_str();
01155
01156
01157 if (!cfn) {
01158 TRACE(XERR, "config file not specified");
01159 return 0;
01160 }
01161
01162
01163 void *lh = 0;
01164 if (!(lh = dlopen(seclib, RTLD_NOW))) {
01165 TRACE(XERR, dlerror()<<" opening shared library "<< seclib);
01166 return 0;
01167 }
01168
01169
01170 XrdSecServLoader_t ep = 0;
01171 if (!(ep = (XrdSecServLoader_t)dlsym(lh, "XrdSecgetService"))) {
01172 TRACE(XERR, dlerror() <<" finding XrdSecgetService() in "<<seclib);
01173 return 0;
01174 }
01175
01176
01177
01178 int nd = 0;
01179 char *rcfn = FilterSecConfig(nd);
01180 if (!rcfn) {
01181 if (nd == 0) {
01182
01183 TRACE(XERR, "no security directives: strong authentication disabled");
01184 return 0;
01185 }
01186
01187 TRACE(XERR, "creating temporary config file");
01188 return 0;
01189 }
01190
01191
01192 XrdSecService *cia = 0;
01193 if (!(cia = (*ep)((fEDest ? fEDest->logger() : (XrdSysLogger *)0), rcfn))) {
01194 TRACE(XERR, "Unable to create security service object via " << seclib);
01195 return 0;
01196 }
01197
01198 TRACE(ALL, "strong authentication enabled");
01199
01200
01201 unlink(rcfn);
01202 delete[] rcfn;
01203
01204
01205 return cia;
01206 }
01207
01208
01209 char *XrdProofdClientMgr::FilterSecConfig(int &nd)
01210 {
01211
01212
01213
01214
01215
01216
01217
01218
01219 XPDLOC(CMGR, "ClientMgr::FilterSecConfig")
01220
01221 static const char *pfx[] = { "xpd.sec.", "sec.protparm", "sec.protocol", "set" };
01222 char *rcfn = 0;
01223
01224 TRACE(REQ, "enter");
01225
01226 const char *cfn = CfgFile();
01227
01228
01229
01230 FILE *fin = 0;
01231 if (!cfn || !(fin = fopen(cfn,"r"))) {
01232 nd = (errno > 0) ? -errno : -1;
01233 return rcfn;
01234 }
01235
01236
01237
01238 int fd = -1;
01239 char lin[2048];
01240 while (fgets(lin,sizeof(lin),fin)) {
01241 if (!strncmp(lin, pfx[0], strlen(pfx[0])) ||
01242 !strncmp(lin, pfx[1], strlen(pfx[1])) ||
01243 !strncmp(lin, pfx[2], strlen(pfx[2])) ||
01244 !strncmp(lin, pfx[3], strlen(pfx[3]))) {
01245
01246 nd++;
01247
01248 if (!rcfn) {
01249 rcfn = new char[strlen(fMgr->TMPdir()) + strlen("/xpdcfn_XXXXXX") + 2];
01250 sprintf(rcfn, "%s/xpdcfn_XXXXXX", fMgr->TMPdir());
01251 if ((fd = mkstemp(rcfn)) < 0) {
01252 delete[] rcfn;
01253 nd = (errno > 0) ? -errno : -1;
01254 fclose(fin);
01255 rcfn = 0;
01256 return rcfn;
01257 }
01258 }
01259 XrdOucString slin = lin;
01260
01261 if (slin.beginswith("xpd.")) slin.replace("xpd.","");
01262
01263 fMgr->ResolveKeywords(slin, 0);
01264
01265 XrdProofdAux::Write(fd, slin.c_str(), slin.length());
01266 }
01267 }
01268
01269
01270 fclose(fin);
01271 close(fd);
01272
01273 return rcfn;
01274 }
01275
01276
01277 XrdProofdClient *XrdProofdClientMgr::GetClient(const char *usr, const char *grp,
01278 bool create)
01279 {
01280
01281
01282
01283 XPDLOC(CMGR, "ClientMgr::GetClient")
01284
01285 TRACE(DBG, "usr: "<< (usr ? usr : "undef")<<", grp:"<<(grp ? grp : "undef"));
01286
01287 XrdOucString dmsg, emsg;
01288 XrdProofdClient *c = 0;
01289 bool newclient = 0;
01290 std::list<XrdProofdClient *>::iterator i;
01291
01292 { XrdSysMutexHelper mh(fMutex);
01293 for (i = fProofdClients.begin(); i != fProofdClients.end(); ++i) {
01294 if ((c = *i) && c->Match(usr,grp)) break;
01295 c = 0;
01296 }
01297 }
01298
01299 if (!c && create) {
01300
01301 XrdProofUI ui;
01302 bool su;
01303 if (fMgr->CheckUser(usr, ui, emsg, su) == 0) {
01304
01305
01306 ui.fUser = usr;
01307 ui.fGroup = grp;
01308 bool full = (fMgr->SrvType() != kXPD_Worker) ? 1 : 0;
01309 c = new XrdProofdClient(ui, full, fMgr->ChangeOwn(), fEDest, fClntAdminPath.c_str());
01310 newclient = 1;
01311 bool freeclient = 1;
01312 if (c && c->IsValid()) {
01313
01314 if (fMgr->GroupsMgr() && fMgr->GroupsMgr()->Num() > 0) {
01315 XrdProofGroup *g = fMgr->GroupsMgr()->GetUserGroup(usr, grp);
01316 if (g) {
01317 c->SetGroup(g->Name());
01318 } else if (TRACING(XERR)) {
01319 emsg = "group = "; emsg += grp; emsg += " nor found";
01320 }
01321 }
01322 { XrdSysMutexHelper mh(fMutex);
01323 XrdProofdClient *nc = 0;
01324 for (i = fProofdClients.begin(); i != fProofdClients.end(); ++i) {
01325 if ((nc = *i) && nc->Match(usr,grp)) break;
01326 nc = 0;
01327 newclient = 0;
01328 }
01329 if (!nc) {
01330
01331 fProofdClients.push_back(c);
01332 freeclient = 0;
01333 }
01334 }
01335 if (freeclient) {
01336 delete c;
01337 } else if (TRACING(DBG)) {
01338 XPDFORM(dmsg, "instance for {client, group} = {%s, %s} created"
01339 " and added to the list (%p)", usr, grp, c);
01340 }
01341 } else {
01342 if (TRACING(XERR)) {
01343 XPDFORM(dmsg, "instance for {client, group} = {%s, %s} is invalid", usr, grp);
01344 }
01345 SafeDelete(c);
01346 }
01347 } else {
01348 if (TRACING(XERR)) {
01349 XPDFORM(dmsg, "client '%s' unknown or unauthorized: %s", usr, emsg.c_str());
01350 }
01351 }
01352 }
01353
01354
01355 if (c && !newclient) {
01356 if (c->TrimSessionDirs() != 0) {
01357 if (TRACING(XERR)) {
01358 XPDFORM(dmsg, "problems trimming client '%s' sandbox", usr);
01359 }
01360 }
01361 }
01362
01363 if (dmsg.length() > 0) {
01364 if (TRACING(DBG)) {
01365 TRACE(DBG, dmsg);
01366 } else {
01367 if (emsg.length() > 0) TRACE(XERR, emsg);
01368 TRACE(XERR, dmsg);
01369 }
01370 }
01371
01372
01373 return c;
01374 }
01375
01376
01377 void XrdProofdClientMgr::Broadcast(XrdProofdClient *clnt, const char *msg)
01378 {
01379
01380
01381
01382
01383 std::list<XrdProofdClient *> *clnts;
01384 if (!clnt) {
01385
01386 clnts = &fProofdClients;
01387 } else {
01388 clnts = new std::list<XrdProofdClient *>;
01389 clnts->push_back(clnt);
01390 }
01391
01392
01393 XrdProofdClient *c = 0;
01394 std::list<XrdProofdClient *>::iterator i;
01395 XrdSysMutexHelper mh(fMutex);
01396 for (i = clnts->begin(); i != clnts->end(); ++i) {
01397 if ((c = *i))
01398 c->Broadcast(msg);
01399 }
01400
01401
01402 if (clnt) delete clnts;
01403 }
01404
01405
01406 void XrdProofdClientMgr::TerminateSessions(XrdProofdClient *clnt, const char *msg,
01407 int srvtype)
01408 {
01409
01410
01411 XPDLOC(CMGR, "ClientMgr::TerminateSessions")
01412
01413
01414 bool all = 0;
01415 std::list<XrdProofdClient *> *clnts;
01416 if (!clnt) {
01417
01418 clnts = &fProofdClients;
01419 all = 1;
01420 } else {
01421 clnts = new std::list<XrdProofdClient *>;
01422 clnts->push_back(clnt);
01423 }
01424
01425
01426
01427 XrdProofdClient *c = 0;
01428 std::list<XrdProofdClient *>::iterator i;
01429 XrdSysMutexHelper mh(fMutex);
01430 for (i = clnts->begin(); i != clnts->end(); ++i) {
01431 if ((c = *i)) {
01432
01433 c->Broadcast(msg);
01434 }
01435 }
01436
01437 TRACE(DBG, "cleaning "<<all);
01438
01439 if (fMgr && fMgr->SessionMgr()) {
01440 int rc = 0;
01441 XrdOucString buf;
01442 XPDFORM(buf, "%s %d", (all ? "all" : clnt->User()), srvtype);
01443 TRACE(DBG, "posting: "<<buf);
01444 if ((rc = fMgr->SessionMgr()->Pipe()->Post(XrdProofdProofServMgr::kCleanSessions,
01445 buf.c_str())) != 0) {
01446 TRACE(XERR, "problem posting the pipe; errno: "<<-rc);
01447 }
01448 }
01449
01450
01451 for (i = clnts->begin(); i != clnts->end(); ++i) {
01452 if ((c = *i))
01453 c->ResetSessions();
01454 }
01455
01456
01457 if (clnt) delete clnts;
01458 }