The forums security code is checking to see if the user has permission to "read private data" in the package instance being served, but the student doesn't have it.
From forums-security-procs.tcl
, cvs version 1.7.2.2, line 44
if { ![acs_privacy::user_can_read_private_data_p -user_id $user_id -object_id [ad_conn package_id]] } { return 0This check comes from the
forums
module, which is part of
OpenACS but can also run under dotLRN. The check is run in both
regular OpenACS and in dotLRN, but in regular OpenACS the check
quietly returns 1 ("true") because privacy control
(PrivacyControlEnabledP
kernel parameter) is set to 0.
In dotLRN privacy control is set to 1.
But why does the check fail for a student, who should have permission
to read private data? Here we have to dig a bit into the permissions
hierarchy. When users are added to dotLRN, they are granted
permission to read private data if they are not a Guest. The relevant
code starts at line 97 of www/admin/user-new-2.tcl
in the
dotlrn
package:
Here's what's going on. In this code fragment, permission is being granted on the entire dotlrn installation. But in the previous code fragment, permission is being checked on theacs_privacy::set_user_read_private_data \ -user_id $user_id \ -object_id [dotlrn::get_package_id] \ -value $read_private_data_p
forums
package instance for a particular class. We can verify the permission
grants by performing a SQL query directly against the permissions
table:
So students are granted permission to read private data on the dotLRN installation, but for some reason this permission isn't cascading down to the forum package instance. Why not? Another SQL query:SQL> select acs_object.name(grantee_id) as grantee, acs_object.name(object_id) as object from acs_permissions where privilege = 'read_private_data'; GRANTEE OBJECT -------------------------- --------------------------------- Andrew Grumet dotLRN Andrew Student dotLRN Test Student dotLRN
The object representing the Management 101 community isn't inheriting permissions from dotLRN, the object on whichselect object_id, object_type, acs_object.name(object_id) as object, security_inherit_p from acs_objects connect by prior context_id = object_id start with object_id = 5646; 2 3 4 OBJECT_ID OBJECT_TYPE OBJECT S(ECURITY_INHERIT_P) ---------- ---------------- ------------------------------ - 5646 forums_message la la la t 2504 forums_forum Management 101 Forum t 2235 apm_package Forums t 2163 apm_package Management 101 t 2041 management.manag management101 f ement101 1373 apm_package dotLRN f 398 apm_service Main Site t -3 acs_object Object -3 t
read_private_data
was granted. Voila!
As for why permissions inheritance is turned off, we can dig into the CVS logs
for community-procs.tcl
in the tcl
subdirectory
of the dotlrn
package.
revision 1.165 date: 2002/08/15 20:23:35; author: arjun; state: Exp; lines: +8 -1 important permission bug fix to dotlrn_community::new. new communities should _not_ inherit perms from the root dotlrn instace, since all dotlrn users have read on the root dotlrn instance. without this fix, users will be able to read stuff in comm's they are not members of.
The quick and dirty solution to this problem is to make sure that all
non-Guest members of each community are granted
read_private_data
directly on the community when their
membership is added. And to make sure that this privilege is revoked
upon revoking membership.
But it strikes me as odd that we need a new privilege
(read_private_data
) instead of just checking for
read
.
The SQL query below lists out the granted privileges for a community:
So all members of a community getSQL> select object_id, acs_object.name(object_id) as object, acs_object.name(grantee_id) as grantee, privilege from acs_permissions where object_id = 2041 order by 2; OBJECT_ID OBJECT GRANTEE PRIVILEGE ---------- ----------------- ------------------------- --------------- 2041 management101 Members of Management 101 create 2041 management101 Members of Management 101 read 2041 management101 Members of Management 101 write 2041 management101 Admins of Management 101 admin
read
privilege on the
community, and because of the way inheritance is set up, this cascades
down to basically everything in the community. The problem comes with
Guests, who should be able to see some stuff in the community but not
other stuff. For Guests, we want permissions to cascade to
portlets and objects that don't expose private data, but not
otherwise. Whereas for non-Guests, permissions can cascade all the
way down without consequence.
As best I can tell, the read_private_data
privilege is
being used as a workaround in lieu of more careful management of
individual object permissions, or possibly because the
hierarchy/inheritance model simply isn't a good fit here. As designed
here, code wanting to restrict access to private data must check for
two privileges instead of one, which is unusual for permissions checks
in OpenACS, and probably not in the spirit of the original permissions
system design.
Significant discussion and design iterations are taking place on the OCT list. I'll update this page with a link once I figure out where the OCT archives live.
Here's the link: Guest handling in .LRN