Пример #1
0
std::string CSpecialProtocol::TranslatePath(const std::string &path)
{
  CURL url(path);
  // check for special-protocol, if not, return
  if (!url.IsProtocol("special"))
  {
    return path;
  }
  return TranslatePath(url);
}
Пример #2
0
String File::TranslatePath(CStrRef filename, bool useFileCache /* = false */,
                           bool keepRelative /*= false */) {
  String canonicalized(Util::canonicalize(filename.data(),
                                          filename.size()), AttachString);

  if (useFileCache) {
    String translated = TranslatePath(canonicalized, false);
    if (!translated.empty() && access(translated.data(), F_OK) < 0 &&
        StaticContentCache::TheFileCache) {
      if (StaticContentCache::TheFileCache->exists(canonicalized.data(),
                                                   false)) {
        // we use file cache's file name to make stat() work
        translated = String(RuntimeOption::FileCache);
      }
    }
    return translated;
  }

  if (RuntimeOption::SafeFileAccess) {
    const vector<string> &allowedDirectories =
      VirtualHost::GetAllowedDirectories();
    for (unsigned int i = 0; i < allowedDirectories.size();
         i++) {
      const string &directory = allowedDirectories[i];
      int len = directory.size();
      if (canonicalized.length() >= len &&
          strncmp(canonicalized.data(), directory.data(), len) == 0) {
        return canonicalized;
      }
    }

    // disallow access with an absolute path
    if (canonicalized.charAt(0) == '/') {
      return "";
    }

    // unresolvable paths are all considered as unsafe
    if (canonicalized.find("..") >= 0) {
      assert(canonicalized.find("..") == 0);
      return "";
    }
  }

  if (canonicalized.charAt(0) == '/' || keepRelative) {
    return canonicalized;
  }

  String cwd = g_context->getCwd();
  if (!cwd.empty() && cwd[cwd.length() - 1] == '/') {
    return cwd + canonicalized;
  }
  return cwd + "/" + canonicalized;
}
Пример #3
0
int CfOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *oldDirname)
{
    Dir *dirh;
    const struct dirent *dirp;
    int offset;
    char dirname[CF_BUFSIZE];

    TranslatePath(dirname, oldDirname);

    if (!IsAbsoluteFileName(dirname))
    {
        sprintf(sendbuffer, "BAD: request to access a non-absolute filename\n");
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
        return -1;
    }

    if ((dirh = DirOpen(dirname)) == NULL)
    {
        Log(LOG_LEVEL_DEBUG, "Couldn't open dir '%s'", dirname);
        snprintf(sendbuffer, CF_BUFSIZE, "BAD: cfengine, couldn't open dir %s\n", dirname);
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
        return -1;
    }

/* Pack names for transmission */

    memset(sendbuffer, 0, CF_BUFSIZE);

    offset = 0;

    for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh))
    {
        if (strlen(dirp->d_name) + 1 + offset >= CF_BUFSIZE - CF_MAXLINKSIZE)
        {
            SendTransaction(&conn->conn_info, sendbuffer, offset + 1, CF_MORE);
            offset = 0;
            memset(sendbuffer, 0, CF_BUFSIZE);
        }

        strncpy(sendbuffer + offset, dirp->d_name, CF_MAXLINKSIZE);
        offset += strlen(dirp->d_name) + 1;     /* + zero byte separator */
    }

    strcpy(sendbuffer + offset, CFD_TERMINATOR);
    SendTransaction(&conn->conn_info, sendbuffer, offset + 2 + strlen(CFD_TERMINATOR), CF_DONE);
    DirClose(dirh);
    return 0;
}
Пример #4
0
void CompareLocalHash(ServerConnectionState *conn, char *sendbuffer, char *recvbuffer)
{
    unsigned char digest1[EVP_MAX_MD_SIZE + 1], digest2[EVP_MAX_MD_SIZE + 1];
    char filename[CF_BUFSIZE], rfilename[CF_BUFSIZE];
    char *sp;
    int i;

/* TODO - when safe change this proto string to sha2 */

    sscanf(recvbuffer, "MD5 %[^\n]", rfilename);

    sp = recvbuffer + strlen(recvbuffer) + CF_SMALL_OFFSET;

    for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
    {
        digest1[i] = *sp++;
    }

    memset(sendbuffer, 0, CF_BUFSIZE);

    TranslatePath(filename, rfilename);

    HashFile(filename, digest2, CF_DEFAULT_DIGEST);

    if ((HashesMatch(digest1, digest2, CF_DEFAULT_DIGEST)) || (HashesMatch(digest1, digest2, HASH_METHOD_MD5)))
    {
        sprintf(sendbuffer, "%s", CFD_FALSE);
        Log(LOG_LEVEL_DEBUG, "Hashes matched ok");
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
    }
    else
    {
        sprintf(sendbuffer, "%s", CFD_TRUE);
        Log(LOG_LEVEL_DEBUG, "Hashes didn't match");
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
    }
}
Пример #5
0
bool RelativeDevice::RemoveFile(const std::string& filename)
{
	return m_otherDevice->RemoveFile(TranslatePath(filename));
}
Пример #6
0
bool RelativeDevice::RenameFile(const std::string& from, const std::string& to)
{
	return m_otherDevice->RenameFile(TranslatePath(from), TranslatePath(to));
}
Пример #7
0
Device::THandle RelativeDevice::OpenBulk(const std::string& fileName, uint64_t* ptr)
{
	return m_otherDevice->OpenBulk(TranslatePath(fileName), ptr);
}
Пример #8
0
Device::THandle RelativeDevice::Create(const std::string& filename)
{
	return m_otherDevice->Create(TranslatePath(filename));
}
Пример #9
0
Device::THandle RelativeDevice::FindFirst(const std::string& folder, FindData* findData)
{
	return m_otherDevice->FindFirst(TranslatePath(folder), findData);
}
Пример #10
0
Device::THandle RelativeDevice::Open(const std::string& fileName, bool readOnly)
{
	return m_otherDevice->Open(TranslatePath(fileName), readOnly);
}
Пример #11
0
std::string CLegacyPathTranslation::TranslateMusicDbPath(const std::string &legacyPath)
{
  return TranslatePath(legacyPath, s_musicDbTranslator, MusicDbTranslatorSize);
}
Пример #12
0
std::string CSpecialProtocol::TranslatePathConvertCase(const std::string& path)
{
  std::string translatedPath = TranslatePath(path);

#ifdef TARGET_POSIX
  if (translatedPath.find("://") != std::string::npos)
    return translatedPath;

  // If the file exists with the requested name, simply return it
  struct stat stat_buf;
  if (stat(translatedPath.c_str(), &stat_buf) == 0)
    return translatedPath;

  std::string result;
  std::vector<std::string> tokens;
  StringUtils::Tokenize(translatedPath, tokens, "/");
  std::string file;
  DIR* dir;
  struct dirent* de;

  for (unsigned int i = 0; i < tokens.size(); i++)
  {
    file = result + "/";
    file += tokens[i];
    if (stat(file.c_str(), &stat_buf) == 0)
    {
      result += "/" + tokens[i];
    }
    else
    {
      dir = opendir(result.c_str());
      if (dir)
      {
        while ((de = readdir(dir)) != NULL)
        {
          // check if there's a file with same name but different case
          if (strcasecmp(de->d_name, tokens[i].c_str()) == 0)
          {
            result += "/";
            result += de->d_name;
            break;
          }
        }

        // if we did not find any file that somewhat matches, just
        // fallback but we know it's not gonna be a good ending
        if (de == NULL)
          result += "/" + tokens[i];

        closedir(dir);
      }
      else
      { // this is just fallback, we won't succeed anyway...
        result += "/" + tokens[i];
      }
    }
  }

  return result;
#else
  return translatedPath;
#endif
}
Пример #13
0
bool RelativeDevice::RemoveDirectory(const std::string& name)
{
	return m_otherDevice->RemoveDirectory(TranslatePath(name));
}
Пример #14
0
size_t RelativeDevice::GetLength(const std::string& fileName)
{
	return m_otherDevice->GetLength(TranslatePath(fileName));
}
Пример #15
0
int AccessControl(EvalContext *ctx, const char *req_path, ServerConnectionState *conn, int encrypt)
{
    Auth *ap;
    int access = false;
    char transrequest[CF_BUFSIZE];
    struct stat statbuf;
    char translated_req_path[CF_BUFSIZE];
    char transpath[CF_BUFSIZE];

/*
 * /var/cfengine -> $workdir translation.
 */
    TranslatePath(translated_req_path, req_path);

    if (ResolveFilename(translated_req_path, transrequest))
    {
        Log(LOG_LEVEL_VERBOSE, "Filename %s is resolved to %s", translated_req_path, transrequest);
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Couldn't resolve (realpath: %s) filename: %s",
            GetErrorStr(), translated_req_path);
    }

    if (lstat(transrequest, &statbuf) == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't stat (lstat: %s) filename: %s",
            GetErrorStr(), transrequest);
        return false;
    }

    Log(LOG_LEVEL_DEBUG, "AccessControl, match (%s,%s) encrypt request = %d", transrequest, conn->hostname, encrypt);

    if (SV.admit == NULL)
    {
        Log(LOG_LEVEL_INFO, "cf-serverd access list is empty, no files are visible");
        return false;
    }

    conn->maproot = false;

    for (ap = SV.admit; ap != NULL; ap = ap->next)
    {
        int res = false;

        Log(LOG_LEVEL_DEBUG, "Examining rule in access list (%s,%s)", transrequest, ap->path);

        strncpy(transpath, ap->path, CF_BUFSIZE - 1);
        MapName(transpath);

        if ((strlen(transrequest) > strlen(transpath)) && (strncmp(transpath, transrequest, strlen(transpath)) == 0)
            && (transrequest[strlen(transpath)] == FILE_SEPARATOR))
        {
            res = true;         /* Substring means must be a / to link, else just a substring og filename */
        }

        /* Exact match means single file to admit */

        if (strcmp(transpath, transrequest) == 0)
        {
            res = true;
        }

        if (strcmp(transpath, "/") == 0)
        {
            res = true;
        }

        if (res)
        {
            Log(LOG_LEVEL_VERBOSE, "Found a matching rule in access list (%s in %s)", transrequest, transpath);

            if (stat(transpath, &statbuf) == -1)
            {
                Log(LOG_LEVEL_INFO,
                      "Warning cannot stat file object %s in admit/grant, or access list refers to dangling link\n",
                      transpath);
                continue;
            }

            if ((!encrypt) && (ap->encrypt == true))
            {
                Log(LOG_LEVEL_ERR, "File %s requires encrypt connection...will not serve", transpath);
                access = false;
            }
            else
            {
                Log(LOG_LEVEL_DEBUG, "Checking whether to map root privileges..");

                if ((IsMatchItemIn(ctx, ap->maproot, MapAddress(conn->ipaddr))) ||
                    (IsRegexItemIn(ctx, ap->maproot, conn->hostname)))
                {
                    conn->maproot = true;
                    Log(LOG_LEVEL_VERBOSE, "Mapping root privileges to access non-root files");
                }

                if ((IsMatchItemIn(ctx, ap->accesslist, MapAddress(conn->ipaddr)))
                    || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname)))
                {
                    access = true;
                    Log(LOG_LEVEL_DEBUG, "Access privileges - match found");
                }
            }
            break;
        }
    }

    if (strncmp(transpath, transrequest, strlen(transpath)) == 0)
    {
        for (ap = SV.deny; ap != NULL; ap = ap->next)
        {
            if (IsRegexItemIn(ctx, ap->accesslist, conn->hostname))
            {
                access = false;
                Log(LOG_LEVEL_INFO, "Host %s explicitly denied access to %s", conn->hostname, transrequest);
                break;
            }
        }
    }

    if (access)
    {
        Log(LOG_LEVEL_VERBOSE, "Host %s granted access to %s", conn->hostname, req_path);

        if (encrypt && LOGENCRYPT)
        {
            /* Log files that were marked as requiring encryption */
            Log(LOG_LEVEL_INFO, "Host %s granted access to %s", conn->hostname, req_path);
        }
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Host %s denied access to %s", conn->hostname, req_path);
    }

    if (!conn->rsa_auth)
    {
        Log(LOG_LEVEL_INFO, "Cannot map root access without RSA authentication");
        conn->maproot = false;  /* only public files accessible */
    }

    return access;
}
Пример #16
0
int StatFile(ServerConnectionState *conn, char *sendbuffer, char *ofilename)
/* Because we do not know the size or structure of remote datatypes,*/
/* the simplest way to transfer the data is to convert them into */
/* plain text and interpret them on the other side. */
{
    Stat cfst;
    struct stat statbuf, statlinkbuf;
    char linkbuf[CF_BUFSIZE], filename[CF_BUFSIZE];
    int islink = false;

    TranslatePath(filename, ofilename);

    memset(&cfst, 0, sizeof(Stat));

    if (strlen(ReadLastNode(filename)) > CF_MAXLINKSIZE)
    {
        snprintf(sendbuffer, CF_BUFSIZE, "BAD: Filename suspiciously long [%s]\n", filename);
        Log(LOG_LEVEL_ERR, "%s", sendbuffer);
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
        return -1;
    }

    if (lstat(filename, &statbuf) == -1)
    {
        snprintf(sendbuffer, CF_BUFSIZE, "BAD: unable to stat file %s", filename);
        Log(LOG_LEVEL_VERBOSE, "%s. (lstat: %s)", sendbuffer, GetErrorStr());
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
        return -1;
    }

    cfst.cf_readlink = NULL;
    cfst.cf_lmode = 0;
    cfst.cf_nlink = CF_NOSIZE;

    memset(linkbuf, 0, CF_BUFSIZE);

#ifndef __MINGW32__                   // windows doesn't support symbolic links
    if (S_ISLNK(statbuf.st_mode))
    {
        islink = true;
        cfst.cf_type = FILE_TYPE_LINK; /* pointless - overwritten */
        cfst.cf_lmode = statbuf.st_mode & 07777;
        cfst.cf_nlink = statbuf.st_nlink;

        if (readlink(filename, linkbuf, CF_BUFSIZE - 1) == -1)
        {
            sprintf(sendbuffer, "BAD: unable to read link\n");
            Log(LOG_LEVEL_ERR, "%s. (readlink: %s)", sendbuffer, GetErrorStr());
            SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
            return -1;
        }

        Log(LOG_LEVEL_DEBUG, "readlink '%s'", linkbuf);

        cfst.cf_readlink = linkbuf;
    }
#endif /* !__MINGW32__ */

    if ((!islink) && (stat(filename, &statbuf) == -1))
    {
        Log(LOG_LEVEL_VERBOSE, "BAD: unable to stat file '%s'. (stat: %s)",
            filename, GetErrorStr());
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
        return -1;
    }

    Log(LOG_LEVEL_DEBUG, "Getting size of link deref '%s'", linkbuf);

    if (islink && (stat(filename, &statlinkbuf) != -1))       /* linktype=copy used by agent */
    {
        statbuf.st_size = statlinkbuf.st_size;
        statbuf.st_mode = statlinkbuf.st_mode;
        statbuf.st_uid = statlinkbuf.st_uid;
        statbuf.st_gid = statlinkbuf.st_gid;
        statbuf.st_mtime = statlinkbuf.st_mtime;
        statbuf.st_ctime = statlinkbuf.st_ctime;
    }

    if (S_ISDIR(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_DIR;
    }

    if (S_ISREG(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_REGULAR;
    }

    if (S_ISSOCK(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_SOCK;
    }

    if (S_ISCHR(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_CHAR_;
    }

    if (S_ISBLK(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_BLOCK;
    }

    if (S_ISFIFO(statbuf.st_mode))
    {
        cfst.cf_type = FILE_TYPE_FIFO;
    }

    cfst.cf_mode = statbuf.st_mode & 07777;
    cfst.cf_uid = statbuf.st_uid & 0xFFFFFFFF;
    cfst.cf_gid = statbuf.st_gid & 0xFFFFFFFF;
    cfst.cf_size = statbuf.st_size;
    cfst.cf_atime = statbuf.st_atime;
    cfst.cf_mtime = statbuf.st_mtime;
    cfst.cf_ctime = statbuf.st_ctime;
    cfst.cf_ino = statbuf.st_ino;
    cfst.cf_dev = statbuf.st_dev;
    cfst.cf_readlink = linkbuf;

    if (cfst.cf_nlink == CF_NOSIZE)
    {
        cfst.cf_nlink = statbuf.st_nlink;
    }

#if !defined(__MINGW32__)
    if (statbuf.st_size > statbuf.st_blocks * DEV_BSIZE)
#else
# ifdef HAVE_ST_BLOCKS
    if (statbuf.st_size > statbuf.st_blocks * DEV_BSIZE)
# else
    if (statbuf.st_size > ST_NBLOCKS(statbuf) * DEV_BSIZE)
# endif
#endif
    {
        cfst.cf_makeholes = 1;  /* must have a hole to get checksum right */
    }
    else
    {
        cfst.cf_makeholes = 0;
    }

    memset(sendbuffer, 0, CF_BUFSIZE);

    /* send as plain text */

    Log(LOG_LEVEL_DEBUG, "OK: type = %d, mode = %" PRIoMAX ", lmode = %" PRIoMAX ", uid = %" PRIuMAX ", gid = %" PRIuMAX ", size = %" PRIdMAX ", atime=%" PRIdMAX ", mtime = %" PRIdMAX,
            cfst.cf_type, (uintmax_t)cfst.cf_mode, (uintmax_t)cfst.cf_lmode, (intmax_t)cfst.cf_uid, (intmax_t)cfst.cf_gid, (intmax_t) cfst.cf_size,
            (intmax_t) cfst.cf_atime, (intmax_t) cfst.cf_mtime);

    snprintf(sendbuffer, CF_BUFSIZE, "OK: %d %ju %ju %ju %ju %jd %jd %jd %jd %d %d %d %jd",
             cfst.cf_type, (uintmax_t)cfst.cf_mode, (uintmax_t)cfst.cf_lmode,
             (uintmax_t)cfst.cf_uid, (uintmax_t)cfst.cf_gid, (intmax_t)cfst.cf_size,
             (intmax_t) cfst.cf_atime, (intmax_t) cfst.cf_mtime, (intmax_t) cfst.cf_ctime,
             cfst.cf_makeholes, cfst.cf_ino, cfst.cf_nlink, (intmax_t) cfst.cf_dev);

    SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);

    memset(sendbuffer, 0, CF_BUFSIZE);

    if (cfst.cf_readlink != NULL)
    {
        strcpy(sendbuffer, "OK:");
        strcat(sendbuffer, cfst.cf_readlink);
    }
    else
    {
        sprintf(sendbuffer, "OK:");
    }

    SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
    return 0;
}
Пример #17
0
void CfEncryptGetFile(ServerFileGetState *args)
/* Because the stream doesn't end for each file, we need to know the
   exact number of bytes transmitted, which might change during
   encryption, hence we need to handle this with transactions */
{
    int fd, n_read, cipherlen, finlen;
    off_t total = 0, count = 0;
    char sendbuffer[CF_BUFSIZE + 256], out[CF_BUFSIZE], filename[CF_BUFSIZE];
    unsigned char iv[32] =
        { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
    int blocksize = CF_BUFSIZE - 4 * CF_INBAND_OFFSET;
    EVP_CIPHER_CTX ctx;
    char *key, enctype;
    struct stat sb;
    ConnectionInfo *conn_info = &args->connect->conn_info;

    key = (args->connect)->session_key;
    enctype = (args->connect)->encryption_type;

    TranslatePath(filename, args->replyfile);

    stat(filename, &sb);

    Log(LOG_LEVEL_DEBUG, "CfEncryptGetFile('%s'), size = %" PRIdMAX, filename, (intmax_t) sb.st_size);

/* Now check to see if we have remote permission */

    if (!TransferRights(filename, args, &sb))
    {
        RefuseAccess(args->connect, args->buf_size, "");
        FailedTransfer(conn_info);
    }

    EVP_CIPHER_CTX_init(&ctx);

    if ((fd = open(filename, O_RDONLY)) == -1)
    {
        Log(LOG_LEVEL_ERR, "Open error of file '%s'. (open: %s)", filename, GetErrorStr());
        FailedTransfer(conn_info);
    }
    else
    {
        int div = 3;

        if (sb.st_size > 10485760L) /* File larger than 10 MB, checks every 64kB */
        {
            div = 32;
        }

        while (true)
        {
            memset(sendbuffer, 0, CF_BUFSIZE);

            if ((n_read = read(fd, sendbuffer, blocksize)) == -1)
            {
                Log(LOG_LEVEL_ERR, "Read failed in EncryptGetFile. (read: %s)", GetErrorStr());
                break;
            }

            off_t savedlen = sb.st_size;

            if (count++ % div == 0)       /* Don't do this too often */
            {
                Log(LOG_LEVEL_DEBUG, "Restatting '%s' - size %d", filename, n_read);
                if (stat(filename, &sb))
                {
                    Log(LOG_LEVEL_ERR, "Cannot stat file '%s' (stat: %s)",
                            filename, GetErrorStr());
                    break;
                }
            }

            if (sb.st_size != savedlen)
            {
                AbortTransfer(conn_info, filename);
                break;
            }

            total += n_read;

            if (n_read > 0)
            {
                EVP_EncryptInit_ex(&ctx, CfengineCipher(enctype), NULL, key, iv);

                if (!EVP_EncryptUpdate(&ctx, out, &cipherlen, sendbuffer, n_read))
                {
                    FailedTransfer(conn_info);
                    EVP_CIPHER_CTX_cleanup(&ctx);
                    close(fd);
                    return;
                }

                if (!EVP_EncryptFinal_ex(&ctx, out + cipherlen, &finlen))
                {
                    FailedTransfer(conn_info);
                    EVP_CIPHER_CTX_cleanup(&ctx);
                    close(fd);
                    return;
                }
            }

            if (total >= savedlen)
            {
                if (SendTransaction(conn_info, out, cipherlen + finlen, CF_DONE) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    EVP_CIPHER_CTX_cleanup(&ctx);
                    close(fd);
                    return;
                }
                break;
            }
            else
            {
                if (SendTransaction(conn_info, out, cipherlen + finlen, CF_MORE) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    close(fd);
                    EVP_CIPHER_CTX_cleanup(&ctx);
                    return;
                }
            }
        }
    }

    EVP_CIPHER_CTX_cleanup(&ctx);
    close(fd);
}
Пример #18
0
bool CSpecialProtocol::ComparePath(const std::string &path1, const std::string &path2)
{
  return TranslatePath(path1) == TranslatePath(path2);
}
Пример #19
0
void dlgSearchObject::OnSearch(wxCommandEvent &ev)
{
	if (!(chkNames->GetValue() || chkDefinitions->GetValue() || chkComments->GetValue()))
		return; // should not happen

	wxBusyCursor wait;
	ToggleBtnSearch(false);
	if (statusBar)
		statusBar->SetStatusText(_("Searching..."));

	wxString txtPatternStr;
	if (txtPattern->GetValue().Contains(wxT("%")))
		txtPatternStr = currentdb->GetConnection()->qtDbString(txtPattern->GetValue().Lower());
	else
		txtPatternStr = currentdb->GetConnection()->qtDbString(wxT("%") + txtPattern->GetValue().Lower() + wxT("%"));

	/*
	Adding objects:

	Create a sql statement which lists all objects of the specified type and add it to the inner statement with an union.
	We need four columns: type, objectname, path and nspname (schema name). If object is schemaless, set nspname to NULL.
	Parts of the path which has to be translated to the local langauge (because of tree path) must begin with a colon.
	Append the type to the combobox and the mapping table in the constructor. */

	wxString databasePath = parent->GetNodePath(currentdb->GetDatabase()->GetId());
	wxString searchSQL = wxT("SELECT * FROM ( ");

	bool nextMode = false;
	// search names
	if (chkNames->GetValue())
	{
		if (nextMode)
			searchSQL += wxT("UNION \n");
		nextMode = true;
		searchSQL += wxT("SELECT * FROM (  ")
		             wxT("	SELECT  ")
		             wxT("	CASE   ")
		             wxT("		WHEN c.relkind = 'r' THEN 'Tables'   ")
		             wxT("		WHEN c.relkind = 'S' THEN 'Sequences'   ")
		             wxT("		WHEN c.relkind = 'v' THEN 'Views'   ")
		             wxT("		ELSE 'should not happen'   ")
		             wxT("	END AS type, c.relname AS objectname,  ")
		             wxT("	':Schemas/' || n.nspname || '/' ||  ")
		             wxT("	CASE   ")
		             wxT("		WHEN c.relkind = 'r' THEN ':Tables'   ")
		             wxT("		WHEN c.relkind = 'S' THEN ':Sequences'   ")
		             wxT("		WHEN c.relkind = 'v' THEN ':Views'   ")
		             wxT("		ELSE 'should not happen'   ")
		             wxT("	END || '/' || c.relname AS path, n.nspname  ")
		             wxT("	FROM pg_class c  ")
		             wxT("	LEFT JOIN pg_namespace n ON n.oid = c.relnamespace     ")
		             wxT("	WHERE c.relkind in ('r','S','v')  ")
		             wxT("	UNION  ")
		             wxT("	SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname ")
		             wxT("	FROM pg_index idx ")
		             wxT("	JOIN pg_class cls ON cls.oid=indexrelid ")
		             wxT("	JOIN pg_class tab ON tab.oid=indrelid ")
		             wxT("	JOIN pg_namespace n ON n.oid=tab.relnamespace ")
		             wxT("	LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') ")
		             wxT("	LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) ")
		             wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid ")
		             wxT("	LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) ")
		             wxT("	WHERE contype IS NULL ")
		             wxT("	UNION  ")
		             wxT("	SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' END AS type, p.proname,  ")
		             wxT("	':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else ':Functions' end || '/' || p.proname, n.nspname ")
		             wxT("	from pg_proc p  ")
		             wxT("	left join pg_namespace n on p.pronamespace = n.oid  ")
		             wxT("	left join pg_type t on p.prorettype = t.oid  ")
		             wxT("	union  ")
		             wxT("	select 'Schemas', nspname, ':Schemas/' || nspname, nspname from pg_namespace  ")
		             wxT("	union  ")
		             wxT("	select 'Columns', a.attname,  ")
		             wxT("	':Schemas/' || n.nspname || '/' ||  ")
		             wxT("	case   ")
		             wxT("		when t.relkind = 'r' then ':Tables'   ")
		             wxT("		when t.relkind = 'S' then ':Sequences'   ")
		             wxT("		when t.relkind = 'v' then ':Views'   ")
		             wxT("		else 'should not happen'   ")
		             wxT("	end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname  ")
		             wxT("	from pg_attribute a  ")
		             wxT("	inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v')  ")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0  ")
		             wxT("	union  ")
		             wxT("	select 'Constraints', case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname from pg_constraint c    ")
		             wxT("	left join pg_class t on c.conrelid = t.oid  ")
		             wxT("	left join pg_class tf on c.confrelid = tf.oid  ")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid 						 ")
		             wxT("	union  ")
		             wxT("	select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname from pg_rewrite r  ")
		             wxT("	left join pg_class t on r.ev_class = t.oid  ")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid 						 ")
		             wxT("	union  ")
		             wxT("	select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname from pg_trigger tr  ")
		             wxT("	left join pg_class t on tr.tgrelid = t.oid  ")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid  ")
		             wxT("	where ");
		if(currentdb->BackendMinimumVersion(9, 0))
			searchSQL += wxT(" tr.tgisinternal = false ");
		else
			searchSQL += wxT(" tr.tgisconstraint = false ");
		searchSQL += wxT("	union ")
		             wxT("	SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname ")
		             wxT("	FROM pg_type t ")
		             wxT("	LEFT OUTER JOIN pg_type e ON e.oid=t.typelem ")
		             wxT("	LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' ")
		             wxT("	LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid ")
		             wxT("	WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%' 	 ");
		if (!settings->GetShowSystemObjects())
			searchSQL += wxT("   AND ct.oid IS NULL\n");
		searchSQL += wxT("	union ")
		             wxT("	SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname ")
		             wxT("	FROM pg_conversion co ")
		             wxT("	JOIN pg_namespace n ON n.oid=co.connamespace ")
		             wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0	 ")
		             wxT("	union ")
		             wxT("	SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname ")
		             wxT("	FROM pg_cast ca ")
		             wxT("	JOIN pg_type st ON st.oid=castsource ")
		             wxT("	JOIN pg_type tt ON tt.oid=casttarget ")
		             wxT("	union ")
		             wxT("	SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname ")
		             wxT("	FROM pg_language lan ")
		             wxT("	WHERE lanispl IS TRUE ")
		             wxT("	union ")
		             wxT("	SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname ")
		             wxT("	FROM pg_ts_config cfg ")
		             wxT("	left join pg_namespace n on cfg.cfgnamespace = n.oid	 ")
		             wxT("	union ")
		             wxT("	SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname ")
		             wxT("	FROM pg_ts_dict dict ")
		             wxT("	left join pg_namespace ns on dict.dictnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname ")
		             wxT("	FROM pg_ts_parser prs ")
		             wxT("	left join pg_namespace ns on prs.prsnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname ")
		             wxT("	FROM pg_ts_template tmpl ")
		             wxT("	left join pg_namespace ns on tmpl.tmplnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname from pg_type t  ")
		             wxT("	inner join pg_namespace n on t.typnamespace = n.oid ")
		             wxT("	where t.typtype = 'd' ")
		             wxT("	union ")
		             wxT("	select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname , ns.nspname from pg_catalog.pg_aggregate ag ")
		             wxT("	inner join pg_proc pr on ag.aggfnoid = pr.oid ")
		             wxT("	left join pg_namespace ns on  pr.pronamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	select case when rolcanlogin = true then 'Login Roles' else 'Group Roles' end, rolname, case when rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname ")
		             wxT("	from pg_roles ")
		             wxT("	union ")
		             wxT("	select 'Tablespaces', spcname, ':Tablespaces/'||spcname, NULL as nspname from pg_tablespace ")
		             wxT("	union ")
		             wxT("	SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname ")
		             wxT("	FROM pg_operator op ")
		             wxT("	left join pg_namespace ns on op.oprnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname ")
		             wxT("	FROM pg_opclass op ")
		             wxT("	left join pg_namespace ns on op.opcnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname ")
		             wxT("	FROM pg_opfamily opf ")
		             wxT("	left join pg_namespace ns on opf.opfnamespace = ns.oid ");

		if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser())
		{
			searchSQL += wxT("	union ")
			             wxT("	select 'Foreign Data Wrappers', fdwname, ':Foreign Data Wrappers/' || fdwname, NULL as nspname from pg_foreign_data_wrapper ")
			             wxT("	union ")
			             wxT("	select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname from pg_foreign_server sr ")
			             wxT("	inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ")
			             wxT("	union ")
			             wxT("	select 'User Mappings', ro.rolname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname || '/:User Mappings/' || ro.rolname, NULL as nspname from pg_user_mapping um ")
			             wxT("	inner join pg_roles ro on um.umuser = ro.oid ")
			             wxT("	inner join pg_foreign_server sr on um.umserver = sr.oid ")
			             wxT("	inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ");
		}

		if(currentdb->BackendMinimumVersion(9, 1))
		{
			searchSQL += wxT("	union ")
			             wxT("	select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname from pg_foreign_table ft ")
			             wxT("	inner join pg_class c on ft.ftrelid = c.oid ")
			             wxT("	inner join pg_namespace ns on c.relnamespace = ns.oid ")
			             wxT("	union ")
			             wxT("	select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL as nspname ")
			             wxT("	FROM pg_extension x	")
			             wxT("	JOIN pg_namespace n on x.extnamespace=n.oid ")
			             wxT("	join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name ")
			             wxT("	union ")
			             wxT("	SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname ")
			             wxT("	FROM pg_collation c ")
			             wxT("	JOIN pg_namespace n ON n.oid=c.collnamespace ");
		}

		searchSQL += wxT(") sn \n")
		             wxT("where lower(sn.objectname) like ") + txtPatternStr + wxT(" \n");
	} // search names

		// search definitions
	if (chkDefinitions->GetValue())
	{
		if (nextMode)
			searchSQL += wxT("UNION \n");
		nextMode = true;
		searchSQL += wxT("SELECT * FROM (  ") // Function's source code
		             wxT("	SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' END AS type, p.proname as objectname,  ")
		             wxT("	':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else ':Functions' end || '/' || p.proname as path, n.nspname ")
		             wxT("	from pg_proc p  ")
		             wxT("	left join pg_namespace n on p.pronamespace = n.oid  ")
		             wxT("	left join pg_type t on p.prorettype = t.oid  ")
		             wxT("WHERE p.prosrc ILIKE ") + txtPatternStr + wxT(" ")
		             wxT("UNION ") // Column's type name and default value
		             wxT("select 'Columns', a.attname, ")
		             wxT("':Schemas/' || n.nspname || '/' || ")
		             wxT("case   ")
		             wxT("	when t.relkind = 'r' then ':Tables' ")
		             wxT("	when t.relkind = 'S' then ':Sequences' ")
		             wxT("	when t.relkind = 'v' then ':Views' ")
		             wxT("	else 'should not happen' ")
		             wxT("end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname ")
		             wxT("from pg_attribute a ")
		             wxT("inner join pg_type ty on a.atttypid = ty.oid ")
		             wxT("left join pg_attrdef ad on a.attrelid = ad.adrelid and a.attnum = ad.adnum ")
		             wxT("inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v') ")
		             wxT("left join pg_namespace n on t.relnamespace = n.oid ")
		             wxT("where a.attnum > 0 ")
		             wxT("  and (ty.typname ilike ") + txtPatternStr + wxT(" or ad.adsrc ilike ") + txtPatternStr + wxT(") ")
		             wxT("UNION ") // View's definition
		             wxT("SELECT 'Views', c.relname, ")
		             wxT("':Schemas/' || n.nspname || '/:Views/' || c.relname, n.nspname ")
		             wxT(" FROM pg_class c ")
		             wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace ")
		             wxT(" WHERE c.relkind = 'v' ")
		             wxT("  and pg_get_viewdef(c.oid) ilike ") + txtPatternStr + wxT(" ")
		             wxT("UNION ") // Relation's column names except for Views (searched earlier)
		             wxT("SELECT CASE ")
		             wxT("  WHEN c.relkind = 'c' THEN 'Types' ")
		             wxT("	WHEN c.relkind = 'r' THEN 'Tables' ")
		             wxT("	WHEN c.relkind = 'f' THEN 'Foreign Tables' ")
		             wxT("	ELSE 'should not happen' ")
		             wxT("	END AS type, c.relname AS objectname, ")
		             wxT("	':Schemas/' || n.nspname || '/' || ")
		             wxT("	CASE ")
		             wxT("	WHEN c.relkind = 'c' THEN ':Types' ")
		             wxT("	WHEN c.relkind = 'r' THEN ':Tables' ")
		             wxT("	WHEN c.relkind = 'f' THEN ':Foreign Tables' ")
		             wxT("	ELSE 'should not happen' ")
		             wxT("	END || '/' || c.relname AS path, n.nspname ")
		             wxT(" from pg_attribute a ")
		             wxT(" inner join pg_class c on a.attrelid = c.oid and c.relkind in ('c','r','f') ")
		             wxT(" left join pg_namespace n on c.relnamespace = n.oid ")
		             wxT(" where a.attname ilike ") + txtPatternStr + wxT(" ");
		             // TODO: search for other object's definitions (indexes, constraints and so on)
		searchSQL += wxT(") sd \n");
	} // search definitions

	// search comments
	if (chkComments->GetValue())
	{
		if (nextMode)
			searchSQL += wxT("UNION \n");
		nextMode = true;

		wxString pd = wxT("(select pd.objoid, pd.classoid, pd.objsubid, c.relname")
		              wxT("  from pg_description pd")
		              wxT("  join pg_class c on pd.classoid = c.oid")
		              wxT(" where pd.description ilike ") + txtPatternStr + wxT(" UNION ")
		              wxT("select psd.objoid, psd.classoid, NULL as objsubid, c.relname")
		              wxT("  from pg_shdescription psd")
		              wxT("  join pg_class c on psd.classoid = c.oid")
		              wxT(" where psd.description ilike ") + txtPatternStr + wxT(") ");

		searchSQL += wxT("SELECT * FROM (  ");
		if(currentdb->BackendMinimumVersion(8, 4)) // Common Table Expressions are available
		{
			searchSQL += wxT("with pd as ") + pd;
			pd = wxT("pd ");
		}
		else // use pd as a subquery
			pd += wxT(" pd ");

		searchSQL += wxT("SELECT CASE")
		             wxT("	WHEN c.relkind = 'r' THEN 'Tables'")
		             wxT("	WHEN c.relkind = 'S' THEN 'Sequences'")
		             wxT("	WHEN c.relkind = 'v' THEN 'Views'")
		             wxT("	ELSE 'should not happen'")
		             wxT("	END AS type, c.relname AS objectname,")
		             wxT("	':Schemas/' || n.nspname || '/' ||")
		             wxT("	CASE")
		             wxT("	WHEN c.relkind = 'r' THEN ':Tables'")
		             wxT("	WHEN c.relkind = 'S' THEN ':Sequences'")
		             wxT("	WHEN c.relkind = 'v' THEN ':Views'")
		             wxT("	ELSE 'should not happen'")
		             wxT("	END || '/' || c.relname AS path, n.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_class c on pd.relname = 'pg_class' and pd.objoid = c.oid")
		             wxT("	LEFT JOIN pg_namespace n ON n.oid = c.relnamespace")
		             wxT("	WHERE c.relkind in ('r','S','v')")
		             wxT("	UNION")
		             wxT("	SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_class cls ON pd.relname = 'pg_class' and pd.objoid = cls.oid")
		             wxT("	JOIN pg_index idx ON cls.oid=indexrelid")
		             wxT("	JOIN pg_class tab ON tab.oid=indrelid")
		             wxT("	JOIN pg_namespace n ON n.oid=tab.relnamespace")
		             wxT("	LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')")
		             wxT("	LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)")
		             wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid")
		             wxT("	LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)")
		             wxT("	WHERE contype IS NULL")
		             wxT("	UNION")
		             wxT("  select case when p_t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' end as type,")
		             wxT("       p_.proname AS objectname,")
		             wxT("       ':Schemas/' || n.nspname || '/' ||")
		             wxT("         case when p_t.typname = 'trigger' then ':Trigger Functions/' else ':Functions/' end || p_.proname AS path, n.nspname")
		             wxT("  from ") + pd +
		             wxT("  join pg_proc p_  on pd.relname = 'pg_proc' and pd.objoid = p_.oid and p_.proisagg = false")
		             wxT("	left join pg_type p_t on p_.prorettype = p_t.oid")
		             wxT("	left join pg_namespace n on p_.pronamespace = n.oid")
		             wxT("	union")
		             wxT("	select 'Schemas', n_.nspname, ':Schemas/' || n_.nspname, n_.nspname")
		             wxT("	  from ") + pd +
		             wxT("  join pg_namespace n_  on pd.relname = 'pg_namespace' and pd.objoid = n_.oid")
		             wxT("	union")
		             wxT("  select 'Columns', a.attname,")
		             wxT("	':Schemas/' || n.nspname || '/' ||")
		             wxT("	case")
		             wxT("	when t.relkind = 'r' then ':Tables'")
		             wxT("	when t.relkind = 'S' then ':Sequences'")
		             wxT("	when t.relkind = 'v' then ':Views'")
		             wxT("	else 'should not happen'")
		             wxT("	end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname")
		             wxT("	from ") + pd +
		             wxT("	join pg_class t on pd.relname = 'pg_class' and pd.objoid = t.oid and t.relkind in ('r','v')")
		             wxT("  join pg_attribute a on a.attrelid = t.oid and pd.objsubid = a.attnum")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0")
		             wxT("	union")
		             wxT("	select 'Constraints',")
		             wxT("	  case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end,")
		             wxT("	  ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'")
		             wxT("	    ||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname")
		             wxT("  from ") + pd +
		             wxT("  join pg_constraint c on pd.relname = 'pg_constraint' and pd.objoid = c.oid")
		             wxT("	left join pg_class t on c.conrelid = t.oid")
		             wxT("	left join pg_class tf on c.confrelid = tf.oid")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid")
		             wxT("	union")
		             wxT("  select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname")
		             wxT("	from ") + pd +
		             wxT("	join pg_rewrite r on pd.relname = 'pg_rewrite' and pd.objoid = r.oid")
		             wxT("	left join pg_class t on r.ev_class = t.oid")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid")
		             wxT("	union")
		             wxT("	select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname")
		             wxT("	from ") + pd +
		             wxT("	join pg_trigger tr on pd.relname = 'pg_trigger' and pd.objoid = tr.oid")
		             wxT("	left join pg_class t on tr.tgrelid = t.oid")
		             wxT("	left join pg_namespace n on t.relnamespace = n.oid WHERE ");
		if(currentdb->BackendMinimumVersion(9, 0))
			searchSQL += wxT(" tr.tgisinternal = false ");
		else
			searchSQL += wxT(" tr.tgisconstraint = false ");
		searchSQL += wxT("	union")
		             wxT("	SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid")
		             wxT("	LEFT OUTER JOIN pg_type e ON e.oid=t.typelem")
		             wxT("	LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'")
		             wxT("	LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid")
		             wxT("	WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%'")
		             wxT("	union")
		             wxT("	SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_conversion co on pd.relname = 'pg_conversion' and pd.objoid = co.oid")
		             wxT("	JOIN pg_namespace n ON n.oid=co.connamespace")
		             wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0")
		             wxT("	union")
		             wxT("	SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_cast ca on pd.relname = 'pg_cast' and pd.objoid = ca.oid")
		             wxT("	JOIN pg_type st ON st.oid=castsource")
		             wxT("	JOIN pg_type tt ON tt.oid=casttarget")
		             wxT("	union")
		             wxT("	SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_language lan on pd.relname = 'pg_language' and pd.objoid = lan.oid")
		             wxT("	WHERE lanispl IS TRUE")
		             wxT("	union")
		             wxT("	SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_ts_config cfg on pd.relname = 'pg_ts_config' and pd.objoid = cfg.oid")
		             wxT("	left join pg_namespace n on cfg.cfgnamespace = n.oid")
		             wxT("	union")
		             wxT("	SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_ts_dict dict on pd.relname = 'pg_ts_dict' and pd.objoid = dict.oid")
		             wxT("	left join pg_namespace ns on dict.dictnamespace = ns.oid")
		             wxT("	union")
		             wxT("	SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_ts_parser prs on pd.relname = 'pg_ts_parser' and pd.objoid = prs.oid")
		             wxT("	left join pg_namespace ns on prs.prsnamespace = ns.oid")
		             wxT("	union")
		             wxT("	SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_ts_template tmpl on pd.relname = 'pg_ts_template' and pd.objoid = tmpl.oid")
		             wxT("	left join pg_namespace ns on tmpl.tmplnamespace = ns.oid")
		             wxT("	union")
		             wxT("	select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname")
		             wxT("  FROM ") + pd +
		             wxT("  JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid")
		             wxT("	inner join pg_namespace n on t.typnamespace = n.oid")
		             wxT("	where t.typtype = 'd'")
		             wxT("	union")
		             wxT("	select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname, ns.nspname")
		             wxT("	from ") + pd +
		             wxT("	join pg_proc pr on pd.relname = 'pg_proc' and pd.objoid = pr.oid")
		             wxT("	JOIN pg_catalog.pg_aggregate ag on ag.aggfnoid = pr.oid")
		             wxT("	left join pg_namespace ns on  pr.pronamespace = ns.oid")
		             wxT("	union")
		             wxT("	select case when r_.rolcanlogin = true then 'Login Roles' else 'Group Roles' end, r_.rolname,")
		             wxT("	       case when r_.rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname")
		             wxT("	from ") + pd +
		             wxT("	join pg_roles r_ on pd.relname = 'pg_authid' and pd.objoid = r_.oid")
		             wxT("	union")
		             wxT("	select 'Tablespaces', ts_.spcname, ':Tablespaces/'||ts_.spcname, NULL as nspname")
		             wxT("	  from ") + pd +
		             wxT("	  JOIN pg_tablespace ts_ on pd.relname = 'pg_tablespace' and pd.objoid = ts_.oid")
		             wxT("	union")
		             wxT("	SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_operator op ON pd.relname = 'pg_operator' and pd.objoid = op.oid")
		             wxT("	left join pg_namespace ns on op.oprnamespace = ns.oid")
		             wxT("	union")
		             wxT("	SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_opclass op ON pd.relname = 'pg_opclass' and pd.objoid = op.oid")
		             wxT("	left join pg_namespace ns on op.opcnamespace = ns.oid")
		             wxT("	union")
		             wxT("	SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname")
		             wxT("	FROM ") + pd +
		             wxT("	JOIN pg_opfamily opf ON pd.relname = 'pg_opfamily' and pd.objoid = opf.oid")
		             wxT("	left join pg_namespace ns on opf.opfnamespace = ns.oid");

		if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser())
		{
			searchSQL += wxT("	union")
		                 wxT("	select 'Foreign Data Wrappers', fdw.fdwname, ':Foreign Data Wrappers/' || fdw.fdwname, NULL as nspname ")
		                 wxT("	  from ") + pd +
		                 wxT("	  JOIN pg_foreign_data_wrapper fdw ON pd.relname = 'pg_foreign_data_wrapper' and pd.objoid = fdw.oid")
		                 wxT("	union ")
		                 wxT("	select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname")
		                 wxT("	  from ") + pd +
		                 wxT("	  JOIN pg_foreign_server sr ON pd.relname = 'pg_foreign_server' and pd.objoid = sr.oid")
		                 wxT("	inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ");
		}

		if(currentdb->BackendMinimumVersion(9, 1))
		{
			searchSQL += wxT("	union")
		                 wxT("	select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname")
		                 wxT("  from ") + pd +
		                 wxT("  JOIN pg_class c ON pd.relname = 'pg_class' and pd.objoid = c.oid")
		                 wxT("  join pg_foreign_table ft on ft.ftrelid = c.oid")
		                 wxT("	inner join pg_namespace ns on c.relnamespace = ns.oid")
		                 wxT("  union")
		                 wxT("	select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL AS nspname")
		                 wxT("	FROM ") + pd +
		                 wxT("	JOIN pg_extension x ON pd.relname = 'pg_extension' and pd.objoid = x.oid")
		                 wxT("	JOIN pg_namespace n on x.extnamespace=n.oid")
		                 wxT("	join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name")
		                 wxT("	union")
		                 wxT("	SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname")
		                 wxT("	FROM ") + pd +
		                 wxT("	JOIN pg_collation c ON pd.relname = 'pg_collation' and pd.objoid = c.oid")
		                 wxT("	JOIN pg_namespace n ON n.oid=c.collnamespace");
		}
		searchSQL += wxT(") sc \n");
	} // search comments

	searchSQL += wxT(") ii \n");

	bool nextPredicate = false;
	if (cbType->GetValue() != _("All types"))
	{
		searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE ");
		nextPredicate = true;
		searchSQL += wxT("ii.type = ") + currentdb->GetConnection()->qtDbString(aMap[cbType->GetValue()]) + wxT(" ");
	}

	if (cbSchema->GetSelection() == cbSchemaIdxCurrent && !currentSchema.IsEmpty())
	{
		searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE ");
		nextPredicate = true;
		searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(currentSchema) + wxT(" ");
	}
	else if (cbSchema->GetValue() == _("My schemas"))
	{
		searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE ");
		nextPredicate = true;
		searchSQL += wxT("ii.nspname IN (SELECT n.nspname FROM pg_namespace n WHERE n.nspowner = (SELECT u.usesysid FROM pg_user u WHERE u.usename = ")
		           + currentdb->GetConnection()->qtDbString(currentdb->GetConnection()->GetUser()) + wxT(")) ");
	}
	else if (cbSchema->GetValue() != _("All schemas"))
	{
		searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE ");
		nextPredicate = true;
		searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(cbSchema->GetValue()) + wxT(" ");
	}

	searchSQL += wxT("ORDER BY 1, 2, 3");

	pgSet *set = currentdb->GetConnection()->ExecuteSet(searchSQL);
	int i = 0;
	if(set)
	{
		lcResults->DeleteAllItems();

		while(!set->Eof())
		{
			wxString objectType = set->GetVal(wxT("type"));
			wxString objectName = set->GetVal(wxT("objectname"));
			wxString ItemPath;


			/* Login Roles, Group Roles and Tablespaces are "outside" the database, so we have to adjust the path */
			if(objectType == wxT("Login Roles") || objectType == wxT("Group Roles") || objectType == wxT("Tablespaces"))
			{
				wxStringTokenizer tkz(databasePath, wxT("/"));
				wxString newPath;
				while(tkz.HasMoreTokens())
				{
					wxString token = tkz.GetNextToken();
					if(token == _("Databases"))
						break;
					ItemPath += token + wxT("/");
				}
				ItemPath += set->GetVal(wxT("path"));
			}
			else
			{
				ItemPath = databasePath + wxT("/") + set->GetVal(wxT("path"));
			}

			if(ItemPath.Contains(wxT("Schemas/information_schema")))
			{
				/* In information Schema only views and columns are displayed, nothing else */
				if(objectType == wxT("Views") || objectType == wxT("Columns"))
				{
					ItemPath.Replace(wxT(":Schemas/information_schema"), wxT(":Catalogs/ANSI/:Catalog Objects"));
					ItemPath.Replace(wxT(":Views/"), wxT(""));
				}
				else
				{
					set->MoveNext();
					continue;
				}
			}

			if(ItemPath.Contains(wxT("Schemas/pg_catalog")))
			{
				ItemPath.Replace(wxT(":Schemas/pg_catalog"), wxT(":Catalogs/PostgreSQL"));
			}

			wxListItem item;
			item.SetId(i);
			lcResults->InsertItem(item);

			wxString locTypeStr = wxGetTranslation(set->GetVal(wxT("type")));

			/* Check if viewing of the specified object is enabled in settings */
			if(!settings->GetDisplayOption(locTypeStr))
			{
				lcResults->SetItemTextColour(i, wxColour(128, 128, 128));
			}

			lcResults->SetItem(i, 0, locTypeStr);
			lcResults->SetItem(i, 1, objectName);
			lcResults->SetItem(i, 2, TranslatePath(ItemPath));
			set->MoveNext();
			i++;
		}
		delete set;
	}

	if(lcResults->GetItemCount() > 0)
	{
		lcResults->SetColumnWidth(0, wxLIST_AUTOSIZE);
		lcResults->SetColumnWidth(1, wxLIST_AUTOSIZE);
		lcResults->SetColumnWidth(2, wxLIST_AUTOSIZE);
	}

	if (statusBar)
	{
		if (i > 0)
			statusBar->SetStatusText(wxString::Format(wxPLURAL("Found %d item", "Found %d items",i), i));
		else
			statusBar->SetStatusText(_("Nothing was found"));
	}

	ToggleBtnSearch(true);
}
Пример #20
0
std::time_t RelativeDevice::GetModifiedTime(const std::string& fileName)
{
	return m_otherDevice->GetModifiedTime(TranslatePath(fileName));
}
Пример #21
0
void CfGetFile(ServerFileGetState *args)
{
    int fd;
    off_t n_read, total = 0, sendlen = 0, count = 0;
    char sendbuffer[CF_BUFSIZE + 256], filename[CF_BUFSIZE];
    struct stat sb;
    int blocksize = 2048;

    ConnectionInfo *conn_info = &(args->connect)->conn_info;

    TranslatePath(filename, args->replyfile);

    stat(filename, &sb);

    Log(LOG_LEVEL_DEBUG, "CfGetFile('%s'), size = %" PRIdMAX, filename, (intmax_t) sb.st_size);

/* Now check to see if we have remote permission */

    if (!TransferRights(filename, args, &sb))
    {
        RefuseAccess(args->connect, args->buf_size, "");
        snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR);
        if (conn_info->type == CF_PROTOCOL_CLASSIC)
        {
            SendSocketStream(conn_info->sd, sendbuffer, args->buf_size);
        }
        else if (conn_info->type == CF_PROTOCOL_TLS)
        {
            TLSSend(conn_info->ssl, sendbuffer, args->buf_size);
        }
        return;
    }

/* File transfer */

    if ((fd = open(filename, O_RDONLY)) == -1)
    {
        Log(LOG_LEVEL_ERR, "Open error of file '%s'. (open: %s)",
            filename, GetErrorStr());
        snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR);
        if (conn_info->type == CF_PROTOCOL_CLASSIC)
        {
            SendSocketStream(conn_info->sd, sendbuffer, args->buf_size);
        }
        else if (conn_info->type == CF_PROTOCOL_TLS)
        {
            TLSSend(conn_info->ssl, sendbuffer, args->buf_size);
        }
    }
    else
    {
        int div = 3;

        if (sb.st_size > 10485760L) /* File larger than 10 MB, checks every 64kB */
        {
            div = 32;
        }

        while (true)
        {
            memset(sendbuffer, 0, CF_BUFSIZE);

            Log(LOG_LEVEL_DEBUG, "Now reading from disk...");

            if ((n_read = read(fd, sendbuffer, blocksize)) == -1)
            {
                Log(LOG_LEVEL_ERR, "Read failed in GetFile. (read: %s)", GetErrorStr());
                break;
            }

            if (n_read == 0)
            {
                break;
            }
            else
            {
                off_t savedlen = sb.st_size;

                /* check the file is not changing at source */

                if (count++ % div == 0)   /* Don't do this too often */
                {
                    if (stat(filename, &sb))
                    {
                        Log(LOG_LEVEL_ERR, "Cannot stat file '%s'. (stat: %s)",
                            filename, GetErrorStr());
                        break;
                    }
                }

                if (sb.st_size != savedlen)
                {
                    snprintf(sendbuffer, CF_BUFSIZE, "%s%s: %s", CF_CHANGEDSTR1, CF_CHANGEDSTR2, filename);

                    if (conn_info->type == CF_PROTOCOL_CLASSIC)
                    {
                        if (SendSocketStream(conn_info->sd, sendbuffer, blocksize) == -1)
                        {
                            Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                        }
                    }
                    else if (conn_info->type == CF_PROTOCOL_TLS)
                    {
                        if (TLSSend(conn_info->ssl, sendbuffer, blocksize) == -1)
                        {
                            Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                        }
                    }

                    Log(LOG_LEVEL_DEBUG, "Aborting transfer after %" PRIdMAX ": file is changing rapidly at source.", (intmax_t)total);
                    break;
                }

                if ((savedlen - total) / blocksize > 0)
                {
                    sendlen = blocksize;
                }
                else if (savedlen != 0)
                {
                    sendlen = (savedlen - total);
                }
            }

            total += n_read;

            if (conn_info->type == CF_PROTOCOL_CLASSIC)
            {
                if (SendSocketStream(conn_info->sd, sendbuffer, sendlen) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    break;
                }
            }
            else if (conn_info->type == CF_PROTOCOL_TLS)
            {
                if (TLSSend(conn_info->ssl, sendbuffer, sendlen) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    break;
                }
            }
        }

        close(fd);
    }
}
Пример #22
0
std::string CLegacyPathTranslation::TranslateVideoDbPath(const std::string &legacyPath)
{
  return TranslatePath(legacyPath, s_videoDbTranslator, VideoDbTranslatorSize);
}
Пример #23
0
static int AccessControl(EvalContext *ctx, const char *req_path, ServerConnectionState *conn, int encrypt)
{
    int access = false;
    char transrequest[CF_BUFSIZE];
    struct stat statbuf;
    char translated_req_path[CF_BUFSIZE];
    char transpath[CF_BUFSIZE];

/*
 * /var/cfengine -> $workdir translation.
 */
    TranslatePath(translated_req_path, req_path);

    if (ResolveFilename(translated_req_path, transrequest))
    {
        Log(LOG_LEVEL_VERBOSE, "Filename %s is resolved to %s", translated_req_path, transrequest);
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Couldn't resolve (realpath: %s) filename: %s",
            GetErrorStr(), translated_req_path);
        return false;                /* can't continue without transrequest */
    }

    if (lstat(transrequest, &statbuf) == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't stat (lstat: %s) filename: %s",
            GetErrorStr(), transrequest);
        return false;
    }

    Log(LOG_LEVEL_DEBUG, "AccessControl, match (%s,%s) encrypt request = %d", transrequest, conn->hostname, encrypt);

    if (SV.admit == NULL)
    {
        Log(LOG_LEVEL_INFO, "cf-serverd access list is empty, no files are visible");
        return false;
    }

    conn->maproot = false;

    for (Auth *ap = SV.admit; ap != NULL; ap = ap->next)
    {
        int res = false;

        Log(LOG_LEVEL_DEBUG, "Examining rule in access list (%s,%s)", transrequest, ap->path);

        /* TODO MapName when constructing this list. */
        strncpy(transpath, ap->path, CF_BUFSIZE - 1);
        MapName(transpath);

        /* If everything is allowed */
        if ((strcmp(transpath, FILE_SEPARATOR_STR) == 0)
            ||
            /* or if transpath is a parent directory of transrequest */
            (strlen(transrequest) > strlen(transpath)
            && strncmp(transpath, transrequest, strlen(transpath)) == 0
            && transrequest[strlen(transpath)] == FILE_SEPARATOR)
            ||
            /* or if it's an exact match */
            (strcmp(transpath, transrequest) == 0))
        {
            res = true;
        }

        /* Exact match means single file to admit */
        if (strcmp(transpath, transrequest) == 0)
        {
            res = true;
        }

        if (res)
        {
            Log(LOG_LEVEL_VERBOSE, "Found a matching rule in access list (%s in %s)", transrequest, transpath);

            if (stat(transpath, &statbuf) == -1)
            {
                Log(LOG_LEVEL_INFO,
                      "Warning cannot stat file object %s in admit/grant, or access list refers to dangling link",
                      transpath);
                continue;
            }

            if ((!encrypt) && (ap->encrypt == true))
            {
                Log(LOG_LEVEL_ERR, "File %s requires encrypt connection...will not serve", transpath);
                access = false;
            }
            else
            {
                Log(LOG_LEVEL_DEBUG, "Checking whether to map root privileges..");

                if ((IsMatchItemIn(ap->maproot, MapAddress(conn->ipaddr))) ||
                    (IsRegexItemIn(ctx, ap->maproot, conn->hostname)))
                {
                    conn->maproot = true;
                    Log(LOG_LEVEL_VERBOSE, "Mapping root privileges to access non-root files");
                }

                if ((IsMatchItemIn(ap->accesslist, MapAddress(conn->ipaddr)))
                    || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname)))
                {
                    access = true;
                    Log(LOG_LEVEL_DEBUG, "Access granted to host: %s", conn->ipaddr);
                }
            }
            break;
        }
    }

    for (Auth *dp = SV.deny; dp != NULL; dp = dp->next)
    {
        strncpy(transpath, dp->path, CF_BUFSIZE - 1);
        MapName(transpath);

        /* If everything is denied */
        if ((strcmp(transpath, FILE_SEPARATOR_STR) == 0)
            ||
            /* or if transpath is a parent directory of transrequest */
            (strlen(transrequest) > strlen(transpath) &&
             strncmp(transpath, transrequest, strlen(transpath)) == 0 &&
             transrequest[strlen(transpath)] == FILE_SEPARATOR)
            ||
            /* or if it's an exact match */
            (strcmp(transpath, transrequest) == 0))
        {
            if ((IsMatchItemIn(dp->accesslist, MapAddress(conn->ipaddr))) ||
                (IsRegexItemIn(ctx, dp->accesslist, conn->hostname)))
            {
                access = false;
                Log(LOG_LEVEL_INFO, "Host '%s' in deny list, explicitly denying access to '%s'",
                    conn->ipaddr, transrequest);
                break;
            }
        }
    }

    if (access)
    {
        Log(LOG_LEVEL_VERBOSE, "Host %s granted access to %s", conn->hostname, req_path);

        if (encrypt && LOGENCRYPT)
        {
            /* Log files that were marked as requiring encryption */
            Log(LOG_LEVEL_INFO, "Host %s granted access to %s", conn->hostname, req_path);
        }
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Host %s denied access to %s", conn->hostname, req_path);
    }

    return access;
}
Пример #24
0
void dlgSearchObject::OnSearch(wxCommandEvent &ev)
{

	/*
	Adding objects:

	Create a sql statement which lists all objects of the specified type and add it to the inner statement with an union.
	We need three columns: type, objectname and path.
	Parts of the path which has to be translated to the local langauge (because of tree path) must begin with a colon.
	Append the type to the combobox and the mapping table in the constructor. */

	wxString databasePath = parent->GetNodePath(currentdb->GetDatabase()->GetId());
	wxString searchSQL = wxT("SELECT * FROM (  ")
	                     wxT("	SELECT  ")
	                     wxT("	CASE   ")
	                     wxT("		WHEN c.relkind = 'r' THEN 'Tables'   ")
	                     wxT("		WHEN c.relkind = 'S' THEN 'Sequences'   ")
	                     wxT("		WHEN c.relkind = 'v' THEN 'Views'   ")
	                     wxT("		ELSE 'should not happen'   ")
	                     wxT("	END AS type, c.relname AS objectname,  ")
	                     wxT("	':Schemas/' || n.nspname || '/' ||  ")
	                     wxT("	CASE   ")
	                     wxT("		WHEN c.relkind = 'r' THEN ':Tables'   ")
	                     wxT("		WHEN c.relkind = 'S' THEN ':Sequences'   ")
	                     wxT("		WHEN c.relkind = 'v' THEN ':Views'   ")
	                     wxT("		ELSE 'should not happen'   ")
	                     wxT("	END || '/' || c.relname AS path  ")
	                     wxT("	FROM pg_class c  ")
	                     wxT("	LEFT JOIN pg_namespace n ON n.oid = c.relnamespace     ")
	                     wxT("	WHERE c.relkind in ('r','S','v')  ")
	                     wxT("	UNION  ")
	                     wxT("	SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname ")
	                     wxT("	FROM pg_index idx ")
	                     wxT("	JOIN pg_class cls ON cls.oid=indexrelid ")
	                     wxT("	JOIN pg_class tab ON tab.oid=indrelid ")
	                     wxT("	JOIN pg_namespace n ON n.oid=tab.relnamespace ")
	                     wxT("	LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') ")
	                     wxT("	LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) ")
	                     wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid ")
	                     wxT("	LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) ")
	                     wxT("	WHERE contype IS NULL ")
	                     wxT("	UNION  ")
	                     wxT("	SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' END AS type, p.proname,  ")
	                     wxT("	':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else ':Functions' end || '/' || p.proname ")
	                     wxT("	from pg_proc p  ")
	                     wxT("	left join pg_namespace n on p.pronamespace = n.oid  ")
	                     wxT("	left join pg_type t on p.prorettype = t.oid  ")
	                     wxT("	union  ")
	                     wxT("	select 'Schemas', nspname, ':Schemas/' || nspname from pg_namespace  ")
	                     wxT("	union  ")
	                     wxT("	select 'Columns', a.attname,  ")
	                     wxT("	':Schemas/' || n.nspname || '/' ||  ")
	                     wxT("	case   ")
	                     wxT("		when t.relkind = 'r' then ':Tables'   ")
	                     wxT("		when t.relkind = 'S' then ':Sequences'   ")
	                     wxT("		when t.relkind = 'v' then ':Views'   ")
	                     wxT("		else 'should not happen'   ")
	                     wxT("	end || '/' || t.relname || '/:Columns/' || a.attname AS path  ")
	                     wxT("	from pg_attribute a  ")
	                     wxT("	inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v')  ")
	                     wxT("	left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0  ")
	                     wxT("	union  ")
	                     wxT("	select 'Constraints', case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end from pg_constraint c    ")
	                     wxT("	left join pg_class t on c.conrelid = t.oid  ")
	                     wxT("	left join pg_class tf on c.confrelid = tf.oid  ")
	                     wxT("	left join pg_namespace n on t.relnamespace = n.oid 						 ")
	                     wxT("	union  ")
	                     wxT("	select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename from pg_rewrite r  ")
	                     wxT("	left join pg_class t on r.ev_class = t.oid  ")
	                     wxT("	left join pg_namespace n on t.relnamespace = n.oid 						 ")
	                     wxT("	union  ")
	                     wxT("	select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind = 'v' then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname from pg_trigger tr  ")
	                     wxT("	left join pg_class t on tr.tgrelid = t.oid  ")
	                     wxT("	left join pg_namespace n on t.relnamespace = n.oid  ")
	                     wxT("	where ");
	if(currentdb->BackendMinimumVersion(9, 0))
	{
		searchSQL += wxT(" tr.tgisinternal = false ");
	}
	else
	{
		searchSQL += wxT(" tr.tgisconstraint = false ");
	}
	searchSQL += wxT("	union ")
	             wxT("	SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types' || t.typname ")
	             wxT("	FROM pg_type t ")
	             wxT("	LEFT OUTER JOIN pg_type e ON e.oid=t.typelem ")
	             wxT("	LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' ")
	             wxT("	LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid ")
	             wxT("	WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' 	 ")
	             wxT("	union ")
	             wxT("	SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname ")
	             wxT("	FROM pg_conversion co ")
	             wxT("	JOIN pg_namespace n ON n.oid=co.connamespace ")
	             wxT("	LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0	 ")
	             wxT("	union ")
	             wxT("	SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) ")
	             wxT("	FROM pg_cast ca ")
	             wxT("	JOIN pg_type st ON st.oid=castsource ")
	             wxT("	JOIN pg_type tt ON tt.oid=casttarget ")
	             wxT("	union ")
	             wxT("	SELECT 'Languages', lanname, ':Languages/' || lanname ")
	             wxT("	FROM pg_language lan ")
	             wxT("	WHERE lanispl IS TRUE ")
	             wxT("	union ")
	             wxT("	SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname ")
	             wxT("	FROM pg_ts_config cfg ")
	             wxT("	left join pg_namespace n on cfg.cfgnamespace = n.oid	 ")
	             wxT("	union ")
	             wxT("	SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname ")
	             wxT("	FROM pg_ts_dict dict ")
	             wxT("	left join pg_namespace ns on dict.dictnamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname ")
	             wxT("	FROM pg_ts_parser prs ")
	             wxT("	left join pg_namespace ns on prs.prsnamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname ")
	             wxT("	FROM pg_ts_template tmpl ")
	             wxT("	left join pg_namespace ns on tmpl.tmplnamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname from pg_type t  ")
	             wxT("	inner join pg_namespace n on t.typnamespace = n.oid ")
	             wxT("	where t.typtype = 'd' ")
	             wxT("	union ")
	             wxT("	select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname from pg_catalog.pg_aggregate ag ")
	             wxT("	inner join pg_proc pr on ag.aggfnoid = pr.oid ")
	             wxT("	left join pg_namespace ns on  pr.pronamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	select case when rolcanlogin = true then 'Login Roles' else 'Group Roles' end, rolname, case when rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname ")
	             wxT("	from pg_roles ")
	             wxT("	union ")
	             wxT("	select 'Tablespaces', spcname, ':Tablespaces/'||spcname from pg_tablespace ")
	             wxT("	union ")
	             wxT("	SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname ")
	             wxT("	FROM pg_operator op ")
	             wxT("	left join pg_namespace ns on op.oprnamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname ")
	             wxT("	FROM pg_opclass op ")
	             wxT("	left join pg_namespace ns on op.opcnamespace = ns.oid ")
	             wxT("	union ")
	             wxT("	SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname ")
	             wxT("	FROM pg_opfamily opf ")
	             wxT("	left join pg_namespace ns on opf.opfnamespace = ns.oid ");


	if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser())
	{
		searchSQL += wxT("	union ")
		             wxT("	select 'Foreign Data Wrappers', fdwname, ':Foreign Data Wrappers/' || fdwname from pg_foreign_data_wrapper ")
		             wxT("	union ")
		             wxT("	select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname from pg_foreign_server sr ")
		             wxT("	inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ")
		             wxT("	union ")
		             wxT("	select 'User Mappings', ro.rolname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname || '/:User Mappings/' || ro.rolname from pg_user_mapping um ")
		             wxT("	inner join pg_roles ro on um.umuser = ro.oid ")
		             wxT("	inner join pg_foreign_server sr on um.umserver = sr.oid ")
		             wxT("	inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ");
	}

	if(currentdb->BackendMinimumVersion(9, 1))
	{
		searchSQL += wxT("	union ")
		             wxT("	select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname from pg_foreign_table ft ")
		             wxT("	inner join pg_class c on ft.ftrelid = c.oid ")
		             wxT("	inner join pg_namespace ns on c.relnamespace = ns.oid ")
		             wxT("	union ")
		             wxT("	select 'Extensions', x.extname, ':Extensions/' || x.extname ")
		             wxT("	FROM pg_extension x	")
		             wxT("	JOIN pg_namespace n on x.extnamespace=n.oid ")
		             wxT("	join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name ")
		             wxT("	union ")
		             wxT("	SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname ")
		             wxT("	FROM pg_collation c ")
		             wxT("	JOIN pg_namespace n ON n.oid=c.collnamespace ");
	}

	searchSQL += wxT(") i ")
	             wxT("where lower(i.objectname) like '%") + txtPattern->GetValue().Lower() + wxT("%' ");
	if(cbType->GetValue() != _("All types"))
	{
		searchSQL += wxT("AND i.type = '") + aMap[cbType->GetValue()] + wxT("' ");
	}
	searchSQL += wxT("ORDER BY 1, 2");

	pgSet *set = currentdb->GetConnection()->ExecuteSet(searchSQL);
	int i = 0;
	if(set)
	{
		lcResults->DeleteAllItems();

		while(!set->Eof())
		{
			wxString objectType = set->GetVal(wxT("type"));
			wxString objectName = set->GetVal(wxT("objectname"));
			wxString ItemPath;


			/* Login Roles, Group Roles and Tablespaces are "outside" the database, so we have to adjust the path */
			if(objectType == wxT("Login Roles") || objectType == wxT("Group Roles") || objectType == wxT("Tablespaces"))
			{
				wxStringTokenizer tkz(databasePath, wxT("/"));
				wxString newPath;
				while(tkz.HasMoreTokens())
				{
					wxString token = tkz.GetNextToken();
					if(token == _("Databases"))
						break;
					ItemPath += token + wxT("/");
				}
				ItemPath += set->GetVal(wxT("path"));
			}
			else
			{
				ItemPath = databasePath + wxT("/") + set->GetVal(wxT("path"));
			}

			if(ItemPath.Contains(wxT("Schemas/information_schema")))
			{
				/* In information Schema only views and columns are displayed, nothing else */
				if(objectType == wxT("Views") || objectType == wxT("Columns"))
				{
					ItemPath.Replace(wxT(":Schemas/information_schema"), wxT(":Catalogs/ANSI/:Catalog Objects"));
					ItemPath.Replace(wxT(":Views/"), wxT(""));
				}
				else
				{
					set->MoveNext();
					continue;
				}
			}

			if(ItemPath.Contains(wxT("Schemas/pg_catalog")))
			{
				ItemPath.Replace(wxT(":Schemas/pg_catalog"), wxT(":Catalogs/PostgreSQL"));
			}

			wxListItem item;
			item.SetId(i);
			lcResults->InsertItem(item);

			wxString locTypeStr = wxGetTranslation(set->GetVal(wxT("type")));

			/* Check if viewing of the specified object is enabled in settings */
			if(!settings->GetDisplayOption(locTypeStr))
			{
				lcResults->SetItemTextColour(i, wxColour(128, 128, 128));
			}

			lcResults->SetItem(i, 0, locTypeStr);
			lcResults->SetItem(i, 1, objectName);
			lcResults->SetItem(i, 2, TranslatePath(ItemPath));
			set->MoveNext();
			i++;
		}
		delete set;
	}

	if(lcResults->GetItemCount() > 0)
	{
		lcResults->SetColumnWidth(0, wxLIST_AUTOSIZE);
		lcResults->SetColumnWidth(1, wxLIST_AUTOSIZE);
		lcResults->SetColumnWidth(2, wxLIST_AUTOSIZE);
	}
}
Пример #25
0
std::string CSpecialProtocol::TranslatePath(const CURL &url)
{
  // check for special-protocol, if not, return
  if (!url.IsProtocol("special"))
  {
#if defined(TARGET_POSIX) && defined(_DEBUG)
    std::string path(url.Get());
    if (path.length() >= 2 && path[1] == ':')
    {
      CLog::Log(LOGWARNING, "Trying to access old style dir: %s\n", path.c_str());
     // printf("Trying to access old style dir: %s\n", path.c_str());
    }
#endif

    return url.Get();
  }

  std::string FullFileName = url.GetFileName();

  std::string translatedPath;
  std::string FileName;
  std::string RootDir;

  // Split up into the special://root and the rest of the filename
  size_t pos = FullFileName.find('/');
  if (pos != std::string::npos && pos > 1)
  {
    RootDir = FullFileName.substr(0, pos);

    if (pos < FullFileName.size())
      FileName = FullFileName.substr(pos + 1);
  }
  else
    RootDir = FullFileName;

  if (RootDir == "subtitles")
    translatedPath = URIUtils::AddFileToFolder(CSettings::GetInstance().GetString(CSettings::SETTING_SUBTITLES_CUSTOMPATH), FileName);
  else if (RootDir == "userdata")
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::GetInstance().GetUserDataFolder(), FileName);
  else if (RootDir == "database")
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::GetInstance().GetDatabaseFolder(), FileName);
  else if (RootDir == "thumbnails")
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::GetInstance().GetThumbnailsFolder(), FileName);
  else if (RootDir == "recordings" || RootDir == "cdrips")
    translatedPath = URIUtils::AddFileToFolder(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOCDS_RECORDINGPATH), FileName);
  else if (RootDir == "screenshots")
    translatedPath = URIUtils::AddFileToFolder(CSettings::GetInstance().GetString(CSettings::SETTING_DEBUG_SCREENSHOTPATH), FileName);
  else if (RootDir == "musicplaylists")
    translatedPath = URIUtils::AddFileToFolder(CUtil::MusicPlaylistsLocation(), FileName);
  else if (RootDir == "videoplaylists")
    translatedPath = URIUtils::AddFileToFolder(CUtil::VideoPlaylistsLocation(), FileName);
  else if (RootDir == "skin")
    translatedPath = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), FileName);
  else if (RootDir == "logpath")
    translatedPath = URIUtils::AddFileToFolder(g_advancedSettings.m_logFolder, FileName);


  // from here on, we have our "real" special paths
  else
  {
    auto rootName = m_pathMap.find(RootDir);
    if (rootName != m_pathMap.end())
    {
      std::string basePath = GetPath(RootDir);
      if (!basePath.empty())
        translatedPath = URIUtils::AddFileToFolder(basePath, FileName);
      else
        translatedPath.clear();
    }
  }

  // check if we need to recurse in
  if (URIUtils::IsSpecial(translatedPath))
  { // we need to recurse in, as there may be multiple translations required
    return TranslatePath(translatedPath);
  }

  // Validate the final path, just in case
  return CUtil::ValidatePath(translatedPath);
}