/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed */ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, union sockaddr_union *them) { char *save_hosts_allow_table, *save_hosts_deny_table; struct request_info ri; #if WITH_IP6 char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = ""; #else char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = ""; #endif int allow; if (!xfd->para.socket.ip.dolibwrap) { return 0; } if (us == NULL || them == NULL) { return -1; } #if defined(HAVE_HOSTS_ALLOW_TABLE) save_hosts_allow_table = hosts_allow_table; if (xfd->para.socket.ip.hosts_allow_table) { Debug1("hosts_allow_table = \"%s\"", xfd->para.socket.ip.hosts_allow_table); hosts_allow_table = xfd->para.socket.ip.hosts_allow_table; } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */ #if defined(HAVE_HOSTS_DENY_TABLE) save_hosts_deny_table = hosts_deny_table; if (xfd->para.socket.ip.hosts_deny_table) { Debug1("hosts_deny_table = \"%s\"", xfd->para.socket.ip.hosts_deny_table); hosts_deny_table = xfd->para.socket.ip.hosts_deny_table; } #endif /* defined(HAVE_HOSTS_DENY_TABLE) */ hosts_access_verbose = 32767; if (inet_ntop(them->soa.sa_family, #if WITH_IP6 them->soa.sa_family==PF_INET6 ? (void *)&them->ip6.sin6_addr : #endif (void *)&them->ip4.sin_addr, clientaddr, sizeof(clientaddr)) == NULL) { Warn1("inet_ntop(): %s", strerror(errno)); } if (inet_ntop(us->soa.sa_family, #if WITH_IP6 us->soa.sa_family==PF_INET6 ? (void *)&us->ip6.sin6_addr : #endif (void *)&us->ip4.sin_addr, serveraddr, sizeof(serveraddr)) == NULL) { Warn1("inet_ntop(): %s", strerror(errno)); } Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0", &ri, xfd->rfd, clientaddr, ntohs(((struct sockaddr_in *)them)->sin_port), serveraddr, ntohs(us->ip4.sin_port), xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p')); request_init(&ri, RQ_FILE, xfd->rfd, RQ_CLIENT_SIN, them, RQ_SERVER_SIN, &us->soa, RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0); Debug("request_init() ->"); Debug1("sock_methods(%p)", &ri); sock_methods(&ri); Debug("sock_methods() ->"); Debug1("hosts_access(%p)", &ri); allow = hosts_access(&ri); Debug1("hosts_access() -> %d", allow); #if defined(HAVE_HOSTS_ALLOW_TABLE) hosts_allow_table = save_hosts_allow_table; #endif #if defined(HAVE_HOSTS_DENY_TABLE) hosts_deny_table = save_hosts_deny_table; #endif if (allow == 0) { return -1; } return 1; }
/* perform socks4 client dialog on existing FD. Called within fork/retry loop, after connect() */ int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, int level) { ssize_t bytes; int result; unsigned char buff[SIZEOF_STRUCT_SOCKS4]; struct socks4 *replyhead = (struct socks4 *)buff; char *destdomname = NULL; /* send socks header (target addr+port, +auth) */ #if WITH_MSGLEVEL <= E_INFO if (ntohl(sockhead->dest) <= 0x000000ff) { destdomname = strchr(sockhead->userid, '\0')+1; } Info11("sending socks4%s request VN=%d DC=%d DSTPORT=%d DSTIP=%d.%d.%d.%d USERID=%s%s%s", destdomname?"a":"", sockhead->version, sockhead->action, ntohs(sockhead->port), ((unsigned char *)&sockhead->dest)[0], ((unsigned char *)&sockhead->dest)[1], ((unsigned char *)&sockhead->dest)[2], ((unsigned char *)&sockhead->dest)[3], sockhead->userid, destdomname?" DESTNAME=":"", destdomname?destdomname:""); #endif /* WITH_MSGLEVEL <= E_INFO */ #if WITH_MSGLEVEL <= E_DEBUG { char *msgbuff; if ((msgbuff = Malloc(3*headlen)) != NULL) { xiohexdump((const unsigned char *)sockhead, headlen, msgbuff); Debug1("sending socks4(a) request data %s", msgbuff); } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ if (writefull(xfd->fd, sockhead, headlen) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", xfd->fd, sockhead, headlen, strerror(errno)); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } return STAT_RETRYLATER; /* retry complete open cycle */ } bytes = 0; Info("waiting for socks reply"); while (bytes >= 0) { /* loop over answer chunks until complete or error */ /* receive socks answer */ do { result = Read(xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, strerror(errno)); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } } if (result == 0) { Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server"); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } return STAT_RETRYLATER; } #if WITH_MSGLEVEL <= E_DEBUG { char msgbuff[3*SIZEOF_STRUCT_SOCKS4]; * xiohexdump((const unsigned char *)replyhead+bytes, result, msgbuff) = '\0'; Debug2("received socks4 reply data (offset "F_Zd"): %s", bytes, msgbuff); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ bytes += result; if (bytes == SIZEOF_STRUCT_SOCKS4) { Debug1("received all "F_Zd" bytes", bytes); break; } Debug2("received %d bytes, waiting for "F_Zu" more bytes", result, SIZEOF_STRUCT_SOCKS4-bytes); } if (result <= 0) { /* we had a problem while reading socks answer */ return STAT_RETRYLATER; /* retry complete open cycle */ } Info7("received socks reply VN=%u CD=%u DSTPORT=%u DSTIP=%u.%u.%u.%u", replyhead->version, replyhead->action, ntohs(replyhead->port), ((uint8_t *)&replyhead->dest)[0], ((uint8_t *)&replyhead->dest)[1], ((uint8_t *)&replyhead->dest)[2], ((uint8_t *)&replyhead->dest)[3]); if (replyhead->version != 0) { Warn1("socks: reply code version is not 0 (%d)", replyhead->version); } switch (replyhead->action) { case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ #if 0 if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &us, uslen, strerror(errno)); } Notice1("successfully connected from %s via socks4", sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); #else Notice("successfully connected via socks4"); #endif break; case SOCKS_CD_FAILED: Msg(level, "socks: connect request rejected or failed"); return STAT_RETRYLATER; case SOCKS_CD_NOIDENT: Msg(level, "socks: ident refused by client"); return STAT_RETRYLATER; case SOCKS_CD_IDENTFAILED: Msg(level, "socks: ident failed"); return STAT_RETRYLATER; default: Msg1(level, "socks: undefined status %u", replyhead->action); } return STAT_OK; }
/* ************************************************************************** ** * Print the buffer content via Debug1(), then reset the buffer. * * Input: none * Output: none * * ************************************************************************** ** */ static void bufr_print( void ) { format_bufr[format_pos] = '\0'; (void)Debug1( "%s", format_bufr ); format_pos = 0; } /* bufr_print */
static int IsCf3Scalar(char *str) { char *sp; char left = 'x', right = 'x'; int dollar = false; int bracks = 0, vars = 0; Debug1("IsCf3Scalar(%s) - syntax verify\n",str); if (str == NULL) { return false; } for (sp = str; *sp != '\0' ; sp++) /* check for varitems */ { switch (*sp) { case '$': if (*(sp+1) == '{' || *(sp+1) == '(') { dollar = true; } break; case '(': case '{': if (dollar) { left = *sp; bracks++; } break; case ')': case '}': if (dollar) { bracks--; right = *sp; } break; } /* Some chars cannot be in variable ids, e.g. $(/bin/cat file) is legal in bash */ if (bracks > 0) { switch (*sp) { case '/': return false; } } if (left == '(' && right == ')' && dollar && (bracks == 0)) { vars++; dollar=false; } if (left == '{' && right == '}' && dollar && (bracks == 0)) { vars++; dollar = false; } } if (dollar && (bracks != 0)) { char output[CF_BUFSIZE]; snprintf(output,CF_BUFSIZE,"Broken scalar variable syntax or bracket mismatch in \"%s\"",str); yyerror(output); return false; } Debug("Found %d variables in (%s)\n",vars,str); return vars; }
static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */ xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ) { int status; bool dash = false; int duptostderr; if (argc != 2) { Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1); } retropt_bool(opts, OPT_DASH, &dash); status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ const char *ends[] = { " ", NULL }; const char *hquotes[] = { "'", NULL }; const char *squotes[] = { "\"", NULL }; const char *nests[] = { "'", "'", "(", ")", "[", "]", "{", "}", NULL } ; char **pargv = NULL; int pargc; size_t len; const char *strp; char *token; /*! */ char *tokp; char *path = NULL; char *tmp; int numleft; /*! Close(something) */ /* parse command line */ Debug1("child: args = \"%s\"", argv[1]); pargv = Malloc(8*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; len = strlen(argv[1])+1; strp = argv[1]; token = Malloc(len); /*! */ tokp = token; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; pargv[0] = strrchr(tokp-1, '/'); if (pargv[0] == NULL) pargv[0] = token; else ++pargv[0]; pargc = 1; while (*strp == ' ') { while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } pargv[pargc++] = tokp; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; } pargv[pargc] = NULL; if ((tmp = Malloc(strlen(pargv[0])+2)) == NULL) { return STAT_RETRYLATER; } if (dash) { tmp[0] = '-'; strcpy(tmp+1, pargv[0]); } else { strcpy(tmp, pargv[0]); } pargv[0] = tmp; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Notice1("execvp'ing \"%s\"", token); Execvp(token, pargv); /* here we come only if execvp() failed */ switch (pargc) { case 1: Error3("execvp(\"%s\", \"%s\"): %s", token, pargv[0], strerror(errno)); break; case 2: Error4("execvp(\"%s\", \"%s\", \"%s\"): %s", token, pargv[0], pargv[1], strerror(errno)); break; case 3: default: Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token, pargv[0], pargv[1], pargv[2], strerror(errno)); break; } Exit(1); /* this child process */ } /* parent */ return 0; }
void AdviceManager::CancelAdvisorSession(gemActor *who, AdviceSession *adviceSession, const char * msg) { Debug1( LOG_ANY, adviceSession->AdviseeClientNum,"Advice session cancelling now.\n"); if ( adviceSession->GetAdvisee() ) { if ( ( who == NULL ) || (adviceSession->GetAdvisor() && who == adviceSession->GetAdvisor()->GetActor() ) ) { if ( adviceSession->AdviseeClientNum != (uint32_t)-1 ) { psserver->SendSystemInfo(adviceSession->AdviseeClientNum,"Your advice session has %s.", msg); switch ( adviceSession->status ) { case SESSION_STATUS_OWNED: psserver->SendSystemInfo(adviceSession->AdviseeClientNum,"Your next request may be handled by a different advisor."); if ( adviceSession->requestEvent) { adviceSession->requestEvent->valid = false; adviceSession->requestEvent = NULL; } adviceSession->answered = true; break; case SESSION_STATUS_CLAIMED: psserver->SendSystemInfo(adviceSession->AdviseeClientNum,"Your request will be sent to all advisors."); break; case SESSION_STATUS_UNKNOWN: break; } } } } if ( adviceSession->GetAdvisor() ) { if ( ( who == NULL ) || ( ( adviceSession->GetAdvisee() && who == adviceSession->GetAdvisee()->GetActor() ) ) ) { if ( adviceSession->AdvisorClientNum != (uint32_t)-1 ) { if ( who == adviceSession->GetAdvisor()->GetActor() || who == NULL ) { switch ( adviceSession->status ) { case SESSION_STATUS_OWNED: psserver->SendSystemInfo(adviceSession->AdvisorClientNum,"Your advice session with %s has %s.",adviceSession->adviseeName.GetData(), msg); break; case SESSION_STATUS_CLAIMED: psserver->SendSystemInfo(adviceSession->AdvisorClientNum,"You have forfieted your session with %s.",adviceSession->adviseeName.GetData()); // Notify all other advisors for ( size_t i = 0; i < advisors.GetSize(); i++ ) { if ( advisors[i].id != adviceSession->AdvisorClientNum ) psserver->SendSystemInfo(advisors[i].id,"%s has relinquished their claim as %s's advisor.",adviceSession->GetAdvisor()->GetName(), adviceSession->adviseeName.GetData() ); } adviceSession->SetAdvisor( NULL ); break; case SESSION_STATUS_UNKNOWN: break; } } else { psserver->SendSystemInfo(adviceSession->AdvisorClientNum,"Your advice session with %s has %s.",adviceSession->adviseeName.GetData(), msg); } } } } adviceSession->status = SESSION_STATUS_UNKNOWN; }
void CharCreationManager::HandleUploadMessage(MsgEntry* me, Client* client) { Debug1(LOG_NEWCHAR, me->clientnum,"New Character is being created"); psCharUploadMessage upload(me); if(!upload.valid) { Debug2(LOG_NET,me->clientnum,"Received unparsable psUploadMessage from client %u.",me->clientnum); return; } AccountID acctID = client->GetAccountID(); if(!acctID.IsValid()) { Error2("Player tried to upload a character to unknown account %s.", ShowID(acctID)); psCharRejectedMessage reject(me->clientnum); psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET); psserver->RemovePlayer(me->clientnum,"Could not find your account."); return; } // Check to see if the player already has 4 accounts; csString query; query.Format("SELECT id FROM characters WHERE account_id=%d", acctID.Unbox()); Result result(db->Select(query)); if(result.IsValid() && result.Count() >= CHARACTERS_ALLOWED) { psserver->RemovePlayer(me->clientnum,"At your character limit."); return; } csString playerName = upload.name; csString lastName = upload.lastname; playerName = NormalizeCharacterName(playerName); lastName = NormalizeCharacterName(lastName); // Check banned names if(psserver->GetCharManager()->IsBanned(playerName)) { csString error; error.Format("The name %s is banned", playerName.GetData()); psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::RESERVED_NAME, (char*)error.GetData()); reject.SendMessage(); return; } if(psserver->GetCharManager()->IsBanned(lastName)) { csString error; error.Format("The lastname %s is banned", lastName.GetData()); psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::RESERVED_NAME, (char*)error.GetData()); reject.SendMessage(); return; } Debug3(LOG_NEWCHAR, me->clientnum,"Got player firstname (%s) and lastname (%s)\n",playerName.GetData(), lastName.GetData()); /////////////////////////////////////////////////////////////// // Check to see if the player name is valid /////////////////////////////////////////////////////////////// if(playerName.Length() == 0 || !FilterName(playerName)) { psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::NON_LEGAL_NAME, "The name you specifed is not a legal player name."); psserver->GetEventManager()->SendMessage(reject.msg); return; } if(lastName.Length() != 0 && !FilterName(lastName)) { psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::NON_LEGAL_NAME, "The name you specifed is not a legal lastname."); psserver->GetEventManager()->SendMessage(reject.msg); return; } Debug2(LOG_NEWCHAR, me->clientnum,"Checking player firstname '%s'..\n",playerName.GetData()); /////////////////////////////////////////////////////////////// // Check to see if the character name is unique in 'characters'. /////////////////////////////////////////////////////////////// if(!IsUnique(playerName)) { psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::NON_UNIQUE_NAME, "The firstname you specifed is not unique."); psserver->GetEventManager()->SendMessage(reject.msg); return; } if(lastName.Length()) { Debug2(LOG_NEWCHAR, me->clientnum,"Checking player lastname '%s'..\n",lastName.GetData()); if(!IsLastNameAvailable(lastName, acctID)) { psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::NON_UNIQUE_NAME, "The lastname you specifed is not unique."); psserver->GetEventManager()->SendMessage(reject.msg); return; } } /////////////////////////////////////////////////////////////// // Check to see if the character name is on the reserve list. /////////////////////////////////////////////////////////////// int reservedName = IsReserved(playerName, acctID); if(reservedName == NAME_RESERVED) { csString error; error.Format("The name %s is reserved", playerName.GetData()); psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::RESERVED_NAME, (char*)error.GetData()); psserver->GetEventManager()->SendMessage(reject.msg); return; } csString error; if(!psserver->charCreationManager->Validate(upload, error)) { error.Append(", your creation choices are invalid."); psCharRejectedMessage reject(me->clientnum, psCharRejectedMessage::INVALID_CREATION, (char*)error.GetData()); reject.SendMessage(); return; } /////////////////////////////////////////////////////////////// // Create the psCharacter structure for the player. /////////////////////////////////////////////////////////////// psCharacter* chardata=new psCharacter(); chardata->SetCharType(PSCHARACTER_TYPE_PLAYER); chardata->SetFullName(playerName,lastName); chardata->SetCreationInfo(upload.bio); psRaceInfo* raceinfo=psserver->GetCacheManager()->GetRaceInfoByNameGender(upload.race, (PSCHARACTER_GENDER)upload.gender); if(raceinfo==NULL) { Error3("Invalid race/gender combination on character creation: Race='%d' Gender='%d'", upload.race, upload.gender); psCharRejectedMessage reject(me->clientnum); psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET); psserver->RemovePlayer(me->clientnum,"Player tried to create an invalid race/gender."); delete chardata; return; } chardata->SetRaceInfo(raceinfo); chardata->SetHitPoints(50.0); chardata->GetMaxHP().SetBase(0.0); chardata->GetMaxMana().SetBase(0.0); //range is unused here float x,y,z,yrot,range; const char* sectorname; InstanceID newinstance = DEFAULT_INSTANCE; //get the option entries for tutorial from the server options. Note it's tutorial:variousdata optionEntry* tutorialEntry = psserver->GetCacheManager()->getOptionSafe("tutorial",""); sectorname = tutorialEntry->getOptionSafe("sectorname", "tutorial")->getValue(); psSectorInfo* sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName(sectorname); if(!sectorinfo || PlayerHasFinishedTutorial(acctID, sectorinfo->uid)) { raceinfo->GetStartingLocation(x,y,z,yrot,range,sectorname); sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName(sectorname); //As we aren't going in the tutorial disable the tutorial help messages disable them for(int i = 0; i < TutorialManager::TUTOREVENTTYPE_COUNT; i++) chardata->CompleteHelpEvent(i); } else { // Try tutorial level first. x = tutorialEntry->getOptionSafe("sectorx", "-225.37")->getValueAsDouble(); y = tutorialEntry->getOptionSafe("sectory", "-21.32")->getValueAsDouble(); z = tutorialEntry->getOptionSafe("sectorz", "26.79")->getValueAsDouble(); yrot = tutorialEntry->getOptionSafe("sectoryrot", "-2.04")->getValueAsDouble(); } bool sectorFound = true; if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name) == NULL) { Error2("Sector='%s' found but no map file was detected for it. Using NPCroom1", sectorname); sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName("NPCroom1"); if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name) == NULL) { Error1("NPCroom1 failed - Critical"); sectorFound = false; } else if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name)) { sectorFound = true; } else { sectorFound = false; } } else if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name)) { sectorFound = true; } else { sectorFound = false; } if(!sectorFound) { Error2("Unresolvable starting sector='%s'", sectorname); psCharRejectedMessage reject(me->clientnum); psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET); psserver->RemovePlayer(me->clientnum,"No starting Sector."); delete chardata; return; } chardata->SetLocationInWorld(newinstance, sectorinfo, x, y, z, yrot); psTrait* trait; // CPrintf(CON_DEBUG, "Trait: %d\n", upload.selectedFace ); trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedFace); if(trait) chardata->SetTraitForLocation(trait->location, trait); trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedHairStyle); if(trait) chardata->SetTraitForLocation(trait->location, trait); trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedBeardStyle); if(trait) chardata->SetTraitForLocation(trait->location, trait); trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedHairColour); if(trait) chardata->SetTraitForLocation(trait->location, trait); trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedSkinColour); if(trait) chardata->SetTraitForLocation(trait->location, trait); gemActor* actor = new gemActor(gemSupervisor, cacheManager, entityManager, chardata, raceinfo->mesh_name, newinstance, EntityManager::GetSingleton().FindSector(sectorinfo->name), csVector3(x,y,z),yrot, client->GetClientNum()); actor->SetupCharData(); if(!upload.verify) { if(!psServer::CharacterLoader.NewCharacterData(acctID,chardata)) { Error1("Character could not be created."); psCharRejectedMessage reject(me->clientnum); psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET); psserver->RemovePlayer(me->clientnum,"Your character could not be created in the database."); delete chardata; return; } } // Check to see if a path name was set. If so we will use that to generate // the character starting stats and skills. if(upload.path != "None") { // Progression Event name is PATH_PathName csString name("PATH_"); name.Append(upload.path); ProgressionScript* script = psserver->GetProgressionManager()->FindScript(name.GetData()); if(script) { // The script uses the race base character points to calculate starting stats. MathEnvironment env; env.Define("CharPoints", raceinfo->initialCP); env.Define("Actor", actor); script->Run(&env); } } else { //int cpUsage = psserver->charCreationManager->CalculateCPChoice( upload.choices ) + // psserver->charCreationManager->CalculateCPLife(upload.lifeEvents ); for(size_t ci = 0; ci < upload.choices.GetSize(); ci++) { CharCreationManager::CreationChoice* choice = psserver->charCreationManager->FindChoice(upload.choices[ci]); if(choice) { csString name(psserver->charCreationManager->FindChoice(upload.choices[ci])->name.GetData()); Debug3(LOG_NEWCHAR, me->clientnum,"Choice: %s Creation Script: %s", name.GetData(), choice->eventScript.GetData()); MathEnvironment env; env.Define("Actor", actor); if(choice->choiceArea == FATHER_JOB || choice->choiceArea == MOTHER_JOB) { int modifier = (choice->choiceArea == FATHER_JOB) ? upload.fatherMod : upload.motherMod; if(modifier > 3 || modifier < 1) modifier = 1; env.Define("ParentStatus", modifier); } ProgressionScript* script = psserver->GetProgressionManager()->FindScript(choice->eventScript); if(script) script->Run(&env); } else { Debug2(LOG_NEWCHAR, me->clientnum,"Character Choice %d not found\n", upload.choices[ci]); } } for(size_t li = 0; li < upload.lifeEvents.GetSize(); li++) { MathEnvironment env; env.Define("Actor", actor); LifeEventChoiceServer* lifeEvent = psserver->charCreationManager->FindLifeEvent(upload.lifeEvents[li]); if(!lifeEvent) { Error2("No LifeEvent Script found: %d", upload.lifeEvents[li]); continue; } csString scriptName(lifeEvent->eventScript.GetData()); Debug2(LOG_NEWCHAR, me->clientnum, "LifeEvent Script: %s", scriptName.GetDataSafe()); ProgressionScript* script = psserver->GetProgressionManager()->FindScript(scriptName); if(script) script->Run(&env); } } if(!upload.verify) { if(reservedName == NAME_RESERVED_FOR_YOU) { AssignScript(chardata); } // This function recalculates the Max HP, Mana and Stamina of the new character chardata->RecalculateStats(); // Make sure the new player have HP, Mana and Samina that was calculated chardata->SetHitPoints(chardata->GetMaxHP().Base()); chardata->SetMana(chardata->GetMaxMana().Base()); chardata->SetStamina(chardata->GetMaxPStamina().Base(),true); chardata->SetStamina(chardata->GetMaxMStamina().Base(),false); psServer::CharacterLoader.SaveCharacterData(chardata, actor); Debug1(LOG_NEWCHAR,me->clientnum,"Player Creation Complete"); // Remove cached objects to make sure that the client gets a fresh character // list from the database if it logs out and in within 2 minutes. iCachedObject* obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("list",client->GetAccountID().Unbox())); if(obj) { obj->ProcessCacheTimeout(); obj->DeleteSelf(); } obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("auth",client->GetAccountID().Unbox())); if(obj) { obj->ProcessCacheTimeout(); obj->DeleteSelf(); } // Here everything is ok client->SetPID(chardata->GetPID()); client->SetName(playerName); psCharApprovedMessage app(me->clientnum); if(app.valid) psserver->GetEventManager()->SendMessage(app.msg); else Bug2("Could not create valid psCharApprovedMessage for client %u.\n",me->clientnum); } else { psCharVerificationMesg mesg(me->clientnum); size_t z; //unfortunately count goes out of valid area so we need to check on charisma for(z = 0; z < psserver->GetCacheManager()->GetSkillAmount(); z++) { unsigned int rank = chardata->Skills().GetSkillRank((PSSKILL) z).Base(); psSkillInfo* info = psserver->GetCacheManager()->GetSkillByID(z); csString name("Not found"); if(info) name.Replace(info->name); if(rank > 0) { if(z >= PSSKILL_AGI && z <= PSSKILL_WILL) { mesg.AddStat(rank, name); } else { mesg.AddSkill(rank, name); } } } mesg.Construct(); mesg.SendMessage(); } delete actor; if(!upload.verify) { // Remove char data from the cache iCachedObject* obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("char", chardata->GetPID().Unbox())); if(obj) { obj->ProcessCacheTimeout(); obj->DeleteSelf(); } } }
void Usleep(unsigned long usec) { Debug1("usleep(%lu)", usec); usleep(usec); Debug("usleep() ->"); return; }
void Exit(int status) { Debug1("exit(%d)", status); exit(status); }
/* protected by res_mutex */ static int wait4msg( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, LDAPMessage **result ) { int rc; struct timeval tv = { 0 }, tv0 = { 0 }, start_time_tv = { 0 }, *tvp = NULL; LDAPConn *lc; assert( ld != NULL ); assert( result != NULL ); LDAP_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex ); if ( timeout == NULL && ld->ld_options.ldo_tm_api.tv_sec >= 0 ) { tv = ld->ld_options.ldo_tm_api; timeout = &tv; } #ifdef LDAP_DEBUG if ( timeout == NULL ) { Debug2( LDAP_DEBUG_TRACE, "wait4msg ld %p msgid %d (infinite timeout)\n", (void *)ld, msgid ); } else { Debug3( LDAP_DEBUG_TRACE, "wait4msg ld %p msgid %d (timeout %ld usec)\n", (void *)ld, msgid, (long)timeout->tv_sec * 1000000 + timeout->tv_usec ); } #endif /* LDAP_DEBUG */ if ( timeout != NULL && timeout->tv_sec != -1 ) { tv0 = *timeout; tv = *timeout; tvp = &tv; #ifdef HAVE_GETTIMEOFDAY gettimeofday( &start_time_tv, NULL ); #else /* ! HAVE_GETTIMEOFDAY */ start_time_tv.tv_sec = time( NULL ); start_time_tv.tv_usec = 0; #endif /* ! HAVE_GETTIMEOFDAY */ } rc = LDAP_MSG_X_KEEP_LOOKING; while ( rc == LDAP_MSG_X_KEEP_LOOKING ) { #ifdef LDAP_DEBUG if ( ldap_debug & LDAP_DEBUG_TRACE ) { Debug3( LDAP_DEBUG_TRACE, "wait4msg continue ld %p msgid %d all %d\n", (void *)ld, msgid, all ); ldap_dump_connection( ld, ld->ld_conns, 1 ); LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); ldap_dump_requests_and_responses( ld ); LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); } #endif /* LDAP_DEBUG */ if ( ( *result = chkResponseList( ld, msgid, all ) ) != NULL ) { rc = (*result)->lm_msgtype; } else { int lc_ready = 0; LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) { if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) { lc_ready = 2; /* ready at ber level, not socket level */ break; } } if ( !lc_ready ) { int err; rc = ldap_int_select( ld, tvp ); if ( rc == -1 ) { err = sock_errno(); #ifdef LDAP_DEBUG Debug1( LDAP_DEBUG_TRACE, "ldap_int_select returned -1: errno %d\n", err ); #endif } if ( rc == 0 || ( rc == -1 && ( !LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART) || err != EINTR ) ) ) { ld->ld_errno = (rc == -1 ? LDAP_SERVER_DOWN : LDAP_TIMEOUT); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); return( rc ); } if ( rc == -1 ) { rc = LDAP_MSG_X_KEEP_LOOKING; /* select interrupted: loop */ } else { lc_ready = 1; } } if ( lc_ready ) { LDAPConn *lnext; int serviced = 0; rc = LDAP_MSG_X_KEEP_LOOKING; LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); if ( ld->ld_requests && ld->ld_requests->lr_status == LDAP_REQST_WRITING && ldap_is_write_ready( ld, ld->ld_requests->lr_conn->lconn_sb ) ) { serviced = 1; ldap_int_flush_request( ld, ld->ld_requests ); } for ( lc = ld->ld_conns; rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL; lc = lnext ) { if ( lc->lconn_status == LDAP_CONNST_CONNECTED && ldap_is_read_ready( ld, lc->lconn_sb ) ) { serviced = 1; /* Don't let it get freed out from under us */ ++lc->lconn_refcnt; rc = try_read1msg( ld, msgid, all, lc, result ); lnext = lc->lconn_next; /* Only take locks if we're really freeing */ if ( lc->lconn_refcnt <= 1 ) { ldap_free_connection( ld, lc, 0, 1 ); } else { --lc->lconn_refcnt; } } else { lnext = lc->lconn_next; } } LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); /* Quit looping if no one handled any socket events */ if (!serviced && lc_ready == 1) rc = -1; } LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); } if ( rc == LDAP_MSG_X_KEEP_LOOKING && tvp != NULL ) { struct timeval curr_time_tv = { 0 }, delta_time_tv = { 0 }; #ifdef HAVE_GETTIMEOFDAY gettimeofday( &curr_time_tv, NULL ); #else /* ! HAVE_GETTIMEOFDAY */ curr_time_tv.tv_sec = time( NULL ); curr_time_tv.tv_usec = 0; #endif /* ! HAVE_GETTIMEOFDAY */ /* delta_time = tmp_time - start_time */ delta_time_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec; delta_time_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec; if ( delta_time_tv.tv_usec < 0 ) { delta_time_tv.tv_sec--; delta_time_tv.tv_usec += 1000000; } /* tv0 < delta_time ? */ if ( ( tv0.tv_sec < delta_time_tv.tv_sec ) || ( ( tv0.tv_sec == delta_time_tv.tv_sec ) && ( tv0.tv_usec < delta_time_tv.tv_usec ) ) ) { rc = 0; /* timed out */ ld->ld_errno = LDAP_TIMEOUT; break; } /* tv0 -= delta_time */ tv0.tv_sec -= delta_time_tv.tv_sec; tv0.tv_usec -= delta_time_tv.tv_usec; if ( tv0.tv_usec < 0 ) { tv0.tv_sec--; tv0.tv_usec += 1000000; } tv.tv_sec = tv0.tv_sec; tv.tv_usec = tv0.tv_usec; Debug3( LDAP_DEBUG_TRACE, "wait4msg ld %p %ld s %ld us to go\n", (void *)ld, (long) tv.tv_sec, (long) tv.tv_usec ); start_time_tv.tv_sec = curr_time_tv.tv_sec; start_time_tv.tv_usec = curr_time_tv.tv_usec; } } return( rc ); }
/* protected by res_mutex, conn_mutex and req_mutex */ static ber_tag_t try_read1msg( LDAP *ld, ber_int_t msgid, int all, LDAPConn *lc, LDAPMessage **result ) { BerElement *ber; LDAPMessage *newmsg, *l, *prev; ber_int_t id; ber_tag_t tag; ber_len_t len; int foundit = 0; LDAPRequest *lr, *tmplr, dummy_lr = { 0 }; BerElement tmpber; int rc, refer_cnt, hadref, simple_request, err; ber_int_t lderr; #ifdef LDAP_CONNECTIONLESS LDAPMessage *tmp = NULL, *chain_head = NULL; int moremsgs = 0, isv2 = 0; #endif assert( ld != NULL ); assert( lc != NULL ); LDAP_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex ); LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex ); LDAP_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex ); Debug3( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d all %d\n", (void *)ld, msgid, all ); retry: if ( lc->lconn_ber == NULL ) { lc->lconn_ber = ldap_alloc_ber_with_options( ld ); if ( lc->lconn_ber == NULL ) { return -1; } } ber = lc->lconn_ber; assert( LBER_VALID (ber) ); /* get the next message */ sock_errset(0); #ifdef LDAP_CONNECTIONLESS if ( LDAP_IS_UDP(ld) ) { struct sockaddr_storage from; ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr_storage) ); if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1; } nextresp3: #endif tag = ber_get_next( lc->lconn_sb, &len, ber ); switch ( tag ) { case LDAP_TAG_MESSAGE: /* * We read a complete message. * The connection should no longer need this ber. */ lc->lconn_ber = NULL; break; case LBER_DEFAULT: err = sock_errno(); #ifdef LDAP_DEBUG Debug0( LDAP_DEBUG_CONNS, "ber_get_next failed.\n" ); #endif if ( err == EWOULDBLOCK ) return LDAP_MSG_X_KEEP_LOOKING; if ( err == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING; ld->ld_errno = LDAP_SERVER_DOWN; if ( !LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) { --lc->lconn_refcnt; } lc->lconn_status = 0; return -1; default: ld->ld_errno = LDAP_LOCAL_ERROR; return -1; } /* message id */ if ( ber_get_int( ber, &id ) == LBER_ERROR ) { ber_free( ber, 1 ); ld->ld_errno = LDAP_DECODING_ERROR; return( -1 ); } /* id == 0 iff unsolicited notification message (RFC 4511) */ /* id < 0 is invalid, just toss it. FIXME: should we disconnect? */ if ( id < 0 ) { goto retry_ber; } /* if it's been abandoned, toss it */ if ( id > 0 ) { if ( ldap_abandoned( ld, id ) ) { /* the message type */ tag = ber_peek_tag( ber, &len ); switch ( tag ) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_INTERMEDIATE: case LBER_ERROR: break; default: /* there's no need to keep the id * in the abandoned list any longer */ ldap_mark_abandoned( ld, id ); break; } Debug3( LDAP_DEBUG_ANY, "abandoned/discarded ld %p msgid %d message type %s\n", (void *)ld, id, ldap_int_msgtype2str( tag ) ); retry_ber: ber_free( ber, 1 ); if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) { goto retry; } return( LDAP_MSG_X_KEEP_LOOKING ); /* continue looking */ } lr = ldap_find_request_by_msgid( ld, id ); if ( lr == NULL ) { const char *msg = "unknown"; /* the message type */ tag = ber_peek_tag( ber, &len ); switch ( tag ) { case LBER_ERROR: break; default: msg = ldap_int_msgtype2str( tag ); break; } Debug3( LDAP_DEBUG_ANY, "no request for response on ld %p msgid %d message type %s (tossing)\n", (void *)ld, id, msg ); goto retry_ber; } #ifdef LDAP_CONNECTIONLESS if ( LDAP_IS_UDP(ld) && isv2 ) { ber_scanf(ber, "x{"); } nextresp2: ; #endif } /* the message type */ tag = ber_peek_tag( ber, &len ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 1 ); return( -1 ); } Debug3( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d message type %s\n", (void *)ld, id, ldap_int_msgtype2str( tag ) ); if ( id == 0 ) { /* unsolicited notification message (RFC 4511) */ if ( tag != LDAP_RES_EXTENDED ) { /* toss it */ goto retry_ber; /* strictly speaking, it's an error; from RFC 4511: 4.4. Unsolicited Notification An unsolicited notification is an LDAPMessage sent from the server to the client that is not in response to any LDAPMessage received by the server. It is used to signal an extraordinary condition in the server or in the LDAP session between the client and the server. The notification is of an advisory nature, and the server will not expect any response to be returned from the client. The unsolicited notification is structured as an LDAPMessage in which the messageID is zero and protocolOp is set to the extendedResp choice using the ExtendedResponse type (See Section 4.12). The responseName field of the ExtendedResponse always contains an LDAPOID that is unique for this notification. * however, since unsolicited responses * are of advisory nature, better * toss it, right now */ #if 0 ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 1 ); return( -1 ); #endif } lr = &dummy_lr; } id = lr->lr_origid; refer_cnt = 0; hadref = simple_request = 0; rc = LDAP_MSG_X_KEEP_LOOKING; /* default is to keep looking (no response found) */ lr->lr_res_msgtype = tag; /* * Check for V3 search reference */ if ( tag == LDAP_RES_SEARCH_REFERENCE ) { if ( ld->ld_version > LDAP_VERSION2 ) { /* This is a V3 search reference */ if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) || lr->lr_parent != NULL ) { char **refs = NULL; tmpber = *ber; /* Get the referral list */ if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) { rc = LDAP_DECODING_ERROR; } else { /* Note: refs array is freed by ldap_chase_v3referrals */ refer_cnt = ldap_chase_v3referrals( ld, lr, refs, 1, &lr->lr_res_error, &hadref ); if ( refer_cnt > 0 ) { /* successfully chased reference */ /* If haven't got end search, set chasing referrals */ if ( lr->lr_status != LDAP_REQST_COMPLETED ) { lr->lr_status = LDAP_REQST_CHASINGREFS; Debug1( LDAP_DEBUG_TRACE, "read1msg: search ref chased, " "mark request chasing refs, " "id = %d\n", lr->lr_msgid ); } } } } } } else if ( tag != LDAP_RES_SEARCH_ENTRY && tag != LDAP_RES_INTERMEDIATE ) { /* All results that just return a status, i.e. don't return data * go through the following code. This code also chases V2 referrals * and checks if all referrals have been chased. */ char *lr_res_error = NULL; tmpber = *ber; /* struct copy */ if ( ber_scanf( &tmpber, "{eAA", &lderr, &lr->lr_res_matched, &lr_res_error ) != LBER_ERROR ) { if ( lr_res_error != NULL ) { if ( lr->lr_res_error != NULL ) { (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); LDAP_FREE( (char *)lr_res_error ); } else { lr->lr_res_error = lr_res_error; } lr_res_error = NULL; } /* Do we need to check for referrals? */ if ( tag != LDAP_RES_BIND && ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) || lr->lr_parent != NULL )) { char **refs = NULL; ber_len_t len; /* Check if V3 referral */ if ( ber_peek_tag( &tmpber, &len ) == LDAP_TAG_REFERRAL ) { if ( ld->ld_version > LDAP_VERSION2 ) { /* Get the referral list */ if ( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) { rc = LDAP_DECODING_ERROR; lr->lr_status = LDAP_REQST_COMPLETED; Debug2( LDAP_DEBUG_TRACE, "read1msg: referral decode error, " "mark request completed, ld %p msgid %d\n", (void *)ld, lr->lr_msgid ); } else { /* Chase the referral * refs array is freed by ldap_chase_v3referrals */ refer_cnt = ldap_chase_v3referrals( ld, lr, refs, 0, &lr->lr_res_error, &hadref ); lr->lr_status = LDAP_REQST_COMPLETED; Debug3( LDAP_DEBUG_TRACE, "read1msg: referral %s chased, " "mark request completed, ld %p msgid %d\n", refer_cnt > 0 ? "" : "not", (void *)ld, lr->lr_msgid); if ( refer_cnt < 0 ) { refer_cnt = 0; } } } } else { switch ( lderr ) { case LDAP_SUCCESS: case LDAP_COMPARE_TRUE: case LDAP_COMPARE_FALSE: break; default: if ( lr->lr_res_error == NULL ) { break; } /* pedantic, should never happen */ if ( lr->lr_res_error[ 0 ] == '\0' ) { LDAP_FREE( lr->lr_res_error ); lr->lr_res_error = NULL; break; } /* V2 referrals are in error string */ refer_cnt = ldap_chase_referrals( ld, lr, &lr->lr_res_error, -1, &hadref ); lr->lr_status = LDAP_REQST_COMPLETED; Debug1( LDAP_DEBUG_TRACE, "read1msg: V2 referral chased, " "mark request completed, id = %d\n", lr->lr_msgid ); break; } } } /* save errno, message, and matched string */ if ( !hadref || lr->lr_res_error == NULL ) { lr->lr_res_errno = lderr == LDAP_PARTIAL_RESULTS ? LDAP_SUCCESS : lderr; } else if ( ld->ld_errno != LDAP_SUCCESS ) { lr->lr_res_errno = ld->ld_errno; } else { lr->lr_res_errno = LDAP_PARTIAL_RESULTS; } } /* in any case, don't leave any lr_res_error 'round */ if ( lr_res_error ) { LDAP_FREE( lr_res_error ); } Debug2( LDAP_DEBUG_TRACE, "read1msg: ld %p %d new referrals\n", (void *)ld, refer_cnt ); if ( refer_cnt != 0 ) { /* chasing referrals */ ber_free( ber, 1 ); ber = NULL; if ( refer_cnt < 0 ) { ldap_return_request( ld, lr, 0 ); return( -1 ); /* fatal error */ } lr->lr_res_errno = LDAP_SUCCESS; /* successfully chased referral */ if ( lr->lr_res_matched ) { LDAP_FREE( lr->lr_res_matched ); lr->lr_res_matched = NULL; } } else { if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL ) { /* request without any referrals */ simple_request = ( hadref ? 0 : 1 ); } else { /* request with referrals or child request */ ber_free( ber, 1 ); ber = NULL; } lr->lr_status = LDAP_REQST_COMPLETED; /* declare this request done */ Debug2( LDAP_DEBUG_TRACE, "read1msg: mark request completed, ld %p msgid %d\n", (void *)ld, lr->lr_msgid ); tmplr = lr; while ( lr->lr_parent != NULL ) { merge_error_info( ld, lr->lr_parent, lr ); lr = lr->lr_parent; if ( --lr->lr_outrefcnt > 0 ) { break; /* not completely done yet */ } } /* ITS#6744: Original lr was refcounted when we retrieved it, * must release it now that we're working with the parent */ if ( tmplr->lr_parent ) { ldap_return_request( ld, tmplr, 0 ); } /* Check if all requests are finished, lr is now parent */ tmplr = lr; if ( tmplr->lr_status == LDAP_REQST_COMPLETED ) { for ( tmplr = lr->lr_child; tmplr != NULL; tmplr = tmplr->lr_refnext ) { if ( tmplr->lr_status != LDAP_REQST_COMPLETED ) break; } } /* This is the parent request if the request has referrals */ if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL && tmplr == NULL ) { id = lr->lr_msgid; tag = lr->lr_res_msgtype; Debug2( LDAP_DEBUG_TRACE, "request done: ld %p msgid %d\n", (void *)ld, id ); Debug3( LDAP_DEBUG_TRACE, "res_errno: %d, res_error: <%s>, " "res_matched: <%s>\n", lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", lr->lr_res_matched ? lr->lr_res_matched : "" ); if ( !simple_request ) { ber_free( ber, 1 ); ber = NULL; if ( build_result_ber( ld, &ber, lr ) == LBER_ERROR ) { rc = -1; /* fatal error */ } } if ( lr != &dummy_lr ) { ldap_return_request( ld, lr, 1 ); } lr = NULL; } /* * RFC 4511 unsolicited (id == 0) responses * shouldn't necessarily end the connection */ if ( lc != NULL && id != 0 && !LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) { --lc->lconn_refcnt; lc = NULL; } } } if ( lr != NULL ) { if ( lr != &dummy_lr ) { ldap_return_request( ld, lr, 0 ); } lr = NULL; } if ( ber == NULL ) { return( rc ); } /* try to handle unsolicited responses as appropriate */ if ( id == 0 && msgid > LDAP_RES_UNSOLICITED ) { int is_nod = 0; tag = ber_peek_tag( &tmpber, &len ); /* we have a res oid */ if ( tag == LDAP_TAG_EXOP_RES_OID ) { static struct berval bv_nod = BER_BVC( LDAP_NOTICE_OF_DISCONNECTION ); struct berval resoid = BER_BVNULL; if ( ber_scanf( &tmpber, "m", &resoid ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 1 ); return -1; } assert( !BER_BVISEMPTY( &resoid ) ); is_nod = ber_bvcmp( &resoid, &bv_nod ) == 0; tag = ber_peek_tag( &tmpber, &len ); } #if 0 /* don't need right now */ /* we have res data */ if ( tag == LDAP_TAG_EXOP_RES_VALUE ) { struct berval resdata; if ( ber_scanf( &tmpber, "m", &resdata ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } /* use it... */ } #endif /* handle RFC 4511 "Notice of Disconnection" locally */ if ( is_nod ) { if ( tag == LDAP_TAG_EXOP_RES_VALUE ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 1 ); return -1; } /* get rid of the connection... */ if ( lc != NULL && !LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) { --lc->lconn_refcnt; } /* need to return -1, because otherwise * a valid result is expected */ ld->ld_errno = lderr; return -1; } } /* make a new ldap message */ newmsg = (LDAPMessage *) LDAP_CALLOC( 1, sizeof(LDAPMessage) ); if ( newmsg == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( -1 ); } newmsg->lm_msgid = (int)id; newmsg->lm_msgtype = tag; newmsg->lm_ber = ber; newmsg->lm_chain_tail = newmsg; #ifdef LDAP_CONNECTIONLESS /* CLDAP replies all fit in a single datagram. In LDAPv2 RFC1798 * the responses are all a sequence wrapped in one message. In * LDAPv3 each response is in its own message. The datagram must * end with a SearchResult. We can't just parse each response in * separate calls to try_read1msg because the header info is only * present at the beginning of the datagram, not at the beginning * of each response. So parse all the responses at once and queue * them up, then pull off the first response to return to the * caller when all parsing is complete. */ if ( LDAP_IS_UDP(ld) ) { /* If not a result, look for more */ if ( tag != LDAP_RES_SEARCH_RESULT ) { int ok = 0; moremsgs = 1; if (isv2) { /* LDAPv2: dup the current ber, skip past the current * response, and see if there are any more after it. */ ber = ber_dup( ber ); ber_scanf( ber, "x" ); if ( ber_peek_tag( ber, &len ) != LBER_DEFAULT ) { /* There's more - dup the ber buffer so they can all be * individually freed by ldap_msgfree. */ struct berval bv; ber_get_option( ber, LBER_OPT_BER_REMAINING_BYTES, &len ); bv.bv_val = LDAP_MALLOC( len ); if ( bv.bv_val ) { ok = 1; ber_read( ber, bv.bv_val, len ); bv.bv_len = len; ber_init2( ber, &bv, ld->ld_lberoptions ); } } } else { /* LDAPv3: Just allocate a new ber. Since this is a buffered * datagram, if the sockbuf is readable we still have data * to parse. */ ber = ldap_alloc_ber_with_options( ld ); if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) ok = 1; } /* set up response chain */ if ( tmp == NULL ) { newmsg->lm_next = ld->ld_responses; ld->ld_responses = newmsg; chain_head = newmsg; } else { tmp->lm_chain = newmsg; } chain_head->lm_chain_tail = newmsg; tmp = newmsg; /* "ok" means there's more to parse */ if ( ok ) { if ( isv2 ) { goto nextresp2; } else { goto nextresp3; } } else { /* got to end of datagram without a SearchResult. Free * our dup'd ber, but leave any buffer alone. For v2 case, * the previous response is still using this buffer. For v3, * the new ber has no buffer to free yet. */ ber_free( ber, 0 ); return -1; } } else if ( moremsgs ) { /* got search result, and we had multiple responses in 1 datagram. * stick the result onto the end of the chain, and then pull the * first response off the head of the chain. */ tmp->lm_chain = newmsg; chain_head->lm_chain_tail = newmsg; *result = chkResponseList( ld, msgid, all ); ld->ld_errno = LDAP_SUCCESS; return( (*result)->lm_msgtype ); } } #endif /* LDAP_CONNECTIONLESS */ /* is this the one we're looking for? */ if ( msgid == LDAP_RES_ANY || id == msgid ) { if ( all == LDAP_MSG_ONE || ( newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT && newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY && newmsg->lm_msgtype != LDAP_RES_INTERMEDIATE && newmsg->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) ) { *result = newmsg; ld->ld_errno = LDAP_SUCCESS; return( tag ); } else if ( newmsg->lm_msgtype == LDAP_RES_SEARCH_RESULT) { foundit = 1; /* return the chain later */ } } /* * if not, we must add it to the list of responses. if * the msgid is already there, it must be part of an existing * search response. */ prev = NULL; for ( l = ld->ld_responses; l != NULL; l = l->lm_next ) { if ( l->lm_msgid == newmsg->lm_msgid ) { break; } prev = l; } /* not part of an existing search response */ if ( l == NULL ) { if ( foundit ) { *result = newmsg; goto exit; } newmsg->lm_next = ld->ld_responses; ld->ld_responses = newmsg; goto exit; } Debug3( LDAP_DEBUG_TRACE, "adding response ld %p msgid %d type %ld:\n", (void *)ld, newmsg->lm_msgid, (long) newmsg->lm_msgtype ); /* part of a search response - add to end of list of entries */ l->lm_chain_tail->lm_chain = newmsg; l->lm_chain_tail = newmsg; /* return the whole chain if that's what we were looking for */ if ( foundit ) { if ( prev == NULL ) { ld->ld_responses = l->lm_next; } else { prev->lm_next = l->lm_next; } *result = l; } exit: if ( foundit ) { ld->ld_errno = LDAP_SUCCESS; return( tag ); } if ( lc && ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) { goto retry; } return( LDAP_MSG_X_KEEP_LOOKING ); /* continue looking */ }
/* protected by res_mutex */ static LDAPMessage * chkResponseList( LDAP *ld, int msgid, int all) { LDAPMessage *lm, **lastlm, *nextlm; int cnt = 0; /* * Look through the list of responses we have received on * this association and see if the response we're interested in * is there. If it is, return it. If not, call wait4msg() to * wait until it arrives or timeout occurs. */ LDAP_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex ); Debug3( LDAP_DEBUG_TRACE, "ldap_chkResponseList ld %p msgid %d all %d\n", (void *)ld, msgid, all ); lastlm = &ld->ld_responses; for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) { nextlm = lm->lm_next; ++cnt; if ( ldap_abandoned( ld, lm->lm_msgid ) ) { Debug2( LDAP_DEBUG_ANY, "response list msg abandoned, " "msgid %d message type %s\n", lm->lm_msgid, ldap_int_msgtype2str( lm->lm_msgtype ) ); switch ( lm->lm_msgtype ) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_INTERMEDIATE: break; default: /* there's no need to keep the id * in the abandoned list any longer */ ldap_mark_abandoned( ld, lm->lm_msgid ); break; } /* Remove this entry from list */ *lastlm = nextlm; ldap_msgfree( lm ); continue; } if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) { LDAPMessage *tmp; if ( all == LDAP_MSG_ONE || all == LDAP_MSG_RECEIVED || msgid == LDAP_RES_UNSOLICITED ) { break; } tmp = lm->lm_chain_tail; if ( tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY || tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE || tmp->lm_msgtype == LDAP_RES_INTERMEDIATE ) { tmp = NULL; } if ( tmp == NULL ) { lm = NULL; } break; } lastlm = &lm->lm_next; } if ( lm != NULL ) { /* Found an entry, remove it from the list */ if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) { *lastlm = lm->lm_chain; lm->lm_chain->lm_next = lm->lm_next; lm->lm_chain->lm_chain_tail = ( lm->lm_chain_tail != lm ) ? lm->lm_chain_tail : lm->lm_chain; lm->lm_chain = NULL; lm->lm_chain_tail = NULL; } else { *lastlm = lm->lm_next; } lm->lm_next = NULL; } #ifdef LDAP_DEBUG if ( lm == NULL) { Debug1( LDAP_DEBUG_TRACE, "ldap_chkResponseList returns ld %p NULL\n", (void *)ld ); } else { Debug3( LDAP_DEBUG_TRACE, "ldap_chkResponseList returns ld %p msgid %d, type 0x%02lx\n", (void *)ld, lm->lm_msgid, (unsigned long)lm->lm_msgtype ); } #endif return lm; }
/* analyze a file descriptor */ int filan_fd(int fd, FILE *outfile) { #if HAVE_STAT64 struct stat64 buf = {0}; #else struct stat buf = {0}; #endif /* !HAVE_STAT64 */ int result; Debug1("checking file descriptor %u", fd); #if HAVE_STAT64 result = Fstat64(fd, &buf); #else result = Fstat(fd, &buf); #endif /* !HAVE_STAT64 */ if (result < 0) { if (errno == EBADF) { Debug2("fstat(%d): %s", fd, strerror(errno)); } else { Warn2("fstat(%d): %s", fd, strerror(errno)); } return -1; } Debug2("fd %d is a %s", fd, getfiletypestring(buf.st_mode)); result = filan_stat(&buf, fd, fd, outfile); if (result >= 0) { /* even more dynamic info */ { /* see if data is available */ struct pollfd ufds; ufds.fd = fd; ufds.events = POLLIN|POLLPRI|POLLOUT #ifdef POLLRDNORM |POLLRDNORM #endif #ifdef POLLRDBAND |POLLRDBAND #endif |POLLWRNORM #ifdef POLLWRBAND |POLLWRBAND #endif #ifdef POLLMSG |POLLMSG #endif ; if (Poll(&ufds, 1, 0) < 0) { Warn4("poll({%d, %hd, %hd}, 1, 0): %s", ufds.fd, ufds.events, ufds.revents, strerror(errno)); } else { fputs("poll: ", outfile); if (ufds.revents & POLLIN) fputs("IN,", outfile); if (ufds.revents & POLLPRI) fputs("PRI,", outfile); if (ufds.revents & POLLOUT) fputs("OUT,", outfile); if (ufds.revents & POLLERR) fputs("ERR,", outfile); if (ufds.revents & POLLNVAL) fputs("NVAL,", outfile); #ifdef FIONREAD if (ufds.revents & POLLIN) { size_t sizet; if ((result = Ioctl(fd, FIONREAD, &sizet) >= 0)) { fprintf (outfile, "; FIONREAD="F_Zu, sizet); } } #endif /* defined(FIONREAD) */ #if _WITH_SOCKET && defined(MSG_DONTWAIT) if ((ufds.revents & POLLIN) && isasocket(fd)) { char _peername[SOCKADDR_MAX]; struct sockaddr *pa = (struct sockaddr *)_peername; struct msghdr msgh = {0}; char peekbuff[1]; /* [0] fails with some compilers */ #if HAVE_STRUCT_IOVEC struct iovec iovec; #endif char ctrlbuff[5120]; ssize_t bytes; fputs("; ", outfile); msgh.msg_name = pa; msgh.msg_namelen = sizeof(*pa); #if HAVE_STRUCT_IOVEC iovec.iov_base = peekbuff; iovec.iov_len = sizeof(peekbuff); msgh.msg_iov = &iovec; msgh.msg_iovlen = 1; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif #if HAVE_STRUCT_MSGHDR_MSGFLAGS msgh.msg_flags = 0; #endif if ((bytes = Recvmsg(fd, &msgh, MSG_PEEK|MSG_DONTWAIT)) < 0) { Warn1("recvmsg(): %s", strerror(errno)); } else { fprintf(outfile, "recvmsg="F_Zd", ", bytes); } } #endif /* _WITH_SOCKET && defined(MSG_DONTWAIT) */ } } } fputc('\n', outfile); return 0; }
VOID showall( VOID ) { PD *p; p = rlr; Debug1( "Rlr: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } p = drl; Debug1( "\r\nDrl: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } p = nrl; Debug1( "\r\nNrl: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } p = slr; Debug1( "\r\nSlr: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } p = alr; Debug1( "\r\nAlr: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } p = tlr; Debug1( "\r\ntlr: " ); while( p ) { Debug1( p->p_name ); Debug1( " " ); p = p->p_link; } Debug1( "\r\n" ); }
static struct subnet_record *make_subnet(const char *name, enum subnet_type type, struct in_addr myip, struct in_addr bcast_ip, struct in_addr mask_ip) { struct subnet_record *subrec = NULL; int nmb_sock, dgram_sock; /* Check if we are creating a non broadcast subnet - if so don't create sockets. */ if(type != NORMAL_SUBNET) { nmb_sock = -1; dgram_sock = -1; } else { /* * Attempt to open the sockets on port 137/138 for this interface * and bind them. * Fail the subnet creation if this fails. */ if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) { if( DEBUGLVL( 0 ) ) { Debug1( "nmbd_subnetdb:make_subnet()\n" ); Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) ); Debug1( "for port %d. ", global_nmb_port ); Debug1( "Error was %s\n", strerror(errno) ); } return NULL; } if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) { if( DEBUGLVL( 0 ) ) { Debug1( "nmbd_subnetdb:make_subnet()\n" ); Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) ); Debug1( "for port %d. ", DGRAM_PORT ); Debug1( "Error was %s\n", strerror(errno) ); } return NULL; } /* Make sure we can broadcast from these sockets. */ set_socket_options(nmb_sock,"SO_BROADCAST"); set_socket_options(dgram_sock,"SO_BROADCAST"); /* Set them non-blocking. */ set_blocking(nmb_sock, False); set_blocking(dgram_sock, False); } subrec = SMB_MALLOC_P(struct subnet_record); if (!subrec) { DEBUG(0,("make_subnet: malloc fail !\n")); close(nmb_sock); close(dgram_sock); return(NULL); } ZERO_STRUCTP(subrec); if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) { DEBUG(0,("make_subnet: malloc fail for subnet name !\n")); close(nmb_sock); close(dgram_sock); ZERO_STRUCTP(subrec); SAFE_FREE(subrec); return(NULL); } DEBUG(2, ("making subnet name:%s ", name )); DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip))); DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip))); subrec->namelist_changed = False; subrec->work_changed = False; subrec->bcast_ip = bcast_ip; subrec->mask_ip = mask_ip; subrec->myip = myip; subrec->type = type; subrec->nmb_sock = nmb_sock; subrec->dgram_sock = dgram_sock; return subrec; }
void sycSSL_CTX_free(SSL_CTX *ctx) { Debug1("SSL_CTX_free(%p)", ctx); SSL_CTX_free(ctx); Debug("SSL_CTX_free() -> void"); return; }
bool NetBase::HandleAck(csRef<psNetPacketEntry> pkt, Connection* connection, LPSOCKADDR_IN addr) { psNetPacket* packet = pkt->packet; // REVERTED 3/8/03 Until I can figure out why this is causing client conencts to fail - Andrew Mann (Rhad) // If we don't know who this connection is, don't handle ACKs //if (!connection) // return false; if (packet->pktsize == PKTSIZE_ACK) // special pktsize means ACK packet here { #ifdef PACKETDEBUG Debug1(LOG_NET,0,"Ack received.\n"); #endif // receipt of ack packet is good enough to keep alive connection if (connection) { connection->heartbeat = 0; connection->lastRecvPacketTime = csGetTicks(); connection->pcknumin++; } csRef<psNetPacketEntry> ack; // The hash only keys on the clientnum and pktid so we need to go looking for the offset csArray<csRef<psNetPacketEntry> > acks = awaitingack.GetAll(PacketKey(pkt->clientnum, pkt->packet->pktid)); for(size_t i = 0;i < acks.GetSize(); i++) { if(acks[i]->packet->offset == pkt->packet->offset) ack = acks[i]; } if (ack) // if acked pkt is found, simply remove it. We're done. { // Only update RTT estimate when packet has not been retransmitted if (!ack->retransmitted && connection) { csTicks elapsed = csGetTicks() - ack->timestamp; if (connection->estRTT > 0) { int diff = (int) (elapsed - connection->estRTT); connection->estRTT += (int) (0.125 * diff); if(diff < 0) diff = -diff; connection->devRTT += (int) (0.125 * (diff - connection->devRTT)); } else { // Initialise the RTT estimates connection->estRTT = elapsed; connection->devRTT = elapsed / 2; } // Update the packet timeout connection->RTO = (int) (connection->estRTT + 4 * connection->devRTT); if (connection->RTO > PKTMAXRTO) { connection->RTO = PKTMAXRTO; } else if(connection->RTO < PKTMINRTO) { connection->RTO = PKTMINRTO; } netInfos.AddPingTicks(elapsed); } // printf ("Ping time: %i, average: %i\n", elapsed, netInfos.GetAveragePingTicks()); if (!awaitingack.Delete(PacketKey(pkt->clientnum, pkt->packet->pktid), ack)) { #ifdef PACKETDEBUG Debug2(LOG_NET,0,"No packet in ack queue :%d\n", ack->packet->pktid); #endif } else if(connection) { connection->RemoveFromWindow(ack->packet->GetPacketSize()); } } else // if not found, it is probably a resent ACK which is redundant so do nothing { #ifdef PACKETDEBUG Debug1(LOG_NET,0,"No matching packet found. No problem though.\n"); #endif } return true; // eat the packet } if (pkt->packet->GetPriority() == PRIORITY_HIGH) // a HIGH_PRIORITY packet -> ack { #ifdef PACKETDEBUG Debug1(LOG_NET,0,"High priority packet received.\n"); #endif if (connection) { csRef<psNetPacketEntry> ack; ack.AttachNew(new psNetPacketEntry(PRIORITY_LOW, pkt->clientnum, pkt->packet->pktid, pkt->packet->offset, pkt->packet->msgsize, PKTSIZE_ACK,(char *)NULL)); SendFinalPacket(ack, addr); // ack should be unre'd here } } return false; }
void sycSSL_free(SSL *ssl) { Debug1("SSL_free(%p)", ssl); SSL_free(ssl); Debug("SSL_free() -> void"); return; }
int Debug1 (const char *format_str, ...) { #else int Debug1 (va_alist) va_dcl { const char *format_str; #endif va_list ap; int old_errno = errno; if (stdout_logging) { #ifdef HAVE_STDARG_H va_start (ap, format_str); #else va_start (ap); format_str = va_arg (ap, const char *); #endif (void) vfprintf (dbf, format_str, ap); va_end (ap); errno = old_errno; return (0); } if (!dbf && *debugf) { mode_t oldumask = umask (022); if (append_log) dbf = sys_fopen (debugf, "a"); else dbf = sys_fopen (debugf, "w"); (void) umask (oldumask); if (dbf) { setbuf (dbf, NULL); } else { errno = old_errno; return (0); } } if (dbf) { #ifdef HAVE_STDARG_H va_start (ap, format_str); #else va_start (ap); format_str = va_arg (ap, const char *); #endif (void) vfprintf (dbf, format_str, ap); va_end (ap); (void) fflush (dbf); } errno = old_errno; return (0); } /* Debug1 */ /* ************************************************************************** ** * Print the buffer content via Debug1(), then reset the buffer. * * Input: none * Output: none * * ************************************************************************** ** */ static void bufr_print (void) { format_bufr[format_pos] = '\0'; (void) Debug1 ("%s", format_bufr); format_pos = 0; } /* bufr_print */
/* open a named or unnamed pipe/fifo */ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *pipename = argv[1]; int rw = (xioflags & XIO_ACCMODE); #if HAVE_STAT64 struct stat64 pipstat; #else struct stat pipstat; #endif /* !HAVE_STAT64 */ bool opt_unlink_early = false; bool opt_unlink_close = true; mode_t mode = 0666; int result; if (argc == 1) { return xioopen_fifo_unnamed(fd, fd->stream.opts); } if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); } if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); applyopts_named(pipename, opts, PH_EARLY); /* umask! */ applyopts(-1, opts, PH_EARLY); if (opt_unlink_early) { if (Unlink(pipename) < 0) { if (errno == ENOENT) { Warn2("unlink(%s): %s", pipename, strerror(errno)); } else { Error2("unlink(%s): %s", pipename, strerror(errno)); return STAT_RETRYLATER; } } } retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); retropt_modet(opts, OPT_PERM, &mode); if (applyopts_named(pipename, opts, PH_EARLY) < 0) { return STAT_RETRYLATER; } if (applyopts_named(pipename, opts, PH_PREOPEN) < 0) { return STAT_RETRYLATER; } if ( #if HAVE_STAT64 Stat64(pipename, &pipstat) < 0 #else Stat(pipename, &pipstat) < 0 #endif /* !HAVE_STAT64 */ ) { if (errno != ENOENT) { Error3("stat(\"%s\", %p): %s", pipename, &pipstat, strerror(errno)); } else { Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename); #if 0 result = Mknod(pipename, S_IFIFO|mode, 0); if (result < 0) { Error3("mknod(%s, %d, 0): %s", pipename, mode, strerror(errno)); return STAT_RETRYLATER; } #else result = Mkfifo(pipename, mode); if (result < 0) { Error3("mkfifo(%s, %d): %s", pipename, mode, strerror(errno)); return STAT_RETRYLATER; } #endif Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]); applyopts_named(pipename, opts, PH_ALL); } if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(pipename)) == NULL) { Error1("strdup(\"%s\"): out of memory", pipename); } fd->stream.opt_unlink_close = true; } } else { /* exists */ Debug1("xioopen_fifo(\"%s\"): already exist, opening it", pipename); Notice3("opening %s \"%s\" for %s", filetypenames[(pipstat.st_mode&S_IFMT)>>12], pipename, ddirection[rw]); /*applyopts_early(pipename, opts);*/ applyopts_named(pipename, opts, PH_EARLY); } if ((result = _xioopen_open(pipename, rw, opts)) < 0) { return result; } fd->stream.fd = result; applyopts_named(pipename, opts, PH_FD); applyopts(fd->stream.fd, opts, PH_FD); applyopts_cloexec(fd->stream.fd, opts); return _xio_openlate(&fd->stream, opts); }
bool PaladinJr::SpeedCheck(Client* client, gemActor* actor, psDRMessage& currUpdate) { csVector3 oldpos; // Dummy variables float yrot; iSector* sector; psWorld * world = entitymanager->GetWorld(); int violation = NOVIOLATION; actor->pcmove->GetLastClientPosition (oldpos, yrot, sector); // If no previous observations then we have nothing to check against. if (!sector) return true; // define cheating variables float dist; float reported_distance; float max_noncheat_distance; float lag_distance; csTicks timedelta; csVector3 vel; // check for warpviolation if (sector != currUpdate.sector && !world->WarpSpace(sector, currUpdate.sector, oldpos)) { if (checks & WARPVIOLATION) { violation = WARPVIOLATION; } else { // we don't do warp checking and crossed a sector // skip this round return true; } } if (checks & SPEEDVIOLATION) { // we don't use the absolute value of the vertical // speed in order to let falls go through if (fabs(currUpdate.vel.x) <= maxVelocity.x && currUpdate.vel.y <= maxVelocity.y && fabs(currUpdate.vel.z) <= maxVelocity.z) { violation |= SPEEDVIOLATION; } } // distance check is skipped on warp violation as it would be wrong if (checks & DISTVIOLATION && !(violation & WARPVIOLATION)) { dist = (currUpdate.pos-oldpos).Norm(); timedelta = actor->pcmove->ClientTimeDiff(); // We use the last reported vel, not the new vel, to calculate how far he should have gone since the last DR update vel = actor->pcmove->GetVelocity(); vel.y = 0; // ignore vertical velocity reported_distance = vel.Norm()*timedelta/1000; Debug4(LOG_CHEAT, client->GetClientNum(),"Player went %1.3fm in %u ticks when %1.3fm was allowed.\n",dist, timedelta, reported_distance); max_noncheat_distance = maxSpeed*timedelta/1000; lag_distance = maxSpeed*client->accumulatedLag/1000; if (dist < max_noncheat_distance + lag_distance) { if(dist == 0) { // player is stationary - reset accumulated lag NetBase::Connection * connection = client->GetConnection(); client->accumulatedLag = connection->estRTT + connection->devRTT; } else if(fabs(dist-reported_distance) < dist/20) { // ignore jitter caused differences Debug1(LOG_CHEAT, client->GetClientNum(),"Ignoring lag jitter."); } else { // adjust accumulated lag float lag = (reported_distance - dist) * 1000.f/maxSpeed + client->accumulatedLag; // cap to meaningful values lag = lag < 0 ? 0 : lag > MAX_ACCUMULATED_LAG ? MAX_ACCUMULATED_LAG : lag; client->accumulatedLag = (csTicks)lag; Debug2(LOG_CHEAT, client->GetClientNum(),"Accumulated lag: %u\n",client->accumulatedLag); } } else { violation |= DISTVIOLATION; } } if (violation != NOVIOLATION) { if (client->GetCheatMask(MOVE_CHEAT)) { //printf("Server has pre-authorized this apparent speed violation.\n"); client->SetCheatMask(MOVE_CHEAT, false); // now clear the Get Out of Jail Free card return true; // not cheating } Debug6(LOG_CHEAT, client->GetClientNum(),"Went %1.2f in %u ticks when %1.2f was expected plus %1.2f allowed lag distance (%1.2f)\n", dist, timedelta, max_noncheat_distance, lag_distance, max_noncheat_distance+lag_distance); //printf("Z Vel is %1.2f\n", currUpdate.vel.z); //printf("MaxSpeed is %1.2f\n", maxSpeed); // Report cheater csVector3 angVel; csString buf; csString type; csString sectorName(sector->QueryObject()->GetName()); // Player has probably been warped if (violation & WARPVIOLATION) { sectorName.Append(" to "); sectorName.Append(currUpdate.sectorName); type = "Warp Violation"; } if (violation & SPEEDVIOLATION) { if(!type.IsEmpty()) type += "|"; type += "Speed Violation (Hack confirmed)"; } if (violation & DISTVIOLATION) { if(!type.IsEmpty()) type += "|"; type += "Distance Violation"; } if (enforcing) { actor->ForcePositionUpdate(); } actor->pcmove->GetAngularVelocity(angVel); buf.Format("%s, %s, %s, %.3f %.3f %.3f, %.3f 0 %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f, %s\n", client->GetName(), type.GetData(), sectorName.GetData(),oldpos.x, oldpos.y, oldpos.z, max_noncheat_distance, max_noncheat_distance, currUpdate.pos.x - oldpos.x, currUpdate.pos.y - oldpos.y, currUpdate.pos.z - oldpos.z, vel.x, vel.y, vel.z, angVel.x, angVel.y, angVel.z, PALADIN_VERSION); psserver->GetLogCSV()->Write(CSV_PALADIN, buf); Debug5(LOG_CHEAT, client->GetClientNum(),"Player %s traversed %1.2fm in %u msec with an accumulated lag allowance of %u ms. Cheat detected!\n", client->GetName (),dist,timedelta,client->accumulatedLag); client->CountDetectedCheat(); //printf("Client has %d detected cheats now.\n", client->GetDetectedCheatCount()); if (client->GetDetectedCheatCount() % warnCount == 0) { psserver->SendSystemError(client->GetClientNum(),"You have been flagged as using speed hacks. You will be disconnected if you continue."); } if (client->GetDetectedCheatCount() >= maxCount) { //printf("Disconnecting a cheating client.\n"); psserver->RemovePlayer(client->GetClientNum(),"Paladin has kicked you from the server for cheating."); return false; } return !enforcing; } else { return true; } }
/* * ldap_sasl_interactive_bind - interactive SASL authentication * * This routine uses interactive callbacks. * * LDAP_SUCCESS is returned upon success, the ldap error code * otherwise. LDAP_SASL_BIND_IN_PROGRESS is returned if further * calls are needed. */ int ldap_sasl_interactive_bind( LDAP *ld, LDAP_CONST char *dn, /* usually NULL */ LDAP_CONST char *mechs, LDAPControl **serverControls, LDAPControl **clientControls, unsigned flags, LDAP_SASL_INTERACT_PROC *interact, void *defaults, LDAPMessage *result, const char **rmech, int *msgid ) { char *smechs = NULL; int rc; #ifdef LDAP_CONNECTIONLESS if( LDAP_IS_UDP(ld) ) { /* Just force it to simple bind, silly to make the user * ask all the time. No, we don't ever actually bind, but I'll * let the final bind handler take care of saving the cdn. */ rc = ldap_simple_bind( ld, dn, NULL ); rc = rc < 0 ? rc : 0; goto done; } else #endif /* First time */ if ( !result ) { #ifdef HAVE_CYRUS_SASL if( mechs == NULL || *mechs == '\0' ) { mechs = ld->ld_options.ldo_def_sasl_mech; } #endif if( mechs == NULL || *mechs == '\0' ) { /* FIXME: this needs to be asynchronous too; * perhaps NULL should be disallowed for async usage? */ rc = ldap_pvt_sasl_getmechs( ld, &smechs ); if( rc != LDAP_SUCCESS ) { goto done; } Debug1( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind: server supports: %s\n", smechs ); mechs = smechs; } else { Debug1( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind: user selected: %s\n", mechs ); } } rc = ldap_int_sasl_bind( ld, dn, mechs, serverControls, clientControls, flags, interact, defaults, result, rmech, msgid ); done: if ( smechs ) LDAP_FREE( smechs ); return rc; }