Commit 2f8efb21 authored by Brian Lloyd's avatar Brian Lloyd

policy fixes

parent 1c5572b9
...@@ -212,6 +212,13 @@ class ZopeSecurityPolicy: ...@@ -212,6 +212,13 @@ class ZopeSecurityPolicy:
if name.startswith('aq_') and name not in valid_aq_: if name.startswith('aq_') and name not in valid_aq_:
raise Unauthorized(name, value) raise Unauthorized(name, value)
containerbase = aq_base(container)
accessedbase = aq_base(accessed)
if accessedbase is accessed:
# accessed is not a wrapper, so assume that the
# value could not have been acquired.
accessedbase = container
############################################################ ############################################################
# If roles weren't passed in, we'll try to get them from the object # If roles weren't passed in, we'll try to get them from the object
...@@ -236,14 +243,16 @@ class ZopeSecurityPolicy: ...@@ -236,14 +243,16 @@ class ZopeSecurityPolicy:
roles = getattr(container, '__roles__', roles) roles = getattr(container, '__roles__', roles)
if roles is _noroles: if roles is _noroles:
# Try to acquire __roles__. If __roles__ can't be if containerbase is container:
# acquired, the value is unprotected and roles is # Container is not wrapped.
# left set to _noroles. if containerbase is not accessedbase:
if aq_base(container) is not container: raise Unauthorized(name, value)
try: else:
roles = container.aq_acquire('__roles__') # Try to acquire roles
try: roles = container.aq_acquire('__roles__')
except AttributeError: except AttributeError:
pass if containerbase is not accessedbase:
raise Unauthorized(name, value)
# We need to make sure that we are allowed to # We need to make sure that we are allowed to
# get unprotected attributes from the container. We are # get unprotected attributes from the container. We are
...@@ -308,17 +317,14 @@ class ZopeSecurityPolicy: ...@@ -308,17 +317,14 @@ class ZopeSecurityPolicy:
# in the context of the accessed item; users in subfolders # in the context of the accessed item; users in subfolders
# should not be able to use proxy roles to access items # should not be able to use proxy roles to access items
# above their subfolder! # above their subfolder!
owner = eo.getOwner() owner = eo.getWrappedOwner()
# Sigh; the default userfolder doesn't return users wrapped
if owner and not hasattr(owner, 'aq_parent'):
udb = eo.getOwner(1)[0]
root = container.getPhysicalRoot()
udb = root.unrestrictedTraverse(udb)
owner = owner.__of__(udb)
if owner is not None: if owner is not None:
if container is not containerbase:
# Unwrapped objects don't need checking
if not owner._check_context(container): if not owner._check_context(container):
# container is higher up than the owner, deny access # container is higher up than the owner,
# deny access
raise Unauthorized(name, value) raise Unauthorized(name, value)
for r in proxy_roles: for r in proxy_roles:
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. DAMAGE.
$Id: cAccessControl.c,v 1.26 2004/01/16 18:49:22 Brian Exp $ $Id: cAccessControl.c,v 1.27 2004/01/27 17:09:53 Brian Exp $
If you have questions regarding this software, If you have questions regarding this software,
contact: contact:
...@@ -675,6 +675,7 @@ static PyObject *aq_validate = NULL; ...@@ -675,6 +675,7 @@ static PyObject *aq_validate = NULL;
static PyObject *aq_parent_str = NULL; static PyObject *aq_parent_str = NULL;
static PyObject *_check_context_str = NULL; static PyObject *_check_context_str = NULL;
static PyObject *getRoles = NULL; static PyObject *getRoles = NULL;
static PyObject *getWrappedOwner_str = NULL;
static int ownerous = 1; static int ownerous = 1;
static int authenticated = 1; static int authenticated = 1;
...@@ -710,6 +711,8 @@ ZopeSecurityPolicy_setup(void) { ...@@ -710,6 +711,8 @@ ZopeSecurityPolicy_setup(void) {
return -1; return -1;
UNLESS (allowed_str = PyString_FromString("allowed")) return -1; UNLESS (allowed_str = PyString_FromString("allowed")) return -1;
UNLESS (getOwner_str = PyString_FromString("getOwner")) return -1; UNLESS (getOwner_str = PyString_FromString("getOwner")) return -1;
UNLESS (getWrappedOwner_str = PyString_FromString("getWrappedOwner"))
return -1;
UNLESS (getPhysicalRoot_str = PyString_FromString("getPhysicalRoot")) UNLESS (getPhysicalRoot_str = PyString_FromString("getPhysicalRoot"))
return -1; return -1;
UNLESS (aq_parent_str = PyString_FromString("aq_parent")) return -1; UNLESS (aq_parent_str = PyString_FromString("aq_parent")) return -1;
...@@ -760,17 +763,15 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -760,17 +763,15 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
/* Import from SimpleObject Policy._noroles */ /* Import from SimpleObject Policy._noroles */
/* Note that _noroles means missing roles, spelled with a NULL in C. /* Note that _noroles means missing roles, spelled with a NULL in C.
Jim. */ Jim. */
PyObject *containerbase = NULL;
PyObject *accessedbase = NULL;
PyObject *p = NULL; PyObject *p = NULL;
PyObject *rval = NULL; PyObject *rval = NULL;
PyObject *stack = NULL; PyObject *stack = NULL;
PyObject *user = NULL; PyObject *user = NULL;
PyObject *method = NULL; PyObject *method = NULL;
PyObject *tmp = NULL; PyObject *tmp = NULL;
PyObject *udb = NULL;
PyObject *root = NULL;
PyObject *item = NULL;
char *sname; char *sname;
...@@ -808,7 +809,23 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -808,7 +809,23 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
Py_XINCREF(roles); /* Convert the borrowed ref to a real one */ Py_XINCREF(roles); /* Convert the borrowed ref to a real one */
/* new */ /*| containerbase = aq_base(container)
**| accessedbase = aq_base(accessed)
**| if accessedbase is accessed:
**| # accessed is not a wrapper, so assume that the
**| # value could not have been acquired.
**| accessedbase = container
*/
containerbase = aq_base(container);
if (containerbase == NULL) goto err;
if (aq_isWrapper(accessed))
accessedbase = aq_base(accessed);
else {
Py_INCREF(container);
accessedbase = container;
}
/*| # If roles weren't passed in, we'll try to get them from /*| # If roles weren't passed in, we'll try to get them from
**| # the object **| # the object
...@@ -818,8 +835,6 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -818,8 +835,6 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
*/ */
if (roles == NULL) { if (roles == NULL) {
/* Note that the '_noroles' arg is just a marker - our C version
of _noroles is null */
roles = callfunction4(getRoles, container, name, value, getRoles); roles = callfunction4(getRoles, container, name, value, getRoles);
if (roles == getRoles) { if (roles == getRoles) {
Py_DECREF(roles); Py_DECREF(roles);
...@@ -829,26 +844,6 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -829,26 +844,6 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
PyErr_Clear(); PyErr_Clear();
} }
/* old */
/*| # If roles weren't passed in, we'll try to get them from
**| # the object
**|
**| if roles is _noroles:
**| roles = getattr(value, "__roles__", _noroles)
*/
if (roles == NULL) {
roles = PyObject_GetAttr(value, __roles__);
if (roles == NULL)
PyErr_Clear();
}
/*| # We still might not have any roles /*| # We still might not have any roles
**| **|
**| if roles is _noroles: **| if roles is _noroles:
...@@ -871,28 +866,45 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -871,28 +866,45 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
/*| roles = getattr(container, "__roles__", _noroles) /*| roles = getattr(container, "__roles__", _noroles)
**| if roles is _noroles: **| if roles is _noroles:
**| if aq_base(container) is not container: **| if containerbase is container:
**| try: **| # Container is not wrapped.
**| roles = container.aq_acquire('__roles__') **| if containerbase is not accessedbase:
**| raise Unauthorized(name, value)
**| else:
**| # Try to acquire roles
**| try: roles = container.aq_aquire('__roles__')
**| except AttributeError: **| except AttributeError:
**| pass **| if containerbase is not accessedbase:
**| raise Unauthorized(name, value)
*/ */
roles = PyObject_GetAttr(container, __roles__); roles = PyObject_GetAttr(container, __roles__);
if (roles == NULL) { if (roles == NULL) {
PyErr_Clear(); PyErr_Clear();
if (aq_isWrapper(container)) { if (!aq_isWrapper(container)) {
if (containerbase != accessedbase) {
unauthErr(name, value);
goto err;
}
}
else {
roles = aq_acquire(container, __roles__); roles = aq_acquire(container, __roles__);
if (roles == NULL) { if (roles == NULL) {
if (PyErr_ExceptionMatches( if (PyErr_ExceptionMatches(
PyExc_AttributeError)) PyExc_AttributeError))
{ {
PyErr_Clear(); PyErr_Clear();
if (containerbase != accessedbase) {
unauthErr(name, value);
goto err;
}
} }
else else
goto err; goto err;
} }
} }
} }
/*| # We need to make sure that we are allowed to get /*| # We need to make sure that we are allowed to get
...@@ -1093,25 +1105,20 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -1093,25 +1105,20 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
**| # in the context of the accessed item; users in subfolders **| # in the context of the accessed item; users in subfolders
**| # should not be able to use proxy roles to access items **| # should not be able to use proxy roles to access items
**| # above their subfolder! **| # above their subfolder!
**| owner = eo.getOwner() **| owner = eo.getWrappedOwner()
**| # Sigh; the default userfolder doesn't return users wrapped
**| if owner and not hasattr(owner, 'aq_parent'):
**| udb=eo.getOwner(1)[0]
**| root=container.getPhysicalRoot()
**| udb=root.unrestrictedTraverse(udb)
**| owner=owner.__of__(udb)
**| **|
**| if owner is not None: **| if owner is not None:
**| if container is not containerbase:
**| if not owner._check_context(container): **| if not owner._check_context(container):
**| # container is higher up than the owner, deny **| # container is higher up than the owner,
**| # access **| # deny access
**| raise Unauthorized(name, value) **| raise Unauthorized(name, value)
**| **|
**| for r in proxy_roles: **| for r in proxy_roles:
**| if r in roles: return 1 **| if r in roles:
**| return 1
**| **|
**| raise Unauthorized, ('You are not authorized to access' **| raise Unauthorized(name, value)
**| '<em>%s</em>.' % cleanupName(name, value))
*/ */
proxy_roles = PyObject_GetAttr(eo, _proxy_roles_str); proxy_roles = PyObject_GetAttr(eo, _proxy_roles_str);
...@@ -1123,9 +1130,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -1123,9 +1130,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
else if (PyObject_IsTrue(proxy_roles)) else if (PyObject_IsTrue(proxy_roles))
{ {
/* patch!! -------------------------------- */ method = PyObject_GetAttr(eo, getWrappedOwner_str);
method = PyObject_GetAttr(eo, getOwner_str);
if (method == NULL) { if (method == NULL) {
Py_DECREF(eo); Py_DECREF(eo);
Py_DECREF(proxy_roles); Py_DECREF(proxy_roles);
...@@ -1140,78 +1145,12 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -1140,78 +1145,12 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
goto err; goto err;
} }
if (PyObject_IsTrue(owner)) {
if (!PyObject_HasAttr(owner, aq_parent_str)) {
item = PyInt_FromLong(1);
if (item == NULL) {
Py_DECREF(eo); Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
goto err;
}
tmp = callmethod1(eo, getOwner_str, item); if (owner != Py_None) {
Py_DECREF(item);
if (tmp == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
goto err;
}
udb = PySequence_GetItem(tmp, 0);
Py_DECREF(tmp);
if (udb == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
goto err;
}
method = PyObject_GetAttr(container,
getPhysicalRoot_str);
if (method == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
Py_DECREF(udb);
goto err;
}
root = PyObject_CallObject(method, NULL);
Py_DECREF(method);
if (root == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
Py_DECREF(udb);
goto err;
}
ASSIGN(udb, callmethod1(root, unrestrictedTraverse_str,
udb));
Py_DECREF(root);
if (udb == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
Py_DECREF(owner);
goto err;
}
ASSIGN(owner, callmethod1(owner, __of__, udb));
Py_DECREF(udb);
if (owner == NULL) {
Py_DECREF(eo);
Py_DECREF(proxy_roles);
goto err;
}
}
}
Py_DECREF(eo); if (containerbase != container) {
if (owner != Py_None) {
tmp = callmethod1(owner,_check_context_str, tmp = callmethod1(owner,_check_context_str,
container container
); );
...@@ -1228,12 +1167,11 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -1228,12 +1167,11 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
unauthErr(name, value); unauthErr(name, value);
goto err; goto err;
} }
Py_DECREF(owner);
Py_DECREF(tmp); Py_DECREF(tmp);
} }
/* ------------------------------------------- */ Py_DECREF(owner);
}
contains = 0; contains = 0;
...@@ -1305,13 +1243,13 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -1305,13 +1243,13 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
} }
} /* End of authentiction skip for public only access */ } /* End of authentiction skip for public only access */
/*| raise Unauthorizied, ("You are not authorized to access" /*| raise Unauthorized(name, value)
**| "<em>%s</em>." % cleanupName(name, value))
*/ */
unauthErr(name, value); unauthErr(name, value);
err: err:
Py_XDECREF(containerbase);
Py_XDECREF(accessedbase);
Py_XDECREF(stack); Py_XDECREF(stack);
Py_XDECREF(roles); Py_XDECREF(roles);
...@@ -2352,7 +2290,7 @@ void initcAccessControl(void) { ...@@ -2352,7 +2290,7 @@ void initcAccessControl(void) {
module = Py_InitModule3("cAccessControl", module = Py_InitModule3("cAccessControl",
cAccessControl_methods, cAccessControl_methods,
"$Id: cAccessControl.c,v 1.26 2004/01/16 18:49:22 Brian Exp $\n"); "$Id: cAccessControl.c,v 1.27 2004/01/27 17:09:53 Brian Exp $\n");
aq_init(); /* For Python <= 2.1.1, aq_init() should be after aq_init(); /* For Python <= 2.1.1, aq_init() should be after
Py_InitModule(). */ Py_InitModule(). */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment