Example 1 works fine. Example 2 fails with a 403 status code. RestAPI Admin account is a super_admin with access to Global. debug cli on Fortigate shows no communication for 2 but full communication with 1. Scratching my head on this for a few days now. The "password" option seems to break it. These command come off the Fortinet Developer Network 6.2 API page. There is no password complexity requirements on this Fortigate.
Works Ex 1:
curl -k -X PUT "https://FORTIGAGE-FQDN-HERE:443/api/v2/cmdb/system/admin/USERNAME-HERE?access_token=ACCESS-TOKEN-HERE" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "{ \"name\": \"USERNAME-HERE\", \"comments\": \"This is a comment\"}"
Fails Ex 2:
curl -k -X PUT "https://FORTIGAGE-FQDN-HERE:443/api/v2/cmdb/system/admin/USERNAME-HERE?access_token=ACCESS-TOKEN-HERE" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "{ \"name\": \"USERNAME-HERE\", \"password\": \"PASSWORD-HERE\", \"comments\": \"This is a comment\"}"
Solved! Go to Solution.
So. I tested this and what I believe is, the api-user can not change sys-admin passwords with just a PUT or POST.
You can create a new admin but you can not change the password of the system admin. You can only change the other parameters of the system admin
To create a new admin with HTTP-POST json format data
{ "name":"systemadmin111", "comments":"pushed via. API", "password":"hotshotDiDiO", "accprofile" : "super_admin",}
To change a new admin attributes with HTTP-PUT json format data
{ "name":"systemadmin111", "comments":"change me", "accprofile" : "prof_admin", "schedule" : "none", }
curl -X POST -d @./createuser -k "https://x.x.x.x/api/v2/cmdb/system/admin?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json curl -X PUT -d @./changeuser -k "https://x.x.x.x/api/v2/cmdb/system/admin/systemadmin111?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json curl -k "https://x.x.x.x/api/v2/cmdb/system/admin/systemadmin111?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json I would have to see if something else is doable but my testing shows if you use password or passwd and with HTTP-PUT it does not make any changes. A side note , if you do not set a password in your json body , fortios will create the user with password and allow you to login as-is the same holds true if you did it via the cli but if you use the webUI the password is mandatory. I was shock to say the least that you could even craft a system admin with no-password. Ken Felix
PCNSE
NSE
StrongSwan
yeah I ran into this also but never spent time investigating until you post this thread. I still believe FTNT put some type of hook in NOT allowing you permission to change existing admin.
It's the same for sms-phone also. You can see more of it when you make the API call
diag debug reset
diag debug enable
diag debug app httpsd -1
And then call the PUT and you will get the "deny for blah blah blah" and status code 403.
PCNSE
NSE
StrongSwan
IDNK but with the local users the string is "passwd"
e.g data_body
{ "passwd" : "93939393939939339" } API call to change my local username curl -v -X PUT -k "https://3.3.3.3/api/v2/cmdb/user/local/klenfelix?access_token=1xhG14ytfL50wn0MNsxcgzpf3pG888" -H "Content-Type: application/x-www-form-urlencoded" -d @./passwd { "http_method":"PUT", "revision":"a3e33bd10417d4b69f10a5f4536c75bb", "revision_changed":true, "old_revision":"4aa389c6d19ed8e7ad9a3dfdfd26574f", "mkey":"klenfelix", "status":"success", "http_status":200, "vdom":"root", "path":"user", "name":"local", "serial":"FG100ETK14010505", "version":"v6.4.4", "build":1803} I have you tried json keyword "passwd" ? and have you tried installed a encrypted password with ENC? With the local users if you push the exact same password value the revison_changed does not toggle true but in your case a 403 tells me permissions Please let us know what you find. Ken Felix
PCNSE
NSE
StrongSwan
So. I tested this and what I believe is, the api-user can not change sys-admin passwords with just a PUT or POST.
You can create a new admin but you can not change the password of the system admin. You can only change the other parameters of the system admin
To create a new admin with HTTP-POST json format data
{ "name":"systemadmin111", "comments":"pushed via. API", "password":"hotshotDiDiO", "accprofile" : "super_admin",}
To change a new admin attributes with HTTP-PUT json format data
{ "name":"systemadmin111", "comments":"change me", "accprofile" : "prof_admin", "schedule" : "none", }
curl -X POST -d @./createuser -k "https://x.x.x.x/api/v2/cmdb/system/admin?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json curl -X PUT -d @./changeuser -k "https://x.x.x.x/api/v2/cmdb/system/admin/systemadmin111?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json curl -k "https://x.x.x.x/api/v2/cmdb/system/admin/systemadmin111?access_token=1xhG14ytfQ50wn0sNsxcgzpf2pW888" -H Content-Type: application/json I would have to see if something else is doable but my testing shows if you use password or passwd and with HTTP-PUT it does not make any changes. A side note , if you do not set a password in your json body , fortios will create the user with password and allow you to login as-is the same holds true if you did it via the cli but if you use the webUI the password is mandatory. I was shock to say the least that you could even craft a system admin with no-password. Ken Felix
PCNSE
NSE
StrongSwan
Thanks Ken, I will raise a feature request.
In our production environment we have compliance requirements to rotate local admin passwords on a regular basis hence my need to automate this. We do this for all vender equipment, but Fortinet Fortigate is the only one that prevents automation of admin password rotation.
This all stemmed from the current FortiOS Ansible module fortios_system_admin failing and I couldn't figure out why.
Delete and recreate the account as you found is a workaround until its fixed, hoping deleting the admin account is allowed. It would be funny if you can delete an admin account, but you can't change the password! <smh>
yeah I ran into this also but never spent time investigating until you post this thread. I still believe FTNT put some type of hook in NOT allowing you permission to change existing admin.
It's the same for sms-phone also. You can see more of it when you make the API call
diag debug reset
diag debug enable
diag debug app httpsd -1
And then call the PUT and you will get the "deny for blah blah blah" and status code 403.
PCNSE
NSE
StrongSwan
I confirmed you can indeed delete the admin account via curl to the REST API:
curl -k -X DELETE "https://FW-FQDN-GOES-HERE:443/api/v2/cmdb/system/admin/admin?access_token=ACCESS-TOKEN-GOES-HERE" -H "accept: application/json"
For anyone doing this with Ansible, this workaround is valid until Fortinet Dev's fix:
tasks:
- name: Delete existing local user uri: url: https://:443/api/v2/cmdb/..em/admin/?access_token= user: "" password: "" method: DELETE body: force_basic_auth: no validate_certs: no status_code: 200 body_format: json ignore_errors: true # register: output # - debug: var=output
- name: Re-create existing local user with new password uri: url: https://:443/api/v2/cmdb/..em/admin/?access_token= user: "" password: "" method: POST body: "{ \"name\": \"\", \"password\": \"\", \"accprofile\": \"super_admin\", \"comments\": \"Full Admin Access\", \"vdom\": [ { \"name\": \"root\" } ]}" force_basic_auth: no validate_certs: no status_code: 200 body_format: json ignore_errors: true # register: output # - debug: var=output
I'm told this has now been fixed in 6.4.7 by the devs.
:)
Thanks Fortinet
User | Count |
---|---|
1923 | |
1144 | |
769 | |
447 | |
277 |
The Fortinet Security Fabric brings together the concepts of convergence and consolidation to provide comprehensive cybersecurity protection for all users, devices, and applications and across all network edges.
Copyright 2025 Fortinet, Inc. All Rights Reserved.