We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 8907
    • 11 Posts
    Here you are.
    Thank you for your quickly response.

    2009-10-24 18:00 JST
    Currently, I found that things.

    • Result of $modx->context->findPolicy() looks correct.
    • $modx->user->getAttributes() returns array of "a:3:{s:16:"modAccessContext";a:0:{}s:22:"modAccessResourceGroup";a:0:{}s:16:"modAccessElement";a:0:{}}(this is serialized)".
    • $modx->user->get(’id’) returns 1.
    I tracked these at modmanagerresponse.class.php line 112, where output "Permission denied" message.

    2009-10-25 00:30 JST
    I inspected modUser::loadAttribute, and found it seems to fail in the execution of the query.
    I still trying to find how to execute these queries...

    P.S. I tryed to attach dump text here, but rejected with next message: "The attachments upload directory is not writable. Your attachment or avatar cannot be saved. ". huh

    --
    -- Dumping data for table `modx_users`
    --

    INSERT INTO `modx_users` VALUES (1,’administrator’,’2b0269bada6e611fbc6b327eb282884a’,’’,’modUser’,1);

    --
    -- Dumping data for table `modx_access_context`
    --

    INSERT INTO `modx_access_context` VALUES (1,’mgr’,’modUserGroup’,1,0,2),(2,’web’,’modUserGroup’,1,0,2);

    --
    -- Dumping data for table `modx_access_policies`
    --

    INSERT INTO `modx_access_policies` VALUES (1,’Resource’,’MODx Resource policy with all attributes.’,0,’’,’{\"add_children\":true,\"create\":true,\"delete\":true,\"list\":true,\"load\":true,\"move\":true,\"publish\":true,\"remove\":true,\"save\":true,\"steal_lock\":true,\"unpublish\":true,\"view\":true}’),(2,’Administrator’,’Context administration policy with all permissions.’,0,’’,’{\"about\":true,\"access_permissions\":true,\"action_ok\":true,\"actions\":true,\"change_password\":true,\"change_profile\":true,\"content_types\":true,\"create\":true,\"credits\":true,\"database\":true,\"database_truncate\":true,\"delete_category\":true,\"delete_chunk\":true,\"delete_context\":true,\"delete_document\":true,\"delete_eventlog\":true,\"delete_plugin\":true,\"delete_snippet\":true,\"delete_template\":true,\"delete_tv\":true,\"delete_role\":true,\"delete_user\":true,\"edit_category\":true,\"edit_chunk\":true,\"edit_context\":true,\"edit_doc_metatags\":true,\"edit_document\":true,\"edit_locked\":true,\"edit_parser\":true,\"edit_plugin\":true,\"edit_role\":true,\"edit_snippet\":true,\"edit_template\":true,\"edit_tv\":true,\"edit_user\":true,\"empty_cache\":true,\"error_dialog\":true,\"export_static\":true,\"file_manager\":true,\"flush_sessions\":true,\"frames\":true,\"help\":true,\"home\":true,\"import_static\":true,\"languages\":true,\"lexicons\":true,\"list\":true,\"load\":true,\"logout\":true,\"logs\":true,\"manage_metatags\":true,\"menus\":true,\"messages\":true,\"namespaces\":true,\"new_category\":true,\"new_chunk\":true,\"new_context\":true,\"new_document\":true,\"new_plugin\":true,\"new_role\":true,\"new_snippet\":true,\"new_template\":true,\"new_tv\":true,\"new_user\":true,\"package_builder\":true,\"packages\":true,\"providers\":true,\"publish_document\":true,\"purge_deleted\":true,\"remove\":true,\"remove_locks\":true,\"save\":true,\"save_category\":true,\"save_chunk\":true,\"save_document\":true,\"save_parser\":true,\"save_password\":true,\"save_plugin\":true,\"save_role\":true,\"save_snippet\":true,\"save_template\":true,\"save_tv\":true,\"save_user\":true,\"search\":true,\"settings\":true,\"steal_locks\":true,\"unlock_element_properties\":true,\"view\":true,\"view_category\":true,\"view_chunk\":true,\"view_context\":true,\"view_document\":true,\"view_eventlog\":true,\"view_offline\":true,\"view_plugin\":true,\"view_snippet\":true,\"view_template\":true,\"view_tv\":true,\"view_unpublished\":true,\"workspaces\":true}’);

    --
    -- Dumping data for table `modx_membergroup_names`
    --

    INSERT INTO `modx_membergroup_names` VALUES (1,’Administrator’,0);

    --
    -- Dumping data for table `modx_member_groups`
    --

    INSERT INTO `modx_member_groups` VALUES (1,1,1,2);

    --
    -- Dumping data for table `modx_user_group_roles`
    --

    INSERT INTO `modx_user_group_roles` VALUES (1,’Member’,NULL,9999),(2,’Super User’,NULL,0);

      • 8907
      • 11 Posts
      I have succeeded to access the manager. grin
      I rewrite queries in modUser::loadAttributes like this.

                              $sql = <<<QUERY
      SELECT entry.target, entry.principal, mr.authority, entry.policy, entry.data
      FROM
      (SELECT mug.role, acl.authority, acl.target, acl.principal, acl.policy, p.data FROM {$accessTable} acl 
        LEFT JOIN {$policyTable} p ON p.id = acl.policy
        JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup'
          AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '')
          AND mug.member = :principal
          AND mug.user_group = acl.principal
      ) entry
      JOIN {$memberRoleTable} mr ON mr.id = entry.role
        AND mr.authority <= entry.authority 
      GROUP BY entry.target, entry.principal, entry.authority, entry.policy
      


      Thanks.
        • 22303 MODX Staff
        • 10,725 Posts
        enogu, I’m confused by what you changed here. Can you show the changes specifically? This sounds to me like you just add invalid session data stored in the db and if you were using beta3, this has changed significantly since then.
          • 8907
          • 11 Posts
          Sorry, my explanation was insufficient.
          First, I’m using beta-4(rev. 5880), and original query is here.

                                  $sql = "SELECT acl.target, acl.principal, mr.authority, acl.policy, p.data FROM {$accessTable} acl " .
                                          "LEFT JOIN {$policyTable} p ON p.id = acl.policy " .
                                          "JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup' " .
                                          "AND mug.member = :principal " .
                                          "AND mug.user_group = acl.principal " .
                                          "JOIN {$memberRoleTable} mr ON mr.id = mug.role " .
                                          "AND mr.authority <= acl.authority " .
                                          "GROUP BY acl.target, acl.principal, acl.authority, acl.policy";
          


          Yesterday, I tried to execute this query directly(using mysql client). But, client has disconnected from daemon, regardless of replacing table-names and the parameter. If this returned empty set, then I suspected the data too. But, this is even no executable.

          I found that the trouble caused to join $memberRoleTable and later clauses(without GROUP BY). I thought that the query has caused trouble similar to cyclic reference. In fact, when I rewrote the query using sub-query and simplified relations of $memberRoleTable, query was executed and returned.

          Key of this change is here. As a result, the table that joins to $memberRoleTable is made only "entry".

          (SELECT mug.role, acl.authority, acl.target, acl.principal, acl.policy, p.data FROM {$accessTable} acl 
            LEFT JOIN {$policyTable} p ON p.id = acl.policy
            JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup'
              AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '')
              AND mug.member = :principal
              AND mug.user_group = acl.principal
          ) entry
          


          I show you fully code of modUser::loadAttributes here.
              /**
               * Loads the principal attributes that define a modUser security profile.
               *
               * {@inheritdoc}
               *
               * @todo Remove the legacy docgroup support.
               */
              function loadAttributes($target, $context = '', $reload = false) {
                  $context = !empty($context) ? $context : $this->xpdo->context->get('key');
                  if ($this->_attributes === null || $reload) {
                      $this->_attributes = array();
                      if (isset($_SESSION["modx.user.{$this->id}.attributes"])) {
                          if ($reload) {
                              unset($_SESSION["modx.user.{$this->id}.attributes"]);
                          } else {
                              $this->_attributes = $_SESSION["modx.user.{$this->id}.attributes"];
                          }
                      }
                  }
                  if (!isset($this->_attributes[$context])) $this->_attributes[$context] = array();
                  if (!isset($this->_attributes[$context][$target])) {
                      $accessTable = $this->xpdo->getTableName($target);
                      $policyTable = $this->xpdo->getTableName('modAccessPolicy');
                      $memberTable = $this->xpdo->getTableName('modUserGroupMember');
                      $memberRoleTable = $this->xpdo->getTableName('modUserGroupRole');
                      if ($this->get('id') > 0) {
                          switch ($target) {
                              case 'modAccessResourceGroup' :
                                  $legacyDocGroups = array();
          #Here was modified.
                                  $sql = <<<QUERY
          SELECT entry.target, entry.principal, mr.authority, entry.policy, entry.data
          FROM
          (SELECT mug.role, acl.authority, acl.target, acl.principal, acl.policy, p.data FROM {$accessTable} acl 
            LEFT JOIN {$policyTable} p ON p.id = acl.policy
            JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup'
              AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '')
              AND mug.member = :principal
              AND mug.user_group = acl.principal
          ) entry
          JOIN {$memberRoleTable} mr ON mr.id = entry.role
            AND mr.authority <= entry.authority 
          GROUP BY entry.target, entry.principal, entry.authority, entry.policy
          QUERY;
                                  $bindings = array(
                                      ':principal' => $this->get('id'),
                                      ':context' => $context
                                  );
                                  $query = new xPDOCriteria($this->xpdo, $sql, $bindings);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => $row['principal'],
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                          $legacyDocGroups[$row['target']]= $row['target'];
                                      }
                                  }
                                  $_SESSION[$context . 'Docgroups']= array_values($legacyDocGroups);
                                  break;
                              case 'modAccessContext' :
          #Here was modified.
                                  $sql = <<<QUERY
          SELECT entry.target, entry.principal, mr.authority, entry.policy, entry.data
          FROM
          (SELECT mug.role, acl.authority, acl.target, acl.principal, acl.policy, p.data FROM {$accessTable} acl 
            LEFT JOIN {$policyTable} p ON p.id = acl.policy
            JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup'
              AND mug.member = :principal
              AND mug.user_group = acl.principal
          ) entry
          JOIN {$memberRoleTable} mr ON mr.id = entry.role
          AND mr.authority <= entry.authority
          GROUP BY entry.target, entry.principal, entry.authority, entry.policy
          QUERY;
                                  $bindings = array(
                                      ':principal' => $this->get('id')
                                  );
                                  $query = new xPDOCriteria($this->xpdo, $sql, $bindings);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => $row['principal'],
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                      }
                                  }
                                  break;
                              case 'modAccessElement' :
          #Here was modified.
                                  $sql = <<<QUERY
          SELECT entry.target, entry.principal, mr.authority, entry.policy, entry.data
          FROM
          (SELECT mug.role, acl.authority, acl.target, acl.principal, acl.policy, p.data FROM {$accessTable} acl 
           LEFT JOIN {$policyTable} p ON p.id = acl.policy
           JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup'
             AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '')
             AND mug.member = :principal
             AND mug.user_group = acl.principal
          ) entry
          JOIN {$memberRoleTable} mr ON mr.id = entry.role
          AND mr.authority <= entry.authority
          GROUP BY entry.target, entry.principal, entry.authority, entry.policy
          QUERY;
                                  $bindings = array(
                                      ':principal' => $this->get('id'),
                                      ':context' => $context
                                  );
                                  $query = new xPDOCriteria($this->xpdo, $sql, $bindings);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => $row['principal'],
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                      }
                                  }
                                  break;
                              default :
                                  break;
                          }
                      } else {
                          switch ($target) {
                              case 'modAccessResourceGroup' :
                                  $legacyDocGroups = array();
          #I did not touch here.
                                  $sql = "SELECT acl.target, acl.principal, 0 AS authority, acl.policy, p.data FROM {$accessTable} acl " .
                                          "LEFT JOIN {$policyTable} p ON p.id = acl.policy " .
                                          "WHERE acl.principal_class = 'modUserGroup' " .
                                          "AND acl.principal = 0 " .
                                          "AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '') " .
                                          "GROUP BY acl.target, acl.principal, acl.authority, acl.policy";
                                  $bindings = array(
                                      ':context' => $context
                                  );
                                  $query = new xPDOCriteria($this->xpdo, $sql, $bindings);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => 0,
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                          $legacyDocGroups[$row['target']]= $row['target'];
                                      }
                                  }
                                  $_SESSION[$context . 'Docgroups']= array_values($legacyDocGroups);
                                  break;
                              case 'modAccessContext' :
          #I did not touch here.
                                  $sql = "SELECT acl.target, acl.principal, 0 AS authority, acl.policy, p.data FROM {$accessTable} acl " .
                                          "LEFT JOIN {$policyTable} p ON p.id = acl.policy " .
                                          "WHERE acl.principal_class = 'modUserGroup' " .
                                          "AND acl.principal = 0 " .
                                          "GROUP BY acl.target, acl.principal, acl.authority, acl.policy";
                                  $query = new xPDOCriteria($this->xpdo, $sql);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => 0,
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                      }
                                  }
                                  break;
                              case 'modAccessElement' :
          #I did not touch here.
                                  $sql = "SELECT acl.target, acl.principal, 0 AS authority, acl.policy, p.data FROM {$accessTable} acl " .
                                          "LEFT JOIN {$policyTable} p ON p.id = acl.policy " .
                                          "WHERE acl.principal_class = 'modUserGroup' " .
                                          "AND acl.principal = 0 " .
                                          "AND (acl.context_key = :context OR acl.context_key IS NULL OR acl.context_key = '') " .
                                          "GROUP BY acl.target, acl.principal, acl.authority, acl.policy";
                                  $bindings = array(
                                      ':context' => $context
                                  );
                                  $query = new xPDOCriteria($this->xpdo, $sql, $bindings);
                                  if ($query->stmt && $query->stmt->execute()) {
                                      while ($row = $query->stmt->fetch(PDO_FETCH_ASSOC)) {
                                          $this->_attributes[$context][$target][$row['target']][] = array(
                                              'principal' => 0,
                                              'authority' => $row['authority'],
                                              'policy' => $row['data'] ? xPDO :: fromJSON($row['data'], true) : array(),
                                          );
                                      }
                                  }
                                  break;
                              default :
                                  break;
                          }
                      }
                      if (!isset($this->_attributes[$context][$target])) {
                          $this->_attributes[$context][$target] = array();
                      }
                      $_SESSION["modx.user.{$this->id}.attributes"] = $this->_attributes;
                  }
              }
          
            • 22303 MODX Staff
            • 10,725 Posts
            enogu, I still don’t understand what the problem is; the original query works fine for me and many others. What version of MySQL are you using?
              • 8907
              • 11 Posts
              I am this feeling. I also know this has no problem in other platforms.
              I think that that is better if it is a problem of solving it by setting of daemons.

              I am using MySQL 5.1.30. But, its configuration has many difference from normal. These are default settings in MySQL-package for OpenSolaris.
              I tried to change table_cache to 64, but no implovement.

              Here is my mysql.cnf.

              # Example MySQL config file for small systems.
              #
              # This is for a system with little memory (<= 64M) where MySQL is only used
              # from time to time and it's important that the mysqld daemon
              # doesn't use much resources.
              #
              # You can copy this file to
              # /etc/my.cnf to set global options,
              # mysql-data-dir/my.cnf to set server-specific options (in this
              # installation this directory is /var/mysql/5.1/data) or
              # ~/.my.cnf to set user-specific options.
              #
              # In this file, you can use all long options that a program supports.
              # If you want to know which options a program supports, run the program
              # with the "--help" option.
              
              # The following options will be passed to all MySQL clients
              [client]
              #password	= your_password
              port		= 3306
              socket		= /tmp/mysql.sock
              default-character-set = ujis
              
              # Here follows entries for some specific programs
              
              # The MySQL server
              [mysqld]
              port		= 3306
              socket		= /tmp/mysql.sock
              skip-locking
              key_buffer = 16K
              max_allowed_packet = 1M
              table_cache = 4
              sort_buffer_size = 64K
              read_buffer_size = 256K
              read_rnd_buffer_size = 256K
              net_buffer_length = 2K
              thread_stack = 64K
              default-character-set = ujis
              
              # Don't listen on a TCP/IP port at all. This can be a security enhancement,
              # if all processes that need to connect to mysqld run on the same host.
              # All interaction with mysqld must be made via Unix sockets or named pipes.
              # Note that using this option without enabling named pipes on Windows
              # (using the "enable-named-pipe" option) will render mysqld useless!
              # 
              #skip-networking
              server-id	= 1
              
              # Uncomment the following if you want to log updates
              #log-bin=mysql-bin
              
              # binary logging format - mixed recommended
              #binlog_format=mixed
              
              # Uncomment the following if you are using InnoDB tables
              #innodb_data_home_dir = /var/mysql/5.1/data/
              #innodb_data_file_path = ibdata1:10M:autoextend
              #innodb_log_group_home_dir = /var/mysql/5.1/data/
              #innodb_log_arch_dir = /var/mysql/5.1/data/
              # You can set .._buffer_pool_size up to 50 - 80 %
              # of RAM but beware of setting memory usage too high
              #innodb_buffer_pool_size = 16M
              #innodb_additional_mem_pool_size = 2M
              # Set .._log_file_size to 25 % of buffer pool size
              #innodb_log_file_size = 5M
              #innodb_log_buffer_size = 8M
              #innodb_flush_log_at_trx_commit = 1
              #innodb_lock_wait_timeout = 50
              
              [mysqldump]
              quick
              max_allowed_packet = 16M
              default-character-set = ujis
              
              [mysql]
              no-auto-rehash
              # Remove the next comment character if you are not familiar with SQL
              #safe-updates
              
              [isamchk]
              key_buffer = 8M
              sort_buffer_size = 8M
              
              [myisamchk]
              key_buffer = 8M
              sort_buffer_size = 8M
              
              [mysqlhotcopy]
              interactive-timeout
              
                • 22303 MODX Staff
                • 10,725 Posts
                My initial bet is that using this config is the problem; it is meant for a very small and minimal machine where MySQL is used very sparingly and MySQL is not used sparingly in MODx Revolution.
                  • 8907
                  • 11 Posts
                  I reverted moduser.class.php and tried on a few another preinstalled configuration. I finally rewrote my.cnf to the following content. But, these trial did not succeed.

                  By the way, My PC was equiped Intel Atom 330 & Intel 945G & 2GB DDR2 (M/B is D945GCLF2). Do you think that the fact is related to something?

                  [client]
                  port=3306
                  socket=/tmp/mysql.sock
                  
                  [mysqld]
                  port=3306
                  socket=/tmp/mysql.sock
                  set-variable = key_buffer_size=16M
                  set-variable = max_allowed_packet=1M
                  
                  [mysqldump]
                  quick
                  
                    • 22303 MODX Staff
                    • 10,725 Posts
                    Do you have the proper mysql client API for the MySQL server version you are using on that machine? Something is not right and it seems to me it’s most likely in the mysql client libraries.
                      • 8907
                      • 11 Posts
                      Currently, I have a doubt that libc might be a cause. Standard MySQL package at OpenSolaris is built by SUNWlibc. I expect that your (and many other’s) MySQL is built by glibc.

                      I can’t be convinced of this possibility. So, I will be going to test on the new installation of MySQL with glibc.
                      I will report details additionally, whether can I find something or not.

                      2009-11-18

                      I will try to older MySQL(5.0 or former) on official repository of OpenSolaris.