795 lines
26 KiB
PHP
795 lines
26 KiB
PHP
<?php
|
|
|
|
/** DomFramework
|
|
* @package domframework
|
|
* @author Dominique Fournier <dominique@fournier38.fr>
|
|
* @license BSD
|
|
*/
|
|
|
|
namespace Domframework;
|
|
|
|
/** All the needed functions to authorize or deny access to an authenticated
|
|
user */
|
|
class Authorizationdb extends Authorization
|
|
{
|
|
/** Separator between differents modules/objects */
|
|
private $separator = "/";
|
|
/** Database PDO connector */
|
|
private $db = null;
|
|
/** The prefix for the table */
|
|
public $tableprefix = "";
|
|
|
|
/** Establish a connexion to the authorization database
|
|
@param string $dsn The DSN needed to connect to database
|
|
@param string|null $username The username needed to connect to database
|
|
@param string|null $password The password needed to connect to database
|
|
@param string|null $driver_options The driver options need to connect to
|
|
database */
|
|
public function connectdb(
|
|
$dsn,
|
|
$username = null,
|
|
$password = null,
|
|
$driver_options = null
|
|
) {
|
|
// Define the structure of the table in the database
|
|
$this->db = new Dblayer($dsn, $username, $password, $driver_options);
|
|
$this->db->table = "domframework_authorization";
|
|
$this->db->tableprefix = $this->tableprefix;
|
|
$this->db->fields = array(
|
|
"object" => array("varchar", "255", "not null"),
|
|
"ownerid" => array("integer", "not null"),
|
|
"groupid" => array("integer", "not null"),
|
|
"modbits" => array("integer", "not null"));
|
|
$this->db->primary = "object";
|
|
$this->db->unique = array("object");
|
|
}
|
|
|
|
/** Create the structure to store the authorization database */
|
|
public function initialize()
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
$tables = $this->db->listTables();
|
|
if (!in_array($this->db->tableprefix . $this->db->table, $tables)) {
|
|
$this->db->createTable();
|
|
$first = array("object" => "/", "ownerid" => 0, "groupid" => 0,
|
|
"modbits" => 755);
|
|
$this->db->create($first);
|
|
}
|
|
}
|
|
|
|
/** Return if the user right is NONE, READ, WRITE, EXECUTE
|
|
if the object doesn't exists, or is not readable, throw an exception
|
|
@param string $object The object path to examine
|
|
@return array with READ, WRITE, EXECUTE */
|
|
public function validate($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(
|
|
dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
),
|
|
$object
|
|
),
|
|
404
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
$ownerid = intval($search["ownerid"]);
|
|
$groupid = intval($search["groupid"]);
|
|
$modbits = octdec($search["modbits"]);
|
|
if ($this->authiduser === 0) {
|
|
return array("READ", "WRITE", "EXECUTE");
|
|
}
|
|
|
|
$res = array();
|
|
if ($this->authiduser === $ownerid) {
|
|
if (($modbits & 0100) === 0100) {
|
|
$res[] = "EXECUTE";
|
|
}
|
|
if (($modbits & 0200) === 0200) {
|
|
$res[] = "WRITE";
|
|
}
|
|
if (($modbits & 0400) === 0400) {
|
|
$res[] = "READ";
|
|
}
|
|
}
|
|
|
|
foreach ($this->authgroups as $group) {
|
|
if ($group !== $groupid) {
|
|
continue;
|
|
}
|
|
if (($modbits & 0010) === 0010) {
|
|
$res[] = "EXECUTE";
|
|
}
|
|
if (($modbits & 0020) === 0020) {
|
|
$res[] = "WRITE";
|
|
}
|
|
if (($modbits & 0040) === 0040) {
|
|
$res[] = "READ";
|
|
}
|
|
}
|
|
|
|
if (($modbits & 0001) === 0001) {
|
|
$res[] = "EXECUTE";
|
|
}
|
|
if (($modbits & 0002) === 0002) {
|
|
$res[] = "WRITE";
|
|
}
|
|
if (($modbits & 0004) === 0004) {
|
|
$res[] = "READ";
|
|
}
|
|
|
|
return array_unique($res);
|
|
}
|
|
|
|
/** Add a new object, with ownerid and groupid, and mode bits
|
|
@param string $object Object path to add
|
|
@param integer $ownerid Owner ID of the object
|
|
@param integer $groupid Group ID of the object
|
|
@param integer $modbits Bits of authorization
|
|
@return boolean TRUE or an exception with the error message */
|
|
public function add($object, $ownerid, $groupid, $modbits)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
// The modbits are stored in octal to be more readable
|
|
$modbits = decoct($modbits);
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
if ($this->authiduser !== 0 && $this->authiduser !== $ownerid) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Can't create object not owned by myself"
|
|
), 406);
|
|
}
|
|
if ($this->authiduser !== 0 && !in_array($groupid, $this->authgroups)) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Can't create object with not owned group"
|
|
), 406);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search)) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s already defined"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if we can add the file in
|
|
// the last folder (Write modbit). Root can always write.
|
|
if ($this->authiduser === 0) {
|
|
$this->db->create(array("object" => $object,
|
|
"ownerid" => $ownerid,
|
|
"groupid" => $groupid,
|
|
"modbits" => $modbits));
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
$this->treecheckWrite($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
$this->db->create(array("object" => $object,
|
|
"ownerid" => $ownerid,
|
|
"groupid" => $groupid,
|
|
"modbits" => $modbits));
|
|
return true;
|
|
}
|
|
|
|
/** Remove the information about an object and all its sub-objects
|
|
@param string $object Object path to drop
|
|
@return boolean TRUE or an exception with the error message */
|
|
public function drop($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
if ($object === "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"The root can not be removed"
|
|
), 406);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(sprintf(
|
|
dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
),
|
|
$object
|
|
), 400);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if we can remove the file
|
|
// in the last folder (Write modbit). Root can always write.
|
|
if ($this->authiduser === 0) {
|
|
$rc = $this->db->delete($object);
|
|
if ($rc > 1) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Removing more than one object"
|
|
), 406);
|
|
}
|
|
if ($rc == 0) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"No object removed"
|
|
), 406);
|
|
}
|
|
$rc = $this->db->delete("$object$this->separator%");
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
$this->treecheckWrite($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
$rc = $this->db->delete($object);
|
|
if ($rc > 1) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Removing more than one object"
|
|
), 406);
|
|
}
|
|
if ($rc == 0) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"No object removed"
|
|
), 406);
|
|
}
|
|
$rc = $this->db->delete("$object$this->separator%");
|
|
return true;
|
|
}
|
|
|
|
/** Change the owner of an object
|
|
Need to be the root administrator
|
|
@param string $object Object path to add
|
|
@param integer $ownerid Owner ID of the object
|
|
@return boolean TRUE or an exception with the error message */
|
|
public function chown($object, $ownerid)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
if ($this->authiduser !== 0) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"The chown is reserved to root user"
|
|
), 405);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
$this->db->update($object, array("ownerid" => $ownerid));
|
|
return true;
|
|
}
|
|
|
|
/** Change the group of an object
|
|
Need to be the ownerid of the object or the root administrator
|
|
@param string $object Object path to add
|
|
@param integer $groupid Group ID of the object
|
|
@return boolean TRUE or an exception with the error message */
|
|
public function chgrp($object, $groupid)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
if ($this->authiduser !== 0 && !in_array($groupid, $this->authgroups)) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"The user must be in the wanted group"
|
|
), 405);
|
|
}
|
|
if (!in_array("WRITE", $this->validate($object))) {
|
|
throw new \Exception(sprintf(dgettext(
|
|
"domframework",
|
|
"%s is write protected"
|
|
), $object), 405);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
$this->db->update($object, array("groupid" => $groupid));
|
|
return true;
|
|
}
|
|
|
|
/** Change mode bits for an object
|
|
Need to be the owner of the object or the root administrator
|
|
@param string $object Object path to change
|
|
@param integer $mod Bits of authorization
|
|
@return boolean TRUE or an exception with the error message */
|
|
public function chmod($object, $mod)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
if (!in_array("WRITE", $this->validate($object))) {
|
|
throw new \Exception(sprintf(dgettext(
|
|
"domframework",
|
|
"%s is write protected"
|
|
), $object), 405);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
// TODO : Don't update if the user is not the owner of the file
|
|
$this->db->update($object, array("modbits" => $modbits));
|
|
return true;
|
|
}
|
|
|
|
/** Return the mode bits for an object if all his parents are readable for
|
|
the user
|
|
@param string $object Object path to examine
|
|
@return int|float the modbits or an exception with the error message */
|
|
public function lsmod($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
return octdec($search["modbits"]);
|
|
}
|
|
|
|
/** Return the ownerid for an object if all his parents are readable for
|
|
the user
|
|
@param string $object Object path to examine
|
|
@return integer the ownerid or an exception with the error message */
|
|
public function lsown($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
400
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
return intval($search["ownerid"]);
|
|
}
|
|
|
|
/** Return the groupid for an object if all his parents are readable for
|
|
the user
|
|
@param string $object Object path to examine
|
|
@return integer the groupid or an exception with the error message */
|
|
public function lsgrp($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
if (substr($object, -1) === "/") {
|
|
$object = substr($object, 0, -1);
|
|
}
|
|
if (substr($object, 0, 1) !== "/") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Object don't start by slash"
|
|
), 406);
|
|
}
|
|
$object = preg_replace("#//+#", "/", $object);
|
|
if ($this->authiduser === "") {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Not authenticated"
|
|
), 401);
|
|
}
|
|
try {
|
|
$this->treecheckExecute($object);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage(), 405);
|
|
}
|
|
|
|
// All the folder structure is accessible. Check if the object already
|
|
// exists
|
|
$search = $this->db->read(array(array("object", $object)));
|
|
if (count($search) === 0) {
|
|
throw new \Exception(
|
|
sprintf(dgettext(
|
|
"domframework",
|
|
"Object %s doesn't exists"
|
|
), $object),
|
|
404
|
|
);
|
|
}
|
|
$search = reset($search);
|
|
return intval($search["groupid"]);
|
|
}
|
|
|
|
////////////////////
|
|
// TREE CHECK //
|
|
////////////////////
|
|
/** Check if all the parent objects are executable
|
|
@param string $object The object to test
|
|
@return boolean TRUE or an exception in case of error */
|
|
private function treecheckExecute($object)
|
|
{
|
|
if ($this->db === null) {
|
|
throw new \Exception(dgettext(
|
|
"domframework",
|
|
"Database to authorize is not connected"
|
|
), 500);
|
|
}
|
|
// Search all the parents in an array
|
|
$parents = array();
|
|
$par = $object;
|
|
while ($par !== "/") {
|
|
$par = dirname($par);
|
|
$parents[] = $par;
|
|
}
|
|
|
|
// For each parent (folder), check if there is the right to cross (Execute
|
|
// modbit). Look at the database in one read request for all the parents.
|
|
$parents = array_reverse($parents);
|
|
$req = "SELECT object,ownerid,groupid,modbits
|
|
FROM domframework_authorization
|
|
WHERE ";
|
|
foreach ($parents as $i => $p) {
|
|
if ($i > 0) {
|
|
$req .= " OR ";
|
|
}
|
|
$req .= "object='" . addslashes($p) . "'";
|
|
}
|
|
$res = $this->db->directRead($req);
|
|
|
|
foreach ($parents as $i => $p) {
|
|
$found = false;
|
|
foreach ($res as $r) {
|
|
if ($r["object"] === $p) {
|
|
$found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!$found) {
|
|
throw new \Exception(sprintf(
|
|
dgettext(
|
|
"domframework",
|
|
"The path %s is not found in database"
|
|
),
|
|
$p
|
|
), 404);
|
|
} else {
|
|
$parentOwner = intval($r["ownerid"]);
|
|
$parentGroup = intval($r["groupid"]);
|
|
$parentModbits = octdec($r["modbits"]);
|
|
if ($this->authiduser === 0) {
|
|
continue;
|
|
}
|
|
if (
|
|
(($parentModbits & 0100) === 64) &&
|
|
$parentOwner === $this->authiduser
|
|
) {
|
|
continue;
|
|
}
|
|
if ((($parentModbits & 0010) === 8)) {
|
|
foreach ($this->authgroups as $tmpgrp) {
|
|
if ($parentGroup === $tmpgrp || $tmpgrp === 0) {
|
|
continue 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($parentModbits & 0001) === 1) {
|
|
continue;
|
|
}
|
|
|
|
throw new \Exception(sprintf(dgettext(
|
|
"domframework",
|
|
"No execute rights on %s"
|
|
), $p), 405);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/** Check if the parent of object is writeable
|
|
@param string $object The object to found
|
|
@return boolean TRUE or an exception */
|
|
private function treecheckWrite($object)
|
|
{
|
|
$parent = dirname($object);
|
|
$search = $this->db->read(array(array("object", $parent)));
|
|
$search = reset($search);
|
|
$parentOwner = intval($search["ownerid"]);
|
|
$parentGroup = intval($search["groupid"]);
|
|
$parentModbits = octdec($search["modbits"]);
|
|
if ((($parentModbits & 0200) === 128) && $parentOwner === $this->authiduser) {
|
|
return true;
|
|
}
|
|
|
|
if ((($parentModbits & 0020) === 16)) {
|
|
if (
|
|
in_array($parentGroup, $this->authgroups) ||
|
|
in_array(0, $this->authgroups)
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (($parentModbits & 0002) === 2) {
|
|
return true;
|
|
}
|
|
|
|
throw new \Exception(sprintf(dgettext(
|
|
"domframework",
|
|
"No write rights on %s"
|
|
), $parent), 405);
|
|
}
|
|
}
|