Beispiel #1
0
/* 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;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
/* ************************************************************************** **
 * 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 */
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #7
0
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();
        }
    }
}
Beispiel #8
0
void Usleep(unsigned long usec) {
   Debug1("usleep(%lu)", usec);
   usleep(usec);
   Debug("usleep() ->");
   return;
}
Beispiel #9
0
void Exit(int status) {
   Debug1("exit(%d)", status);
   exit(status);
}
Beispiel #10
0
/* 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 );
}
Beispiel #11
0
/* 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 */
}
Beispiel #12
0
/* 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;
}
Beispiel #13
0
/* 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;
}
Beispiel #14
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" );	

}
Beispiel #15
0
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;
}
Beispiel #16
0
void sycSSL_CTX_free(SSL_CTX *ctx) {
   Debug1("SSL_CTX_free(%p)", ctx);
   SSL_CTX_free(ctx);
   Debug("SSL_CTX_free() -> void");
   return;
}
Beispiel #17
0
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;
}
Beispiel #18
0
void sycSSL_free(SSL *ssl) {
   Debug1("SSL_free(%p)", ssl);
   SSL_free(ssl);
   Debug("SSL_free() -> void");
   return;
}
Beispiel #19
0
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 */
Beispiel #20
0
/* 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;
    }
}
Beispiel #22
0
/*
 * 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;
}