Thanks to visit codestin.com
Credit goes to github.com

Skip to content

403 Forbidden for POST Requests to change owner to nobody #481

Closed
@nicolas-rdgs

Description

@nicolas-rdgs

Describe the bug

I don't know if it's really a bug, but the client send a bad request to Splunk because there is a conflict key argument.

The client returns a 403 Forbidden error when I try to change the owner of a saved search via the "POST" method of SavedSearch object/entity.

Splunk (please complete the following information):

  • Version: 8.2.2.1
  • OS: Debian 11
  • Deployment: single-instance

SDK (please complete the following information):

  • Version: 1.7.1
  • Language Runtime Version: Python 3.9.2
  • OS: Debian 11

To Reproduce

import splunklib.client as client

service = client.connect(host=, port=, username=, password=, owner="admin", app="search", sharing="app")
saved_search = service.saved_searches["Test savedsearch"]
saved_search.post("acl", owner="nobody", app="search", sharing="app")

# Traceback
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
/home/user/splunk_update_rules.ipynb Cell 2 in <cell line: 2>()
      1 a = service.saved_searches["Test savedsearch"]
----> 2 a.post("acl", owner="nobody", app="search", sharing="app")

File ~/.local/lib/python3.9/site-packages/splunklib/client.py:1038, in Entity.post(self, path_segment, owner, app, sharing, **query)
   1036 def post(self, path_segment="", owner=None, app=None, sharing=None, **query):
   1037     owner, app, sharing = self._proper_namespace(owner, app, sharing)
-> 1038     return super(Entity, self).post(path_segment, owner=owner, app=app, sharing=sharing, **query)

File ~/.local/lib/python3.9/site-packages/splunklib/client.py:846, in Endpoint.post(self, path_segment, owner, app, sharing, **query)
    844 else:
    845     path = self.service._abspath(self.path + path_segment, owner=owner, app=app, sharing=sharing)
--> 846 return self.service.post(path, owner=owner, app=app, sharing=sharing, **query)

File ~/.local/lib/python3.9/site-packages/splunklib/binding.py:288, in _authentication.<locals>.wrapper(self, *args, **kwargs)
    285             return request_fun(self, *args, **kwargs)
    286 try:
    287     # Issue the request
--> 288     return request_fun(self, *args, **kwargs)
    289 except HTTPError as he:
    290     if he.status == 401 and self.autologin:
    291         # Authentication failed. Try logging in, and then
    292         # rerunning the request. If either step fails, throw
    293         # an AuthenticationError and give up.

File ~/.local/lib/python3.9/site-packages/splunklib/binding.py:69, in _log_duration.<locals>.new_f(*args, **kwargs)
     66 @wraps(f)
     67 def new_f(*args, **kwargs):
     68     start_time = datetime.now()
---> 69     val = f(*args, **kwargs)
     70     end_time = datetime.now()
     71     logging.debug("Operation took %s", end_time-start_time)

File ~/.local/lib/python3.9/site-packages/splunklib/binding.py:762, in Context.post(self, path_segment, owner, app, sharing, headers, **query)
    760 logging.debug("POST request to %s (body: %s)", path, repr(query))
    761 all_headers = headers + self.additional_headers + self._auth_headers
--> 762 response = self.http.post(path, all_headers, **query)
    763 return response

File ~/.local/lib/python3.9/site-packages/splunklib/binding.py:1240, in HttpLib.post(self, url, headers, **kwargs)
   1234     body = _encode(**kwargs).encode('utf-8')
   1235 message = {
   1236     'method': "POST",
   1237     'headers': headers,
   1238     'body': body
   1239 }
-> 1240 return self.request(url, message)

File ~/.local/lib/python3.9/site-packages/splunklib/binding.py:1260, in HttpLib.request(self, url, message, **kwargs)
   1258 response = record(response)
   1259 if 400 <= response.status:
-> 1260     raise HTTPError(response)
   1262 # Update the cookie with any HTTP request
   1263 # Initially, assume list of 2-tuples
   1264 key_value_tuples = response.headers

HTTPError: HTTP 403 Forbidden -- You do not have permission to share objects at the system level

After some investigation, this following line is the root cause:

return super(Entity, self).post(path_segment, owner=owner, app=app, sharing=sharing, **query)

Because "**query" replace the values of owner, app and sharing arguments, so query become empty and kwargs in HttpLib.post too.
I have the same behavior when I do:

% curl -sku admin:xxx -d output_mode=json 'https://localhost:8089/servicesNS/nobody/soc_rules/saved/searches/Test%20savedsearch/acl' | jq
{
  "messages": [
    {
      "type": "ERROR",
      "text": "You do not have permission to share objects at the system level"
    }
  ]
}

I discovered the "body" argument/key from binding.py (line: 1221) that parse correctly the POST data, so when I do the following request, it works:

saved_search.post("acl", body={"owner":"nobody", "app": "search", "sharing": "app"})

{'status': 200,
 'reason': 'OK',
 'headers': [('Date', 'Wed, 24 Aug 2022 15:09:42 GMT'),
......
}

It is the correct way to do that or it is a unwanted behavior?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions