summaryrefslogtreecommitdiffstats
path: root/gluster/swift/common/middleware/gswauth/swauth/middleware.py
diff options
context:
space:
mode:
authorPrashanth Pai <ppai@redhat.com>2014-01-02 12:20:20 +0530
committerChetan Risbud <crisbud@redhat.com>2014-01-08 03:30:36 -0800
commitc3c46d6188015cd5f75e7a6f754fd032ab30ac21 (patch)
treea40987f9ddc5b5a130eee4ac5bb29e4f1898989b /gluster/swift/common/middleware/gswauth/swauth/middleware.py
parentf81f652899b9fd46114ce9089f6b9a97ea9584a1 (diff)
Fix users not able to change their own password/key
Users were not able to update their own password/key with the update operation resulting in 403 (HTTPForbidden). EXAMPLES: Command to update password/key of regular user: gswauth-add-user -U account1:user1 -K old_pass account1 user1 new_pass Command to update password/key of account admin: gswauth-add-user -U account1:admin -K old_pass -a account1 admin new_pass Command to update password/key of reseller_admin: gswauth-add-user -U account1:radmin -K old_pass -r account1 radmin new_pass BUG: https://bugs.launchpad.net/gluster-swift/+bug/1262227 Change-Id: I604da5aee67099b29541eb7e51a040a041f1961b Signed-off-by: Prashanth Pai <ppai@redhat.com> Reviewed-on: http://review.gluster.org/6650 Reviewed-by: Luis Pabon <lpabon@redhat.com> Tested-by: Luis Pabon <lpabon@redhat.com> Reviewed-on: http://review.gluster.org/6668 Reviewed-by: Chetan Risbud <crisbud@redhat.com> Tested-by: Chetan Risbud <crisbud@redhat.com>
Diffstat (limited to 'gluster/swift/common/middleware/gswauth/swauth/middleware.py')
-rw-r--r--gluster/swift/common/middleware/gswauth/swauth/middleware.py51
1 files changed, 47 insertions, 4 deletions
diff --git a/gluster/swift/common/middleware/gswauth/swauth/middleware.py b/gluster/swift/common/middleware/gswauth/swauth/middleware.py
index ac1b295..c07c423 100644
--- a/gluster/swift/common/middleware/gswauth/swauth/middleware.py
+++ b/gluster/swift/common/middleware/gswauth/swauth/middleware.py
@@ -972,9 +972,19 @@ class Swauth(object):
X-Auth-User-Reseller-Admin may be set to `true` to create a
.reseller_admin.
+ Creating users
+ **************
Can only be called by an account .admin unless the user is to be a
.reseller_admin, in which case the request must be by .super_admin.
+ Changing password/key
+ *********************
+ 1) reseller_admin key can be changed by super_admin and by himself.
+ 2) admin key can be changed by any admin in same account,
+ reseller_admin, super_admin and himself.
+ 3) Regular user key can be changed by any admin in his account,
+ reseller_admin, super_admin and himself.
+
:param req: The swob.Request to process.
:returns: swob.Response, 2xx on success.
"""
@@ -990,11 +1000,14 @@ class Swauth(object):
if req.path_info or not account or account[0] == '.' or not user or \
user[0] == '.' or not key:
return HTTPBadRequest(request=req)
+ user_arg = account + ':' + user
if reseller_admin:
- if not self.is_super_admin(req):
- return HTTPUnauthorized(request=req)
- elif not self.is_account_admin(req, account):
- return self.denied_response(req)
+ if not self.is_super_admin(req) and\
+ not self.is_user_changing_own_key(req, user_arg):
+ return HTTPUnauthorized(request=req)
+ elif not self.is_account_admin(req, account) and\
+ not self.is_user_changing_own_key(req, user_arg):
+ return self.denied_response(req)
path = quote('/v1/%s/%s' % (self.auth_account, account))
resp = self.make_pre_authed_request(
@@ -1403,6 +1416,36 @@ class Swauth(object):
return user_detail and self.auth_encoder().match(
key, user_detail.get('auth'))
+ def is_user_changing_own_key(self, req, user):
+ """
+ Check if the user is changing his own key.
+ :param req: The swob.Request to check. This contains x-auth-admin-user
+ and x-auth-admin-key headers which are credentials of the
+ user sending the request.
+ :param user: User whose password is to be changed.
+ :returns True if user is changing his own key, False if not.
+ """
+ admin_detail = self.get_admin_detail(req)
+ if not admin_detail:
+ # The user does not exist
+ return False
+
+ # If user is not admin/reseller_admin and x-auth-user-admin or
+ # x-auth-user-reseller-admin headers are present in request, he may be
+ # attempting to escalate himself as admin/reseller_admin!
+ if '.admin' not in (g['name'] for g in admin_detail['groups']):
+ if req.headers.get('x-auth-user-admin') == 'true' or \
+ req.headers.get('x-auth-user-reseller-admin') == 'true':
+ return False
+ if '.reseller_admin' not in \
+ (g['name'] for g in admin_detail['groups']) and \
+ req.headers.get('x-auth-user-reseller-admin') == 'true':
+ return False
+
+ return req.headers.get('x-auth-admin-user') == user and \
+ self.credentials_match(admin_detail,
+ req.headers.get('x-auth-admin-key'))
+
def is_super_admin(self, req):
"""
Returns True if the admin specified in the request represents the