示例#1
0
/**
* Update the local cache of the remote user details
* @param object $usr The user details we read from the remote.
*/
function UpdateUserFromExternal(&$usr)
{
    global $c;
    /**
     * When we're doing the create we will usually need to generate a user number
     */
    if (!isset($usr->user_no) || intval($usr->user_no) == 0) {
        $qry = new AwlQuery("SELECT nextval('usr_user_no_seq');");
        $qry->Exec('Login', __LINE__, __FILE__);
        $sequence_value = $qry->Fetch(true);
        // Fetch as an array
        $usr->user_no = $sequence_value[0];
    }
    $qry = new AwlQuery('SELECT * FROM usr WHERE user_no = :user_no', array(':user_no' => $usr->user_no));
    if ($qry->Exec('Login', __LINE__, __FILE__) && $qry->rows() == 1) {
        $type = "UPDATE";
        if ($old = $qry->Fetch()) {
            $changes = false;
            foreach ($usr as $k => $v) {
                if ($old->{$k} != $v) {
                    $changes = true;
                    dbg_error_log("Login", "User '%s' field '%s' changed from '%s' to '%s'", $usr->username, $k, $old->{$k}, $v);
                    break;
                }
            }
            if (!$changes) {
                dbg_error_log("Login", "No changes to user record for '%s' - leaving as-is.", $usr->username);
                if (isset($usr->active) && $usr->active == 'f') {
                    return false;
                }
                return;
                // Normal case, if there are no changes
            } else {
                dbg_error_log("Login", "Changes to user record for '%s' - updating.", $usr->username);
            }
        }
    } else {
        $type = "INSERT";
    }
    $params = array();
    if ($type != 'INSERT') {
        $params[':user_no'] = $usr->user_no;
    }
    $qry = new AwlQuery(sql_from_object($usr, $type, 'usr', 'WHERE user_no= :user_no'), $params);
    $qry->Exec('Login', __LINE__, __FILE__);
    /**
     * We disallow login by inactive users _after_ we have updated the local copy
     */
    if (isset($usr->active) && ($usr->active === 'f' || $usr->active === false)) {
        return false;
    }
    if ($type == 'INSERT') {
        $qry = new AwlQuery('INSERT INTO principal( type_id, user_no, displayname, default_privileges) SELECT 1, user_no, fullname, :privs::INT::BIT(24) FROM usr WHERE username=:username', array(':privs' => privilege_to_bits($c->default_privileges), ':username' => $usr->username));
        $qry->Exec('Login', __LINE__, __FILE__);
        CreateHomeCalendar($usr->username);
    } else {
        if ($usr->fullname != $old->{'fullname'}) {
            // Also update the displayname if the fullname has been updated.
            $qry->QDo('UPDATE principal SET displayname=:new_display WHERE user_no=:user_no', array(':new_display' => $usr->fullname, ':user_no' => $usr->user_no));
        }
    }
}
示例#2
0
        case 'DAV::privilege':
        case 'http://www.xythos.com/namespaces/StorageServer:privilege':
            $ticket_privs_array = $v->GetElements();
            // Ensure we always get an array back
            $ticket_privileges = 0;
            foreach ($ticket_privs_array as $k1 => $v1) {
                $ticket_privileges |= privilege_to_bits($v1->GetTag());
            }
            if ($ticket_privileges & privilege_to_bits('write')) {
                $ticket_privileges |= privilege_to_bits('read');
            }
            if ($ticket_privileges & privilege_to_bits('read')) {
                $ticket_privileges |= privilege_to_bits(array('read-free-busy', 'read-current-user-privilege-set'));
            }
            if ($ticket_privileges & privilege_to_bits('read-free-busy')) {
                $ticket_privileges |= privilege_to_bits('schedule-query-freebusy');
            }
            break;
    }
}
if ($ticket_timeout == 'infinity') {
    $sql_timeout = null;
} else {
    if (preg_match('{^([a-z]+)-(\\d+)$}i', $ticket_timeout, $matches)) {
        /** It isn't specified, but timeout seems to be 'unit-number' like 'Seconds-3600', so we make it '3600 Seconds' which PostgreSQL understands */
        $sql_timeout = $matches[2] . ' ' . $matches[1];
    } else {
        $sql_timeout = $ticket_timeout;
    }
}
$collection_id = $target->GetProperty('collection_id');
示例#3
0
function ticket_row_editor()
{
    global $c, $id, $editor, $can_write_principal, $privilege_names;
    $ticketrow = new Editor("Tickets", "access_ticket");
    $ticketrow->SetSubmitName('ticketrow');
    if ($can_write_principal && $ticketrow->IsSubmit()) {
        $username = $editor->Value('username');
        $ugly_path = $_POST['target'];
        if ($ugly_path == '/' . $username || $ugly_path == '/' . $username . '/') {
            $target_collection = $id;
        } else {
            $username_len = strlen($username) + 2;
            $sql = "SELECT collection_id FROM collection WHERE dav_name = :exact_name";
            $sql .= " AND substring(dav_name FROM 1 FOR {$username_len}) = '/{$username}/'";
            $params = array(':exact_name' => $ugly_path);
            if (!preg_match('#/$#', $ugly_path)) {
                $sql .= " OR dav_name = :truncated_name OR dav_name = :trailing_slash_name";
                $params[':truncated_name'] = preg_replace('#[^/]*$#', '', $ugly_path);
                $params[':trailing_slash_name'] = $ugly_path . "/";
            }
            $sql .= " ORDER BY LENGTH(dav_name) DESC LIMIT 1";
            $qry = new AwlQuery($sql, $params);
            if ($qry->Exec() && $qry->rows() > 0) {
                $row = $qry->Fetch();
                $target_collection = $row->collection_id;
            } else {
                $c->messages[] = translate('Can only add tickets for existing collection paths which you own');
                return $ticketrow;
            }
        }
        $_POST['dav_owner_id'] = $id;
        $_POST['target_collection_id'] = $target_collection;
        $ticket_id = check_by_regex($_POST['ticket_id'], '/[A-Za-z0-9]+/');
        $ticketrow->SetWhere('dav_owner_id=' . $id . ' AND ticket_id=' . AwlQuery::quote($ticket_id));
        if (isset($_POST['ticket_privileges'])) {
            $privilege_bitpos = array_flip($privilege_names);
            $priv_names = array_keys($_POST['ticket_privileges']);
            $privs_dec = privilege_to_bits($priv_names);
            $_POST['privileges'] = sprintf('%024s', decbin($privs_dec));
            $ticketrow->Assign('privileges', $privs_dec);
        }
        $c->messages[] = translate('Creating new ticket granting privileges to this Principal');
        $ticketrow->Write();
    }
    return $ticketrow;
}
示例#4
0
 /**
  * Is the user has the privileges to do what is requested.
  */
 function HavePrivilegeTo($do_what)
 {
     $test_bits = privilege_to_bits($do_what);
     //    dbg_error_log( 'caldav', 'request::HavePrivilegeTo("%s") [%s] against allowed "%s" => "%s" (%s)',
     //             (is_array($do_what) ? implode(',',$do_what) : $do_what), decbin($test_bits),
     //              decbin($this->privileges), ($this->privileges & $test_bits), decbin($this->privileges & $test_bits) );
     return ($this->privileges & $test_bits) > 0;
 }
    $distinct = 'DISTINCT ON (calendar_item.uid) ';
    $params[':path_match'] = '^' . $target_collection->bound_from();
} else {
    $where = ' WHERE caldav_data.collection_id = ' . $target_collection->resource_id();
    $distinct = '';
}
if (is_array($qry_filters)) {
    dbg_log_array("calquery", "qry_filters", $qry_filters, true);
    $components = array();
    $filter_fragment = SqlFilterFragment($qry_filters, $components);
    if ($filter_fragment !== false) {
        $where .= ' ' . $filter_fragment['sql'];
        $params = array_merge($params, $filter_fragment['params']);
    }
}
if ($target_collection->Privileges() != privilege_to_bits('DAV::all')) {
    $where .= " AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL) ";
}
if (isset($c->hide_TODO) && ($c->hide_TODO === true || is_string($c->hide_TODO) && preg_match($c->hide_TODO, $_SERVER['HTTP_USER_AGENT'])) && !$target_collection->HavePrivilegeTo('all')) {
    $where .= " AND caldav_data.caldav_type NOT IN ('VTODO') ";
}
if (isset($c->hide_older_than) && intval($c->hide_older_than > 0)) {
    $where .= " AND (CASE WHEN caldav_data.caldav_type<>'VEVENT' OR calendar_item.dtstart IS NULL THEN true ELSE calendar_item.dtstart > (now() - interval '" . intval($c->hide_older_than) . " days') END) ";
}
$sql = 'SELECT ' . $distinct . ' caldav_data.*,calendar_item.*  FROM collection INNER JOIN caldav_data USING(collection_id) INNER JOIN calendar_item USING(dav_id) ' . $where;
if (isset($c->strict_result_ordering) && $c->strict_result_ordering) {
    $sql .= " ORDER BY caldav_data.dav_id";
}
$qry = new AwlQuery($sql, $params);
if ($qry->Exec("calquery", __LINE__, __FILE__) && $qry->rows() > 0) {
    while ($dav_object = $qry->Fetch()) {
function get_freebusy($path_match, $range_start, $range_end, $bin_privs = null)
{
    global $request, $c;
    $debugging = false;
    //    if ( $debugging ) {
    //        printf( "Path: %s\n", $path_match );
    //        print_r( $range_start );
    //        print_r( $range_end );
    //    }
    if (!isset($bin_privs)) {
        $bin_privs = $request->Privileges();
    }
    if (!isset($range_start) || !isset($range_end)) {
        $request->DoResponse(400, 'All valid freebusy requests MUST contain a time-range filter');
    }
    $params = array(':path_match' => $path_match, ':start' => $range_start->UTC(), ':end' => $range_end->UTC());
    $where = ' WHERE caldav_data.dav_name ~ :path_match ';
    $where .= 'AND rrule_event_overlaps( dtstart, dtend, rrule, :start, :end) ';
    $where .= "AND caldav_data.caldav_type IN ( 'VEVENT', 'VTODO' ) ";
    $where .= "AND (calendar_item.transp != 'TRANSPARENT' OR calendar_item.transp IS NULL) ";
    $where .= "AND (calendar_item.status != 'CANCELLED' OR calendar_item.status IS NULL) ";
    $where .= "AND collection.is_calendar AND collection.schedule_transp = 'opaque' ";
    if ($bin_privs != privilege_to_bits('all')) {
        $where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL) ";
    }
    $fbtimes = array();
    $sql = 'SELECT caldav_data.caldav_data, calendar_item.rrule, calendar_item.transp, calendar_item.status, ';
    $sql .= "to_char(calendar_item.dtstart at time zone 'GMT'," . AWLDatabase::SqlUTCFormat . ') AS start, ';
    $sql .= "to_char(calendar_item.dtend at time zone 'GMT'," . AWLDatabase::SqlUTCFormat . ') AS finish, ';
    $sql .= "calendar_item.class, calendar_item.dav_id ";
    $sql .= 'FROM caldav_data INNER JOIN calendar_item USING(dav_id,user_no,dav_name,collection_id) ';
    $sql .= 'INNER JOIN collection USING(collection_id)';
    $sql .= $where;
    if (isset($c->strict_result_ordering) && $c->strict_result_ordering) {
        $sql .= ' ORDER BY dav_id';
    }
    $qry = new AwlQuery($sql, $params);
    if ($qry->Exec("REPORT", __LINE__, __FILE__) && $qry->rows() > 0) {
        while ($calendar_object = $qry->Fetch()) {
            $extra = '';
            if ($calendar_object->status == 'TENTATIVE') {
                $extra = ';BUSY-TENTATIVE';
            } else {
                if (isset($c->_workaround_client_freebusy_bug) && $c->_workaround_client_freebusy_bug) {
                    $extra = ';BUSY';
                }
            }
            //      if ( $debugging ) {
            //        $extra = ';'.$calendar_object->dav_id;
            //      }
            //      dbg_error_log( "REPORT", " FreeBusy: Not transparent, tentative or cancelled: %s, %s, %s", $calendar_object->start, $calendar_object->finish, $calendar_object->class );
            $ics = new vComponent($calendar_object->caldav_data);
            $expanded = expand_event_instances($ics, $range_start, $range_end);
            $expansion = $expanded->GetComponents(array('VEVENT' => true, 'VTODO' => true, 'VJOURNAL' => true));
            //      if ( $debugging ) echo "===================   $calendar_object->dav_id   ========================\n";
            $dtstart_type = 'DTSTART';
            foreach ($expansion as $k => $v) {
                //        if ( $debugging ) print $k."\n".$v->Render();
                $start_date = $v->GetProperty($dtstart_type);
                if (!isset($start_date) && $v->GetType() != 'VTODO') {
                    $dtstart_type = 'DUE';
                    $start_date = $v->GetProperty($dtstart_type);
                }
                $start_date = new RepeatRuleDateTime($start_date);
                $duration = $v->GetProperty('DURATION');
                $duration = !isset($duration) ? 'P1D' : $duration->Value();
                $end_date = clone $start_date;
                $end_date->modify($duration);
                if ($end_date == $start_date || $end_date < $range_start || $start_date > $range_end) {
                    //            if ( $debugging )
                    //              echo "-----------------------------------------------------\n";
                    continue;
                }
                //        if ( $debugging )
                //            echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
                $thisfb = $start_date->UTC() . '/' . $end_date->UTC() . $extra;
                array_push($fbtimes, $thisfb);
            }
        }
    }
    $freebusy = new vComponent();
    $freebusy->setType('VFREEBUSY');
    $freebusy->AddProperty('DTSTAMP', date('Ymd\\THis\\Z'));
    $freebusy->AddProperty('DTSTART', $range_start->UTC());
    $freebusy->AddProperty('DTEND', $range_end->UTC());
    sort($fbtimes);
    foreach ($fbtimes as $k => $v) {
        $text = explode(';', $v, 2);
        $freebusy->AddProperty('FREEBUSY', $text[0], isset($text[1]) ? array('FBTYPE' => $text[1]) : null);
    }
    return $freebusy;
}
示例#7
0
function handle_freebusy_request($ic)
{
    global $c, $session, $request, $ical;
    $request->NeedPrivilege('CALDAV:schedule-send-freebusy');
    $reply = new XMLDocument(array("DAV:" => "", "urn:ietf:params:xml:ns:caldav" => "C"));
    $responses = array();
    $fbq_start = $ic->GetPValue('DTSTART');
    $fbq_end = $ic->GetPValue('DTEND');
    if (!(isset($fbq_start) || isset($fbq_end))) {
        $request->DoResponse(400, 'All valid freebusy requests MUST contain a DTSTART and a DTEND');
    }
    $range_start = new RepeatRuleDateTime($fbq_start);
    $range_end = new RepeatRuleDateTime($fbq_end);
    $attendees = $ic->GetProperties('ATTENDEE');
    if (preg_match('# iCal/\\d#', $_SERVER['HTTP_USER_AGENT'])) {
        dbg_error_log("POST", "Non-compliant iCal request.  Using X-WR-ATTENDEE property");
        $wr_attendees = $ic->GetProperties('X-WR-ATTENDEE');
        foreach ($wr_attendees as $k => $v) {
            $attendees[] = $v;
        }
    }
    dbg_error_log("POST", "Responding with free/busy for %d attendees", count($attendees));
    foreach ($attendees as $k => $attendee) {
        $attendee_email = preg_replace('/^mailto:/', '', $attendee->Value());
        dbg_error_log("POST", "Calculating free/busy for %s", $attendee_email);
        /** @todo Refactor this so we only do one query here and loop through the results */
        $params = array(':session_principal' => $session->principal_id, ':scan_depth' => $c->permission_scan_depth, ':email' => $attendee_email);
        $qry = new AwlQuery('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE lower(usr.email) = lower(:email)', $params);
        if (!$qry->Exec('POST', __LINE__, __FILE__)) {
            $request->DoResponse(501, 'Database error');
        }
        if ($qry->rows() > 1) {
            // Unlikely, but if we get more than one result we'll do an exact match instead.
            if (!$qry->QDo('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE usr.email = :email', $params)) {
                $request->DoResponse(501, 'Database error');
            }
            if ($qry->rows() == 0) {
                /** Sigh... Go back to the original case-insensitive match */
                $qry->QDo('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE lower(usr.email) = lower(:email)', $params);
            }
        }
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:caldav');
        $reply->CalDAVElement($response, "recipient", $reply->href($attendee->Value()));
        if ($qry->rows() == 0) {
            $remote = new iSchedule();
            $answer = $remote->sendRequest($attendee->Value(), 'VFREEBUSY/REQUEST', $ical->Render());
            if ($answer === false) {
                $reply->CalDAVElement($response, "request-status", "3.7;Invalid Calendar User");
                $reply->CalDAVElement($response, "calendar-data");
                $responses[] = $response;
                continue;
            }
            foreach ($answer as $a) {
                if ($a === false) {
                    $reply->CalDAVElement($response, "request-status", "3.7;Invalid Calendar User");
                    $reply->CalDAVElement($response, "calendar-data");
                } elseif (substr($a, 0, 1) >= 1) {
                    $reply->CalDAVElement($response, "request-status", $a);
                    $reply->CalDAVElement($response, "calendar-data");
                } else {
                    $reply->CalDAVElement($response, "request-status", "2.0;Success");
                    $reply->CalDAVElement($response, "calendar-data", $a);
                }
                $responses[] = $response;
            }
            continue;
        }
        if (!($attendee_usr = $qry->Fetch())) {
            $request->DoResponse(501, 'Database error');
        }
        if ((privilege_to_bits('schedule-query-freebusy') & bindec($attendee_usr->p)) == 0) {
            $reply->CalDAVElement($response, "request-status", "3.8;No authority");
            $reply->CalDAVElement($response, "calendar-data");
            $responses[] = $response;
            continue;
        }
        $attendee_path_match = '^/' . $attendee_usr->username . '/';
        $fb = get_freebusy($attendee_path_match, $range_start, $range_end, bindec($attendee_usr->p));
        $fb->AddProperty('UID', $ic->GetPValue('UID'));
        $fb->SetProperties($ic->GetProperties('ORGANIZER'), 'ORGANIZER');
        $fb->AddProperty($attendee);
        $vcal = new vCalendar(array('METHOD' => 'REPLY'));
        $vcal->AddComponent($fb);
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:caldav');
        $reply->CalDAVElement($response, "recipient", $reply->href($attendee->Value()));
        $reply->CalDAVElement($response, "request-status", "2.0;Success");
        // Cargo-cult setting
        $reply->CalDAVElement($response, "calendar-data", $vcal->Render());
        $responses[] = $response;
    }
    $response = $reply->NewXMLElement("schedule-response", $responses, $reply->GetXmlNsArray(), 'urn:ietf:params:xml:ns:caldav');
    $request->XMLResponse(200, $response);
}
示例#8
0
 /**
  * Return the privileges bits for the current session user to this resource
  */
 function Privileges()
 {
     global $session;
     if (!isset($this->privileges)) {
         $this->privileges = 0;
     }
     if (is_string($this->privileges)) {
         $this->privileges = bindec($this->privileges);
     }
     if ($this->_is_group && in_array(ConstructURL('/' . $session->username . '/'), $this->GroupMemberSet())) {
         $this->privileges |= privilege_to_bits(array('DAV::read', 'DAV::read-current-user-privilege-set'));
     }
     return $this->privileges;
 }
示例#9
0
 /**
  * Does the user have the privileges to do what is requested.
  * @param $do_what mixed The request privilege name, or array of privilege names, to be checked.
  * @param $any boolean Whether we accept any of the privileges. The default is true, unless the requested privilege is 'all', when it is false.
  * @return boolean Whether they do have one of those privileges against this resource.
  */
 function HavePrivilegeTo($do_what, $any = null)
 {
     if (!isset($this->privileges)) {
         $this->FetchPrivileges();
     }
     if (!isset($any)) {
         $any = $do_what != 'all';
     }
     $test_bits = privilege_to_bits($do_what);
     dbg_error_log('DAVResource', 'Testing %s privileges of "%s" (%s) against allowed "%s" => "%s" (%s)', $any ? 'any' : 'exactly', $do_what, decbin($test_bits), decbin($this->privileges), $this->privileges & $test_bits, decbin($this->privileges & $test_bits));
     if ($any) {
         return ($this->privileges & $test_bits) > 0;
     } else {
         return ($this->privileges & $test_bits) == $test_bits;
     }
 }
示例#10
0
 /**
  * Return the privileges bits for the current session user to this resource
  */
 function Privileges()
 {
     global $session;
     if (!isset($this->privileges)) {
         $this->privileges = 0;
     }
     if (is_string($this->privileges)) {
         $this->privileges = bindec($this->privileges);
     }
     if ($this->_is_group) {
         if (isset($session->principal) && in_array($session->principal->url(), $this->GroupMemberSet())) {
             $this->privileges |= privilege_to_bits(array('DAV::read', 'DAV::read-current-user-privilege-set'));
         }
     }
     return $this->privileges;
 }
示例#11
0
        $href = $bound_from . $rawurl;
    } else {
        $href = $bound_from . substr($rawurl, $path_pos + strlen($request->path));
    }
    @dbg_error_log("REPORT", 'Reporting on href "%s"', $href);
    $href_in .= $href_in == '' ? '' : ', ';
    $href_in .= ':href' . $k;
    $params[':href' . $k] = $href;
}
$where = " WHERE caldav_data.collection_id = " . $collection->resource_id();
$where .= " AND caldav_data.dav_name IN ( {$href_in} ) ";
if ($mode == 'caldav') {
    if ($collection->Privileges() != privilege_to_bits('DAV::all')) {
        $where .= " AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL) ";
    }
    if (isset($c->hide_TODO) && $c->hide_TODO && !$collection->Privileges() == privilege_to_bits('all')) {
        $where .= " AND caldav_data.caldav_type NOT IN ('VTODO') ";
    }
}
$sql = 'SELECT calendar_item.*, addressbook_resource.*, caldav_data.* FROM caldav_data
                  LEFT JOIN calendar_item USING(dav_id, user_no, dav_name, collection_id)
                  LEFT JOIN addressbook_resource USING(dav_id)
                  LEFT JOIN collection USING(collection_id)';
/**
 * @todo: Add stanzas for missing rows, so we don't just return a blank multistatus but
 * actually return <response> stanzas with a 404 for each absent href.  We could do
 * this relatively easily with an array_flip($params) and remove each matching dav_name
 * as we process it.
 */
if (isset($c->strict_result_ordering) && $c->strict_result_ordering) {
    $where .= " ORDER BY caldav_data.dav_id";
示例#12
0
function process_ace($grantor, $by_principal, $by_collection, $ace)
{
    global $cache_delete_list, $request;
    $elements = $ace->GetContent();
    $principal_node = $elements[0];
    $grant = $elements[1];
    if ($principal_node->GetNSTag() != 'DAV::principal') {
        $request->MalformedRequest('ACL request must contain a principal, not ' . $principal->GetNSTag());
    }
    $grant_tag = $grant->GetNSTag();
    if ($grant_tag == 'DAV::deny') {
        $request->PreconditionFailed(403, 'grant-only');
    }
    if ($grant_tag == 'DAV::invert') {
        $request->PreconditionFailed(403, 'no-invert');
    }
    if ($grant->GetNSTag() != 'DAV::grant') {
        $request->MalformedRequest('ACL request must contain a principal for each ACE');
    }
    $privilege_names = array();
    $xml_privs = $grant->GetPath("/DAV::grant/DAV::privilege/*");
    foreach ($xml_privs as $k => $priv) {
        $privilege_names[] = $priv->GetNSTag();
    }
    $privileges = privilege_to_bits($privilege_names);
    $principal_content = $principal_node->GetContent();
    if (count($principal_content) != 1) {
        $request->MalformedRequest('ACL request must contain exactly one principal per ACE');
    }
    $principal_content = $principal_content[0];
    switch ($principal_content->GetNSTag()) {
        case 'DAV::property':
            $principal_property = $principal_content->GetContent();
            if ($principal_property[0]->GetNSTag() != 'DAV::owner') {
                $request->PreconditionFailed(403, 'recognized-principal');
            }
            if (privilege_to_bits('all') != $privileges) {
                $request->PreconditionFailed(403, 'no-protected-ace-conflict', 'Owner must always have all permissions');
            }
            continue;
            // and then we ignore it, since it's protected
            break;
        case 'DAV::unauthenticated':
            $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users');
            break;
        case 'DAV::href':
            $principal_type = 'href';
            $grantee = new DAVResource(DeconstructURL($principal_content->GetContent()));
            $grantee_id = $grantee->getProperty('principal_id');
            if (!$grantee->Exists() || !$grantee->IsPrincipal()) {
                $request->PreconditionFailed(403, 'recognized-principal', 'Principal "' + $principal_content->GetContent() + '" not found.');
            }
            $sqlparms = array(':to_principal' => $grantee_id);
            $where = 'WHERE to_principal=:to_principal AND ';
            if (isset($by_principal)) {
                $sqlparms[':by_principal'] = $by_principal;
                $where .= 'by_principal = :by_principal';
            } else {
                $sqlparms[':by_collection'] = $by_collection;
                $where .= 'by_collection = :by_collection';
            }
            $qry = new AwlQuery('SELECT privileges FROM grants ' . $where, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__) && $qry->rows() == 1 && ($current = $qry->Fetch())) {
                $sql = 'UPDATE grants SET privileges=:privileges::INT::BIT(24) ' . $where;
            } else {
                $sqlparms[':by_principal'] = $by_principal;
                $sqlparms[':by_collection'] = $by_collection;
                $sql = 'INSERT INTO grants (by_principal, by_collection, to_principal, privileges) VALUES(:by_principal, :by_collection, :to_principal, :privileges::INT::BIT(24))';
            }
            $sqlparms[':privileges'] = $privileges;
            $qry = new AwlQuery($sql, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__)) {
                Principal::cacheDelete('dav_name', $grantee->dav_name());
                Principal::cacheFlush('principal_id IN (SELECT member_id FROM group_member WHERE group_id = ?)', array($grantee_id));
            }
            break;
        case 'DAV::authenticated':
            $principal_type = 'authenticated';
            if (bindec($grantor->GetProperty('default_privileges')) == $privileges) {
                continue;
            }
            // There is no change, so skip it
            $sqlparms = array(':privileges' => $privileges);
            if (isset($by_collection)) {
                $sql = 'UPDATE collection SET default_privileges=:privileges::INT::BIT(24) WHERE collection_id=:by_collection';
                $sqlparms[':by_collection'] = $by_collection;
            } else {
                $sql = 'UPDATE principal SET default_privileges=:privileges::INT::BIT(24) WHERE principal_id=:by_principal';
                $sqlparms[':by_principal'] = $by_principal;
            }
            $qry = new AwlQuery($sql, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__)) {
                /**
                 *  Basically this has changed everyone's permissions now, so...
                 */
                Principal::cacheFlush('TRUE');
            }
            break;
        case 'DAV::all':
            //      $principal_type = 'all';
            $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users');
            break;
        default:
            $request->PreconditionFailed(403, 'recognized-principal');
            break;
    }
}
示例#13
0
if ($editor->Available()) {
    $c->stylesheets[] = 'css/browse.css';
    $c->scripts[] = 'js/browse.js';
    $grantrow = new Editor("Grants", "grants");
    $grantrow->SetSubmitName('savegrantrow');
    $grantrow->SetLookup('to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = ' . $id . ') ORDER BY displayname');
    if ($can_write_collection) {
        if ($grantrow->IsSubmit()) {
            $_POST['by_collection'] = $id;
            $to_principal = intval($_POST['to_principal']);
            $orig_to_id = intval($_POST['orig_to_id']);
            $grantrow->SetWhere("by_collection=" . $id . " AND to_principal={$orig_to_id}");
            if (isset($_POST['grant_privileges'])) {
                $privilege_bitpos = array_flip($privilege_names);
                $priv_names = array_keys($_POST['grant_privileges']);
                $privs = privilege_to_bits($priv_names);
                $_POST['privileges'] = sprintf('%024s', decbin($privs));
                $grantrow->Assign('privileges', $privs_dec);
            }
            $grantrow->Write();
            unset($_GET['to_principal']);
        } elseif (isset($_GET['delete_grant'])) {
            $qry = new AwlQuery("DELETE FROM grants WHERE by_collection=:grantor_id AND to_principal = :to_principal", array(':grantor_id' => $id, ':to_principal' => intval($_GET['delete_grant'])));
            $qry->Exec('collection-edit');
        }
    }
    function edit_grant_row($row_data)
    {
        global $grantrow, $id, $privilege_xlate, $privilege_names;
        global $btn_all, $btn_all_title, $btn_rw, $btn_rw_title, $btn_read, $btn_read_title;
        global $btn_fb, $btn_fb_title, $btn_sd, $btn_sd_title, $btn_ss, $btn_ss_title;
示例#14
0
 foreach ($xml_privs as $k => $priv) {
     $privilege_names[] = $priv->GetTag();
 }
 $privileges = privilege_to_bits($privilege_names);
 $principal_content = $principal->GetContent();
 if (count($principal_content) != 1) {
     $request->MalformedRequest('ACL request must contain exactly one principal per ACE');
 }
 $principal_content = $principal_content[0];
 switch ($principal_content->GetTag()) {
     case 'DAV::property':
         $principal_property = $principal_content->GetContent();
         if ($principal_property[0]->GetTag() != 'DAV::owner') {
             $request->PreconditionFailed(403, 'recognized-principal');
         }
         if (privilege_to_bits('all') != $privileges) {
             $request->PreconditionFailed(403, 'no-protected-ace-conflict', 'Owner must always have all permissions');
         }
         continue;
         // and then we ignore it, since it's protected
         break;
     case 'DAV::unauthenticated':
         $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users');
         break;
     case 'DAV::href':
         $principal_type = 'href';
         $principal = new DAVResource(DeconstructURL($principal_content->GetContent()));
         if (!$principal->Exists() || !$principal->IsPrincipal()) {
             $request->PreconditionFailed(403, 'recognized-principal', 'Principal "' + $principal_content->GetContent() + '" not found.');
         }
         $sqlparms = array(':to_principal' => $principal->GetProperty('principal_id'));
示例#15
0
 private function Write($field_values, $inserting = true)
 {
     global $c;
     if (is_array($field_values)) {
         $field_values = (object) $field_values;
     }
     if (!isset($field_values->{'user_active'})) {
         if (isset($field_values->{'active'})) {
             $field_values->{'user_active'} = $field_values->{'active'};
         } else {
             if ($inserting) {
                 $field_values->{'user_active'} = true;
             }
         }
     }
     if (!isset($field_values->{'modified'}) && isset($field_values->{'updated'})) {
         $field_values->{'modified'} = $field_values->{'updated'};
     }
     if (!isset($field_values->{'type_id'}) && $inserting) {
         $field_values->{'type_id'} = 1;
     }
     // Default to 'person'
     if (!isset($field_values->{'default_privileges'}) && $inserting) {
         $field_values->{'default_privileges'} = sprintf('%024s', decbin(privilege_to_bits($c->default_privileges)));
     }
     $sql = '';
     if ($inserting) {
         $insert_fields = array();
         $param_names = array();
     } else {
         $update_list = array();
     }
     $sql_params = array();
     foreach (self::updateableFields() as $k) {
         if (!isset($field_values->{$k}) && !isset($this->{$k})) {
             continue;
         }
         $param_name = ':' . $k;
         $sql_params[$param_name] = isset($field_values->{$k}) ? $field_values->{$k} : $this->{$k};
         if ($k == 'default_privileges') {
             $sql_params[$param_name] = sprintf('%024s', $sql_params[$param_name]);
             $param_name = 'cast(' . $param_name . ' as text)::BIT(24)';
         } else {
             if ($k == 'modified' && isset($field_values->{$k}) && preg_match('{^([23]\\d\\d\\d[01]\\d[0123]\\d)T?([012]\\d[0-5]\\d[0-5]\\d)$}', $field_values->{$k}, $matches)) {
                 $sql_params[$param_name] = $matches[1] . 'T' . $matches[2];
             }
         }
         if ($inserting) {
             $param_names[] = $param_name;
             $insert_fields[] = $k;
         } else {
             $update_list[] = $k . '=' . $param_name;
         }
     }
     if ($inserting && isset(self::$db_mandatory_fields)) {
         foreach (self::$db_mandatory_fields as $k) {
             if (!isset($sql_params[':' . $k])) {
                 throw new Exception(get_class($this) . '::Create: Mandatory field "' . $k . '" is not set.');
             }
         }
         if (isset($this->user_no)) {
             $param_names[] = ':user_no';
             $insert_fields[] = 'user_no';
             $sql_params[':user_no'] = $this->user_no;
         }
         if (isset($this->created)) {
             $param_names[] = ':created';
             $insert_fields[] = 'created';
             $sql_params[':created'] = $this->created;
         }
         $sql = 'INSERT INTO ' . self::$db_tablename . ' (' . implode(',', $insert_fields) . ') VALUES(' . implode(',', $param_names) . ')';
     } else {
         $sql = 'UPDATE ' . self::$db_tablename . ' SET ' . implode(',', $update_list);
         $sql .= ' WHERE principal_id=:principal_id';
         $sql_params[':principal_id'] = $this->principal_id;
     }
     $qry = new AwlQuery($sql, $sql_params);
     if ($qry->Exec('Principal', __FILE__, __LINE__)) {
         $this->unCache();
         $new_principal = new Principal('username', $sql_params[':username']);
         foreach ($new_principal as $k => $v) {
             $this->{$k} = $v;
         }
     }
 }