Support Forum
The Forums are a place to find answers on a range of Fortinet products from peers and product experts.
iwasnewbee
New Contributor

jsonrpc add request to fortimanager return error "no write permission"

Trying Python module "requests" on FortiManager URL with /jsonrpc, it is ok when doing method "get". But change to method "add", it returns an error code: -10147 and message: no write permission. Tried on different Fortimanager and get same result. FM version is 6.2.8

 

The admin setting on Fortimanager already enabled with "set rpc-permit read-write".

 

Anyone encountered same problem? 

 

1 Solution
vschmitt_FTNT

Dear Meng,

 

Thank you for your answer.

Yes you have to lock the adom, make your changes and the commit the changes and then unlock the adom. This must be done in the script so that you don't hit the error.

Even if you do not see it locked in the GUI, if you run your script that does not contain the lock of adom before doing changes, it will return the same error code.

When you are saying:


Or even I locked it manually from GUI using same id, the result is the same.

Are you using same session id as the script while the script is running, or am I missing something? Because the lock must be done using the same session id, but after the login call and before the add function calls.

 

Also I adapted, your sample to add the "schedule" data parameter that is mandatory to add_firewall_policy and removed the "type" data parameter that was not correctly understood in you add_firewall_address.

 

When adding the lock_adom(), commit_changes() and unlock_adom() in the code, it does not trigger the error, if we omit them it triggers the errors, in my environment.

I presume the lock is not on the policy package itself because as I understand even adding an address does not work for you.

 

 

Also it may not be an locking issue, in case of admin user account not having sufficient privilege it would trigger an error code -11 "No permission for the resource", in case of no JSON API Access Read-Write, or not being allowed to all Administrative Domains, or not sufficient "Admin profile". So it should not be your case.

 

Nevertheless, please find in attachment your script modified to take into account the lock, commit and unlock steps.

Maybe you can share the output of your script so I can better help you?

 

View solution in original post

4 REPLIES 4
vschmitt_FTNT

Hello,

 

This error code -10147 is usually when you are trying to add or modify an object on locked adom, when using the Fortimanager in workspace mode normal.

 

I just did the test and it gives me same error, when locking the root Adom by another administrator:


{ "id": 1, "result": [ { "status": { "code": -10147, "message": "no write permission" }, "url": "\/pm\/config\/adom\/root\/obj\/firewall\/address" } ] }

Please find the attached  the python script I am using, the get method works fine but the add method will get same error as yours.

If the adom in your case is not locked, can you consider sharing the script you are using?

 

Best Regards

Vincent

iwasnewbee

Thank you Vincent!

 

The thing is my Adom is not locked. Or even I locked it manually from GUI using same id, the result is the same.

 

And I wonder if it needs a lock/unlock step in the script, but I don't see it in any example. So I tried following one, it takes it OK, but it doesn't change anything.

 
def lock_adom():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = {"method": "exec", "params": [{"url": f"/dvmdb/adom/{adom_name}/workspace/lock"}], "session": session_id, "id": 1}
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])

 

[{'status': {'code': 0, 'message': 'OK'}, 'url': '/dvmdb/adom/TEST/workspace/lock'}]

 

See my other codes in attachment. 

Any "add" returns,

[{'status': {'code': -10147,
'message': 'no write permission'}, 'url': '/pm/config/adom/TEST/pkg/FortiGate_TEST/firewall/policy'}]

[{'status': {'code': -10147,
'message': 'no write permission'}, 'url': '/pm/config/adom/TEST/obj/firewall/address'}]

 

Thanks,

Meng

def login():
    global session_id
    url = f"https://{server_ip}/jsonrpc"
    payload_object = { "method": "exec", "params": [{"data": [{"passwd": pwd, "user": user}],  "url": "sys/login/user"}], "id": 1}
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    session_id = (resp.json()['session'])
    print(resp.json()['result'])


def get_firewall_policy():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = {"method": "get", "params": [{"url": f"/pm/config/adom/{adom_name}/pkg/{pkg_name}/firewall/policy"}], "session": session_id, "id": 1}
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])


def add_firewall_policy():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = {
                        "method": "add",
                        "params": [{
                                    "data": [{
                                        "dstaddr": dst_address,
                                        "dstintf": dst_interface,
                                        "logtraffic": logtraffic,
                                        "name": policy_name,
                                        "service": service,
                                        "srcaddr": src_address,
                                        "srcintf": src_interface,
                                        "action": action,
                                        "nat": nat
                                    }], 
                                    "url": f"/pm/config/adom/{adom_name}/pkg/{pkg_name}/firewall/policy"
                        }],
                        "session": session_id,
                        "id": 1
    }
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])


def get_firewall_address():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = {"method": "get", "params": [{"url": f"/pm/config/adom/{adom_name}/obj/firewall/address"}], "session": session_id, "id": 1}
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])


def add_firewall_address():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = {
                        "method": "add",
                        "params": [{
                                    "data": [{
                                            "allow-routing": allow_routing,
                                            "associated-interface": associated_interface,
                                            "name": object_name,
                                            "subnet": subnet,
                                            "type": object_type
                                        }],
                                    "url": f"/pm/config/adom/{adom_name}/obj/firewall/address"
                        }],
                        "session": session_id,
                        "id": 1
    }
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])


def logout():
    url = f"https://{server_ip}/jsonrpc"
    payload_object = { "method": "exec", "params": [{"data": [{"unlocked": True}], "url": "sys/logout"}], "session": session_id, "id": 1}
    payload = json.dumps(payload_object)
    headers = {'Content-Type': "application/json"}
    resp = requests.request("POST", url, data=payload, headers=headers, verify=False)
    print(resp.json()['result'])


dst_address = 'all'
dst_interface = 'any'
logtraffic = 2
policy_name = 'TEST'
service = 'ALL'
src_address = 'all'
src_interface = 'any'
action = 1
nat = 0

allow_routing=0
associated_interface='any'
object_name='NEW-ADDR'
subnet=['1.1.1.1', '255.255.255.255']
object_type=0,


login()
get_firewall_policy()
add_firewall_policy()
get_firewall_address()
add_firewall_address()
logout()

 

vschmitt_FTNT

Dear Meng,

 

Thank you for your answer.

Yes you have to lock the adom, make your changes and the commit the changes and then unlock the adom. This must be done in the script so that you don't hit the error.

Even if you do not see it locked in the GUI, if you run your script that does not contain the lock of adom before doing changes, it will return the same error code.

When you are saying:


Or even I locked it manually from GUI using same id, the result is the same.

Are you using same session id as the script while the script is running, or am I missing something? Because the lock must be done using the same session id, but after the login call and before the add function calls.

 

Also I adapted, your sample to add the "schedule" data parameter that is mandatory to add_firewall_policy and removed the "type" data parameter that was not correctly understood in you add_firewall_address.

 

When adding the lock_adom(), commit_changes() and unlock_adom() in the code, it does not trigger the error, if we omit them it triggers the errors, in my environment.

I presume the lock is not on the policy package itself because as I understand even adding an address does not work for you.

 

 

Also it may not be an locking issue, in case of admin user account not having sufficient privilege it would trigger an error code -11 "No permission for the resource", in case of no JSON API Access Read-Write, or not being allowed to all Administrative Domains, or not sufficient "Admin profile". So it should not be your case.

 

Nevertheless, please find in attachment your script modified to take into account the lock, commit and unlock steps.

Maybe you can share the output of your script so I can better help you?

 

iwasnewbee

Awesome Vincent! Now it works like a charm!

 

The Lock and Commit then Unlock are very important, without it no modification worked. Somehow these are not showing in any API examples online.

 

I found my previous mistake, I tested lock_adom on one Adom(copy string) , but add functions all remain using {adom} variable, so always shows no permission. lol

 

Now policy and address all add successfully!!!

[{'data': {'policyid': 1}, 'status': {'code': 0, 'message': 'OK'}, 'url': '/pm/config/adom/FW_TEST/pkg/FortiGate_FIREWALL/firewall/policy'}]

[{'data': {'name': 'NEW-ADDR'}, 'status': {'code': 0, 'message': 'OK'}, 'url': '/pm/config/adom/FW_TEST/obj/firewall/address'}]

 

If I lock Adom via GUI, then "lock_adom" will show this,

[{'status': {'code': -20055, 'message': 'Workspace is locked by other user'}, 'url': '/dvmdb/adom/FW_TEST/workspace/lock'}]

then "add_policy" show this,

[{'status': {'code': -10147, 'message': 'no write permission'}, 'url': '/pm/config/adom/FW_TEST/pkg/FortiGate_FIREWALL/firewall/policy'}]

 

Labels
Top Kudoed Authors