diff --git a/doc/markdown/auth_guide.md b/doc/markdown/auth_guide.md
index 9a8df92..4d38dfa 100644
--- a/doc/markdown/auth_guide.md
+++ b/doc/markdown/auth_guide.md
@@ -144,6 +144,26 @@ Example:
 gswauth-add-user -K gswauthkey -a test ana anapwd
 ~~~
 
+**Change password 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
+~~~
+
 #### gswauth-delete-account:
 Delete an account. An account cannot be deleted if it still contains users, an error will be returned.
 
diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user
index e32ea28..78af60d 100755
--- a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user
+++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user
@@ -60,20 +60,28 @@ if __name__ == '__main__':
         parsed_path = '/'
     elif parsed_path[-1] != '/':
         parsed_path += '/'
-    # Ensure the account exists
-    path = '%sv2/%s' % (parsed_path, account)
-    headers = {'X-Auth-Admin-User': options.admin_user,
-               'X-Auth-Admin-Key': options.admin_key}
-    conn = http_connect(parsed.hostname, parsed.port, 'GET', path, headers,
-                        ssl=(parsed.scheme == 'https'))
-    resp = conn.getresponse()
-    if resp.status // 100 != 2:
-        headers['Content-Length'] = '0'
-        conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, headers,
+    # Check if user is changing his own password. This is carried out by
+    # making sure that the user changing the password and the user whose
+    # password is being changed are the same.
+    # If not, ensure that the account exists before creating new user.
+    if not options.admin_user == (account + ':' + user):
+        # GET the account
+        path = '%sv2/%s' % (parsed_path, account)
+        headers = {'X-Auth-Admin-User': options.admin_user,
+                   'X-Auth-Admin-Key': options.admin_key}
+        conn = http_connect(parsed.hostname, parsed.port, 'GET', path, headers,
                             ssl=(parsed.scheme == 'https'))
         resp = conn.getresponse()
         if resp.status // 100 != 2:
-            print 'Account creation failed: %s %s' % (resp.status, resp.reason)
+            # If the GET operation fails, it means the account does not exist.
+            # Now we create the account by sending a PUT request.
+            headers['Content-Length'] = '0'
+            conn = http_connect(parsed.hostname, parsed.port, 'PUT', path,
+                                headers, ssl=(parsed.scheme == 'https'))
+            resp = conn.getresponse()
+            if resp.status // 100 != 2:
+                print 'Account creation failed: %s %s' % \
+                    (resp.status, resp.reason)
     # Add the user
     path = '%sv2/%s/%s' % (parsed_path, account, user)
     headers = {'X-Auth-Admin-User': options.admin_user,
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
diff --git a/test/functional_auth/gswauth/test_gswauth.py b/test/functional_auth/gswauth/test_gswauth.py
index 3ee3f5d..5219f13 100644
--- a/test/functional_auth/gswauth/test_gswauth.py
+++ b/test/functional_auth/gswauth/test_gswauth.py
@@ -227,15 +227,16 @@ class TestGSWauth(unittest.TestCase):
             # attempt to change password
             path = '%sv2/%s/%s' % (config['auth_prefix'], config['account'],
                     config['username'])
-            headers = self._get_admin_headers()
+            headers = {'X-Auth-Admin-User':
+                       config['account'] + ':' + config['username'],
+                       'X-Auth-Admin-Key': config['password']}
             headers.update({'X-Auth-User-Key': 'newpassword',
                             'Content-Length': '0',
-                            'X-Auth-Admin-Key': config['password'],
                             'X-Auth-User-Admin': 'true'})
             conn = http_connect(config['auth_host'], config['auth_port'], 'PUT',
                     path, headers)
             resp = conn.getresponse()
-            self.assertTrue(resp.status == 401)
+            self.assertTrue(resp.status == 201)
 
         finally:
             try:
diff --git a/test/functional_auth/gswauth/test_gswauth_cli.py b/test/functional_auth/gswauth/test_gswauth_cli.py
index 4e99e38..d07b9c3 100644
--- a/test/functional_auth/gswauth/test_gswauth_cli.py
+++ b/test/functional_auth/gswauth/test_gswauth_cli.py
@@ -438,11 +438,6 @@ class TestUser(unittest.TestCase):
         self.assertNotEqual(status, 0, 'user creation succeeded with user of other account: '+output)
         self.assertEqual('403 Forbidden' in output,True, 'user creation succeeded with user of other account: '+output)
 
-        #update password of own regular user
-        (status,output)=Utils.addUser('test', 'tester', 'testingupdated', user='test:tester', key='testing')
-        self.assertNotEqual(status, 0, 'regular user update password succeeded with own credentials: '+output)
-        self.assertEqual('403 Forbidden' in output,True, 'regular user update password succeeded with own credentials: '+output)
-
     def testDeleteUser(self):
         #set test acc
         self.setTestAccUserEnv()
@@ -577,3 +572,74 @@ class TestUser(unittest.TestCase):
         (status,output) = Utils.deleteUser('test', 'usertobedeletedbyitself',user='test:usertobedeletedbyitself',key='testing')
         self.assertEqual(status, 0, 'user deletion failed with own credentials : '+output)
 
+    def testChangeKey(self):
+        # Create account and users
+        (status, output) = Utils.addAccount('test')
+        self.assertEqual(status, 0, 'Account creation failed: ' + output)
+
+        (status, output) = Utils.addAdminUser('test', 'admin', 'password')
+        self.assertEqual(status, 0, 'User addition failed: ' + output)
+
+        (status, output) = Utils.addUser('test', 'user', 'password')
+        self.assertEqual(status, 0, 'User addition failed: ' + output)
+
+        (status, output) = Utils.addResellerAdminUser('test', 'radmin', 'password')
+        self.assertEqual(status, 0, 'User addition failed: ' + output)
+
+        # Change acccount admin password/key
+        (status, output) = Utils.addAdminUser('test', 'admin', 'new_password', user='test:admin', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Change regular user password/key
+        (status, output) = Utils.addUser('test', 'user', 'new_password', user='test:user', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Change reseller admin password/key
+        (status, output) = Utils.addResellerAdminUser('test', 'radmin', 'new_password', user='test:radmin', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # To verify that password was changed for real, re-run the above commands, but with the new password
+        # Change acccount admin password/key using the new password
+        (status, output) = Utils.addAdminUser('test', 'admin', 'password', user='test:admin', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Change regular user password/key using the new password
+        (status, output) = Utils.addUser('test', 'user', 'password', user='test:user', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Change reseller admin password/key using the new password
+        (status, output) = Utils.addResellerAdminUser('test', 'radmin', 'password', user='test:radmin', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Make sure that regular user cannot upgrade to admin
+        (status, output) = Utils.addAdminUser('test', 'user', 'password', user='test:user', key='password')
+        self.assertEqual('User creation failed' in output, True, 'Update key failed: ' + output)
+
+        # Make sure that regular user cannot upgrade to reseller_admin
+        (status, output) = Utils.addResellerAdminUser('test', 'user', 'password', user='test:user', key='password')
+        self.assertEqual('User creation failed' in output, True, 'Update key failed: ' + output)
+
+        # Make sure admin cannot update himself to reseller_admin
+        (status, output) = Utils.addResellerAdminUser('test', 'admin', 'password', user='test:admin', key='password')
+        self.assertEqual('User creation failed' in output, True, 'Update key failed: ' + output)
+
+        # Account admin changing regular user password/key
+        (status, output) = Utils.addUser('test', 'user', 'new_password', user='test:admin', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+        # Verify by running the command with new password
+        (status, output) = Utils.addUser('test', 'user', 'password', user='test:user', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Reseller admin changing regular user password/key
+        (status, output) = Utils.addUser('test', 'user', 'new_password', user='test:radmin', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+        # Verify by running the command with new password
+        (status, output) = Utils.addUser('test', 'user', 'password', user='test:user', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+
+        # Reseller admin changing account admin password/key
+        (status, output) = Utils.addAdminUser('test', 'admin', 'new_password', user='test:radmin', key='password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
+        # Verify by running the command with new password
+        (status, output) = Utils.addAdminUser('test', 'admin', 'password', user='test:admin', key='new_password')
+        self.assertEqual(status, 0, 'Update key failed: ' + output)
diff --git a/test/unit/common/middleware/gswauth/swauth/test_middleware.py b/test/unit/common/middleware/gswauth/swauth/test_middleware.py
index f01c34f..bce734d 100644
--- a/test/unit/common/middleware/gswauth/swauth/test_middleware.py
+++ b/test/unit/common/middleware/gswauth/swauth/test_middleware.py
@@ -3242,6 +3242,10 @@ class TestAuth(unittest.TestCase):
 
     def test_put_user_reseller_admin_fail_bad_creds(self):
         self.test_auth.app = FakeApp(iter([
+            # Checking if user is changing his own key. This is called.
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:rdm"},
+             {"name": "test"}, {"name": ".admin"},
+             {"name": ".reseller_admin"}], "auth": "plaintext:key"})),
             # GET of user object (reseller admin)
             # This shouldn't actually get called, checked
             # below
@@ -3261,9 +3265,13 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Reseller-Admin': 'true'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 401)
-        self.assertEquals(self.test_auth.app.calls, 0)
+        self.assertEquals(self.test_auth.app.calls, 1)
 
         self.test_auth.app = FakeApp(iter([
+            # Checking if user is changing his own key. This is called.
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
+             {"name": "test"}, {"name": ".admin"}],
+                "auth": "plaintext:key"})),
             # GET of user object (account admin, but not reseller admin)
             # This shouldn't actually get called, checked
             # below
@@ -3283,13 +3291,16 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Reseller-Admin': 'true'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 401)
-        self.assertEquals(self.test_auth.app.calls, 0)
+        self.assertEquals(self.test_auth.app.calls, 1)
 
         self.test_auth.app = FakeApp(iter([
+            # Checking if user is changing his own key. This is called.
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"})),
             # GET of user object (regular user)
             # This shouldn't actually get called, checked
             # below
-            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+           ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
              {"name": "test"}], "auth": "plaintext:key"}))]))
         resp = Request.blank('/auth/v2/act/usr',
                              environ={
@@ -3304,13 +3315,17 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Reseller-Admin': 'true'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 401)
-        self.assertEquals(self.test_auth.app.calls, 0)
+        self.assertEquals(self.test_auth.app.calls, 1)
 
     def test_put_user_account_admin_fail_bad_creds(self):
         self.test_auth.app = FakeApp(iter([
             # GET of user object (account admin, but wrong
             # account)
             ('200 Ok', {}, json.dumps({"groups": [{"name": "act2:adm"},
+             {"name": "test"}, {"name": ".admin"}],
+                "auth": "plaintext:key"})),
+            # Checking if user is changing his own key.
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
              {"name": "test"}, {"name": ".admin"}],
                 "auth": "plaintext:key"}))]))
         resp = Request.blank('/auth/v2/act/usr',
@@ -3326,10 +3341,13 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Admin': 'true'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 403)
-        self.assertEquals(self.test_auth.app.calls, 1)
+        self.assertEquals(self.test_auth.app.calls, 2)
 
         self.test_auth.app = FakeApp(iter([
             # GET of user object (regular user)
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"})),
+            # Checking if user is changing his own key.
             ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
              {"name": "test"}], "auth": "plaintext:key"}))]))
         resp = Request.blank('/auth/v2/act/usr',
@@ -3345,13 +3363,17 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Admin': 'true'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 403)
-        self.assertEquals(self.test_auth.app.calls, 1)
+        self.assertEquals(self.test_auth.app.calls, 2)
 
     def test_put_user_regular_fail_bad_creds(self):
         self.test_auth.app = FakeApp(iter([
             # GET of user object (account admin, but wrong
             # account)
             ('200 Ok', {}, json.dumps({"groups": [{"name": "act2:adm"},
+             {"name": "test"}, {"name": ".admin"}],
+                "auth": "plaintext:key"})),
+            # Checking if user is changing his own key.
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
              {"name": "test"}, {"name": ".admin"}],
                 "auth": "plaintext:key"}))]))
         resp = Request.blank('/auth/v2/act/usr',
@@ -3365,13 +3387,16 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Key': 'key'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 403)
-        self.assertEquals(self.test_auth.app.calls, 1)
+        self.assertEquals(self.test_auth.app.calls, 2)
 
         self.test_auth.app = FakeApp(iter([
             # GET of user object (regular user)
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"})),
+            # Checking if user is changing his own key.
             ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
              {"name": "test"}], "auth": "plaintext:key"}))]))
-        resp = Request.blank('/auth/v2/act/usr',
+        resp = Request.blank('/auth/v2/act2/usr',
                              environ={
                                  'REQUEST_METHOD': 'PUT'},
                              headers={
@@ -3382,7 +3407,7 @@ class TestAuth(unittest.TestCase):
                                  'X-Auth-User-Key': 'key'}
                              ).get_response(self.test_auth)
         self.assertEquals(resp.status_int, 403)
-        self.assertEquals(self.test_auth.app.calls, 1)
+        self.assertEquals(self.test_auth.app.calls, 2)
 
     def test_put_user_regular_success(self):
         self.test_auth.app = FakeApp(iter([
@@ -3941,6 +3966,134 @@ class TestAuth(unittest.TestCase):
         self.assert_(not self.test_auth.credentials_match(
             {'auth': 'plaintext:key'}, 'notkey'))
 
+    def test_is_user_changing_own_key_err(self):
+        # User does not exist
+        self.test_auth.app = FakeApp(
+            iter([('404 Not Found', {}, '')]))
+        req = Request.blank('/auth/v2/act/usr',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:usr',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'key'})
+        self.assert_(
+            not self.test_auth.is_user_changing_own_key(req, 'act:usr'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # user attempting to escalate himself as admin
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/usr',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:usr',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'key',
+                                'X-Auth-User-Admin': 'true'})
+        self.assert_(
+            not self.test_auth.is_user_changing_own_key(req, 'act:usr'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # admin attempting to escalate himself as reseller_admin
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
+             {"name": "test"}, {"name": ".admin"}],
+                "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/adm',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:adm',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'key',
+                                'X-Auth-User-Reseller-Admin': 'true'})
+        self.assert_(
+            not self.test_auth.is_user_changing_own_key(req, 'act:adm'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # different user
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/usr2',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:usr',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'key'})
+        self.assert_(
+            not self.test_auth.is_user_changing_own_key(req, 'act:usr2'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # wrong key
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/usr',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:usr',
+                                'X-Auth-Admin-Key': 'wrongkey',
+                                'X-Auth-User-Key': 'newkey'})
+        self.assert_(
+            not self.test_auth.is_user_changing_own_key(req, 'act:usr'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+    def test_is_user_changing_own_key_sucess(self):
+        # regular user
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:usr"},
+             {"name": "test"}], "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/usr',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:usr',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'newkey'})
+        self.assert_(
+            self.test_auth.is_user_changing_own_key(req, 'act:usr'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # account admin
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
+             {"name": "test"}, {"name": ".admin"}],
+                "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/adm',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:adm',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'newkey',
+                                'X-Auth-User-Admin': 'true'})
+        self.assert_(
+            self.test_auth.is_user_changing_own_key(req, 'act:adm'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
+        # reseller admin
+        self.test_auth.app = FakeApp(iter([
+            ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"},
+             {"name": "test"}, {"name": ".admin"},
+                {"name": ".reseller_admin"}], "auth": "plaintext:key"}))]))
+        req = Request.blank('/auth/v2/act/adm',
+                            environ={
+                                'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Auth-Admin-User': 'act:adm',
+                                'X-Auth-Admin-Key': 'key',
+                                'X-Auth-User-Key': 'newkey',
+                                'X-Auth-User-Reseller-Admin': 'true'})
+        self.assert_(
+            self.test_auth.is_user_changing_own_key(req, 'act:adm'))
+        self.assertEquals(self.test_auth.app.calls, 1)
+
     def test_is_super_admin_success(self):
         self.assert_(
             self.test_auth.is_super_admin(