API 409 error

rstasel
Valued Contributor

Hi All,

I'm at wits end with an API job that SHOULD set an extension attribute, but instead just comes back with a 409 error and no good info WHY.

#!/bin/sh

apiUser="user"
apiPass="pass"
jssURL="https://jss.example.com:8443"
ea_number="91"
serial=$(system_profiler SPHardwareDataType | grep 'Serial Number (system)' | awk '{print $NF}')

name=$(curl -s "https://inventory.example.com/serial/$serial" | grep -A1 -o "Device name:" | tail -n1 | sed 's/^[ 	]*//;s/[ 	]*$//' | cut -d" " -f1)

if [ ! $name ]; then
        name="Undefined"
fi

# Create xml
echo "<computer><extension_attributes><extension_attribute><id>$ea_number</id><value>$name</value></extension_attribute></extension_attributes></computer>" | xmllint --format - > /private/tmp/ea.xml

## Upload the xml file
curl -vvvfku "${apiUser}":"${apiPass}" "${jssURL}/JSSResource/computers/serialnumber/${serial}/subset/extensionattributes" -H "Content-Type: text/xml" -T /private/tmp/ea.xml -X PUT

And all I get back from the API is "the requested URL returned error: 409". The full PUT url looks like:

/JSSResource/computers/serialnumber/C1MQ41xxxxxx/subset/extensionattributes

(obviously the serial is obfuscated). I see nothing wrong. the account being used has update/read for computers, computer extension attributes, and read for sites. I've tried just giving it all rights, same result.

JSS is on 10.22.1.

Anyone see what I'm doing wrong? Oh, the xml the script generates looks like:

<?xml version="1.0"?>
<computer>
  <extension_attributes>
    <extension_attribute>
      <id>91</id>
      <value>Undefined</value>
    </extension_attribute>
  </extension_attributes>
</computer>

I've tried with and without the pass through xmllint and the results are the same. I've also confirmed there's not some random phantom duplicate device in our JSS with the same serial (doing an API call with same api account, just polling for computer ID based on serial, returns one result).

Thanks!

2 ACCEPTED SOLUTIONS

rstasel
Valued Contributor

Figured it out. So apparently when I'd tried other permissions, something else was broken in the script, that also resulted in a 409 error.

Stepped back to just manually crafting a PUT and was getting a "Not authorized for user PUT". Turns out, even to update a computer extension attribute, you need user access: https://www.jamf.com/jamf-nation/discussions/17846/9-81-issue-with-api-update

Specifically, since I just tested this, you need "UPDATE" permission to Users, as well as read. This makes... zero sense, but works.

View solution in original post

SamF
Contributor II
Contributor II

Documentation on the privileges required to interact with a given endpoint/resource can be found here. Updates to the user and location information also updates any user objects associated with that device, hence why the additional privilege is necessary in this case. The API does not differentiate between the contents of the request body to know whether you're including information that would require those privileges, therefore all calls to that resource/operation combo require the same privileges.

View solution in original post

9 REPLIES 9

rstasel
Valued Contributor

Looking at this: https://www.jamf.com/developers/apis/classic/reference/#/computers/findComputersBySerialNumberSubset

Makes me think maybe you can't PUT based on serial number? So I would need to get the ID, then do the put?

Going to test that.

rstasel
Valued Contributor

same results.

rstasel
Valued Contributor

Figured it out. So apparently when I'd tried other permissions, something else was broken in the script, that also resulted in a 409 error.

Stepped back to just manually crafting a PUT and was getting a "Not authorized for user PUT". Turns out, even to update a computer extension attribute, you need user access: https://www.jamf.com/jamf-nation/discussions/17846/9-81-issue-with-api-update

Specifically, since I just tested this, you need "UPDATE" permission to Users, as well as read. This makes... zero sense, but works.

tlarkin
Honored Contributor

This is probably due to the fact that you can have EAs from the User objects so it is a dependency. That is my guess

rstasel
Valued Contributor

Nope....

54f08248b0e94986a7e63b4b7f98bb3b

SamF
Contributor II
Contributor II

Documentation on the privileges required to interact with a given endpoint/resource can be found here. Updates to the user and location information also updates any user objects associated with that device, hence why the additional privilege is necessary in this case. The API does not differentiate between the contents of the request body to know whether you're including information that would require those privileges, therefore all calls to that resource/operation combo require the same privileges.

rstasel
Valued Contributor

Sure, but I'm not updating user or location... I'm updating a computer extension attribute, which according to the docs, JUST needs "/computerextensionattributes/id/{id} PUT Update - Extension Attributes"

I also gave Read since I also wanted to read back, as well as read for computers.

I don't see anything that indicates I should be required to have User update rights for writing to a computer EA...

rstasel
Valued Contributor

Ah, so it's really this line, not the one I posted (that line is regarding changing the actual EA, not changing the value stored in the EA.

/computers/id/{id} PUT

Update - Computers
Update - Users

Still weird that it's (seemingly) doing a authorization check before checking what I'm actually trying to update.

rstasel
Valued Contributor

Though, regardless, I was getting a 409 when I lacked "Users" permission. Seems like it should be returning a 401 instead.