27 error_reporting(E_ALL);
28 if (ini_get(
'memory_limit') !=
'-1') ini_set(
'memory_limit',
'-1');
29 if ((php_sapi_name() !=
'cli')) {
30 trigger_error(
"You can only run this script from the command line\n", E_USER_ERROR);
35 define(
'LOG_FILE_NAME',
'set_permissions.log');
37 if (count($argv) < 4) {
43 process_args($config);
45 require_once $config[
'system_root'].
'/core/include/init.inc';
46 require_once SQ_INCLUDE_PATH.
'/assertions.inc';
48 define(
'LOG_FILE', SQ_SYSTEM_ROOT.
'/data/private/logs/'.LOG_FILE_NAME);
49 define(
'SYNCH_FILE', SQ_TEMP_PATH.
'/set_permissions.assetid');
52 check_permissions_args($config[
'permissions']);
55 $assetids = preg_replace(
'/[\s]*/',
'', $config[
'assetids']);
58 $rootnodes = getRootNodes($assetids);
60 _disconnectFromMatrixDatabase();
61 $pid_prepare = pcntl_fork();
62 switch ($pid_prepare) {
67 _connectToMatrixDatabase();
69 $root_user = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'root_user');
77 if (!$GLOBALS[
'SQ_SYSTEM']->setCurrentUser($root_user)) {
78 echo
"Failed logging in as root user\n";
82 $children = $rootnodes;
83 foreach ($rootnodes as $rootnode_id) {
84 $children += array_merge($children, array_keys(($GLOBALS[
'SQ_SYSTEM']->am->getChildren($rootnode_id))));
89 file_put_contents(SYNCH_FILE, implode(
',', $children));
92 _disconnectFromMatrixDatabase();
97 pcntl_waitpid(-1, $status);
102 pcntl_waitpid(-1, $status);
107 if (file_exists(SYNCH_FILE)) {
108 $children_str = file_get_contents(SYNCH_FILE);
110 echo
"Unable to find Synch File, probably because the root user was not able to log in, or the user executing this script does not have permission to write to this folder.\n";
114 $children = explode(
',', $children_str);
115 $children = array_unique($children);
118 $chunk_children = array_chunk($children, $config[
'batch_size']);
119 $current_child_list = Array();
121 log_to_file(
'======================= Start applying permissions '.date(
'd-m-Y h:i:s').
' =======================', LOG_FILE);
122 log_to_file(
"Applying permissions for: " . var_export(count($children),TRUE) .
" assets \n", LOG_FILE);
125 while (!empty($chunk_children)) {
126 $current_child_list = array_pop($chunk_children);
127 $current_remaining = count($current_child_list);
132 trigger_error(
'Process failed to fork', E_USER_ERROR);
137 _connectToMatrixDatabase();
138 $GLOBALS[
'SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
142 foreach ($current_child_list as $child_assetid) {
143 $child_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($child_assetid);
144 if (!$GLOBALS[
'SQ_SYSTEM']->am->acquireLock($child_assetid,
'permissions')) {
145 log_to_file(
'Unable to acquire permissions lock for assetid ' .$child_assetid.
'. Skipping this asset.', LOG_FILE);
149 if (!$child_asset->writeAccess(
'permissions')) {
150 log_to_file(
'Do not have write access for assetid ' .$child_assetid .
'. Skipping this asset.', LOG_FILE);
151 $GLOBALS[
'SQ_SYSTEM']->am->releaseLock($child_assetid,
'permissions');
152 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($child_asset);
157 foreach ($config[
'permissions'] as $p) {
158 if ($p[
'granted'] ==
'/') {
159 if (!$GLOBALS[
'SQ_SYSTEM']->am->deletePermission($child_assetid, $p[
'userid'], $p[
'type'])) {
160 log_to_file(
'Failed deleting permission for assetid ' . $child_assetid .
'.', LOG_FILE);
164 $permission_granted = (($p[
'granted'] ==
'+') ? TRUE : FALSE);
165 if (!$GLOBALS[
'SQ_SYSTEM']->am->setPermission($child_assetid, $p[
'userid'], $p[
'type'], $permission_granted, $config[
'cascades'], $config[
'force'])) {
166 log_to_file(
'Failed setting permission for assetid ' . $child_assetid .
'.', LOG_FILE);
172 log_to_file(
'Applied permissions for child assetid '.$child_assetid, LOG_FILE);
174 $current_remaining--;
175 echo
'-- Remaining: ' . (string) ($current_remaining + (count($chunk_children) * $config[
'batch_size'])) .
"\n";
177 $GLOBALS[
'SQ_SYSTEM']->am->releaseLock($child_assetid,
'permissions');
178 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($child_asset);
184 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
186 _disconnectFromMatrixDatabase();
191 pcntl_waitpid(-1, $status);
196 if ($fork_num >= $config[
'max_threads']) {
198 pcntl_waitpid(-1, $status);
202 if (empty($chunk_children)) {
204 while ($fork_num > 0) {
206 pcntl_waitpid(-1, $status);
218 log_to_file(
'======================= Finished Applying Permissions '.date(
'd-m-Y h:i:s').
' =======================', LOG_FILE);
219 if (file_exists(SYNCH_FILE)) {
234 echo
"Usage: php {$_SERVER['argv'][0]} <system_root> <assetid[,assetid]> \"<permission_strings>\"\n";
235 echo
" php {$_SERVER['argv'][0]} <system_root> <assetid[,assetid]> \"<permission_strings>\" [-nc] [-f]\n";
236 echo
" php {$_SERVER['argv'][0]} <system_root> <assetid[,assetid]> \"<permission_strings>\" [--max-threads <max_threads>] [--batch-size <batch_size>]\n";
238 echo
" <permission_strings> A string representing the permissions to change.\n";
239 echo
" example: 'r+101;w-102;a/103' => add read permission to User #101,\n";
240 echo
" deny write permission to user #102 and remove admin permission for user #103.\n";
241 echo
" -nc No cascade. Don't set the cascade flag, which allows new child assets to inherit the permissions.\n";
242 echo
" -f Force permissions, even if the permissions are already applied or granted/denied are in conflict.\n";
243 echo
" --max-threads Maximum concurrency. Default is 3, max allowed is 5.\n";
244 echo
" --batch-size Default is 50.\n";
246 echo
"Results are logged to data/private/logs/".LOG_FILE_NAME.
"\n";
257 function process_args(&$config) {
259 $config[
'system_root'] = (isset($_SERVER[
'argv'][1])) ? $_SERVER[
'argv'][1] :
'';
260 if (empty($config[
'system_root'])) {
261 echo
"ERROR: You need to supply the path to the System Root as the first argument\n";
265 if (!is_dir($config[
'system_root']) || !is_readable($config[
'system_root'].
'/core/include/init.inc')) {
266 echo
"ERROR: Path provided doesn't point to a Matrix installation's System Root. Please provide correct path and try again.\n";
270 $config[
'assetids'] = (isset($_SERVER[
'argv'][2])) ? $_SERVER[
'argv'][2] :
'';
271 if (empty($config[
'assetids'])) {
272 echo
"ERROR: You need to specify the root nodes to apply the schema from as the second argument\n";
276 $config[
'permissions_string'] = (isset($_SERVER[
'argv'][3])) ? $_SERVER[
'argv'][3] :
'';
277 if (empty($config[
'permissions_string'])) {
278 echo
"ERROR: You need to specify a permissions string as the third argument\n";
283 $config[
'permissions'] = array();
284 $config[
'permission_types'] = Array(
'r' => 1,
'w' => 2,
'a' => 3);
286 $perms = split(
';', $config[
'permissions_string'].
';');
287 foreach ($perms as $p) {
289 array_push($config[
'permissions'], Array(
290 'type' => (
int) $config[
'permission_types'][$p{0}],
292 'userid' => substr($p, 2),
297 $config[
'cascades'] = !get_boolean_arg(
'-nc');
298 $config[
'force'] = get_boolean_arg(
'-f');
300 $config[
'max_threads'] = (int) get_parameterised_arg(
'--max-threads', 3);
301 if ($config[
'max_threads'] > 5) {
302 $config[
'max_threads'] = 5;
303 } elseif ($config[
'max_threads'] < 1) {
304 $config[
'max_threads'] = 1;
307 $config[
'batch_size'] = (int) get_parameterised_arg(
'--batch-size', 50);
308 if ($config[
'batch_size'] < 5) {
309 $config[
'batch_size'] = 50;
313 echo
"Will attempt to set permissions to asset(s) {$config['assetids']}.\n\n";
314 echo
" Max threads: {$config['max_threads']}\n";
315 echo
" Batch size: {$config['batch_size']}\n";
321 function check_permissions_args($permissions) {
322 foreach ($permissions as $p) {
323 if (($p[
'type'] > 3) || ($p[
'type'] < 1)) {
324 trigger_error(
"Invalid permission type in permissions string.\n", E_USER_ERROR);
327 if (($p[
'granted'] !=
'+') && ($p[
'granted'] !=
'-') && ($p[
'granted'] !=
'/')) {
328 trigger_error(
"Invalid granted flag in permissions string.\n", E_USER_ERROR);
331 if (!assert_valid_assetid($p[
'userid'])) {
332 trigger_error(
"Invalid userid in permissions string.\n", E_USER_ERROR);
343 function get_boolean_arg($arg) {
344 $key = array_search($arg, $_SERVER[
'argv']);
361 function get_parameterised_arg($arg, $default) {
362 $key = array_search($arg, $_SERVER[
'argv']);
364 if (($key) && (isset($_SERVER[
'argv'][$key + 1]))) {
365 return $_SERVER[
'argv'][$key + 1];
381 function get_line($prompt=
'')
385 return rtrim(fgets(STDIN, 4096));
396 function _disconnectFromMatrixDatabase()
399 if (isset($conn_id) && !empty($conn_id)) {
413 function _connectToMatrixDatabase()
415 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
424 function log_to_file($content, $file_name=
"set_metadata_schema.log")
426 file_put_contents($file_name,
'['.date(
'd-m-Y h:i:s').
'] '.$content.
"\n", FILE_APPEND);
431 function getRootNodes($action)
433 $rootnodes = explode(
',', $action);
436 $rootnodes_exists = $GLOBALS[
'SQ_SYSTEM']->am->assetExists($rootnodes);
438 $not_exists = array_diff($rootnodes, $rootnodes_exists);
439 if (!empty($not_exists)) {
440 $list_not_exists = implode(
', ', $not_exists);
441 echo
"These rootnode ids do not exists in the system: $list_not_exists \n";