Hi IPA Users,
I have a custom PHP script on the same Apache HTTPD server as used by IPA and the script
attempts to make a request to the IPA Server's JSON endpoint using PHP's libcurl
and a custom service principal. However, the request is coming across as the IPA HTTP
service principal, not my custom principal (and therefore the permissions are wrong). If
I run curl from the command line it works as expected. In fact, I believe this was
working before and now isn't after I upgraded to IPA 4.5.4. How do I get PHP's
libcurl to use my custom service principal instead of the HTTP service principal installed
by IPA?
This works:
kinit
myservice/ipaserver.example.com -k -t /etc/myservice.keytab
/usr/bin/curl -v -H
referer:https://ipaserver.example.com/ipa -H
"Content-Type:application/json" -H "Accept:applicaton/json"
--negotiate -u : --cacert /etc/ipa/ca.crt -d
'{"method":"user_mod/1","params":[["testuser"],{"userpassword":
"testpassword", "version": "2.228"}],"id":0}'
-X POST
https://ipaserver.example.com/ipa/json
And as expected the verbose response includes the attribute: "principal":
"myservice/ipaserver.example.com(a)EXAMPLE.COM"
Now here is what the PHP script function for the same request looks like:
<?php
function web_request($body) {
$krbcache = tmpfile();
$KRB5CCPATH = stream_get_meta_data($krbcache)['uri'];
$IPAHOSTNAME = "ipaserver.example.com";
$ref = "https://" . $IPAHOSTNAME . "/ipa";
$url = "https://" . $IPAHOSTNAME . "/ipa/json";
putenv("KRB5CCNAME=FILE:/$KRB5CCPATH");
putenv("IPAHOSTNAME=$IPAHOSTNAME");
putenv("KRB5_CLIENT_KTNAME=/etc/myservice.keytab");
putenv("KRB5_KTNAME=/etc/myservice.keytab");
$command = "kinit
myservice/ipaserver.example.com -k -t
/etc/myservice.keytab";
shell_exec($command);
$ch = curl_init($url);
$headers = array("Expect:", "Content-Type:application/json",
"Accept:application/json", "referer: " . $ref);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE);
curl_setopt($ch, CURLOPT_CAINFO, "/etc/ipa/ca.crt");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERNAME, ":");
#DEBUG OPTS
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);
#START DEBUG LOGGING
$info = curl_getinfo($ch);
foreach($info as $key => $value) {
if(!is_array($value)) {
error_log($key . ': ' . $value);
}
}
error_log('Request Body: ' . $body);
error_log('Response: ' . $result);
# END DEBUG LOGGING
if(curl_errno($ch)) {
throw new Exception("Could not send CURL request: " . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($status !== 200) {
throw new Exception("Unable to authenticate to server: HTTP Return code:
" . $status);
}
curl_close($ch);
fclose($krbcache);
return $result;
}
?>
This fails with a permissions error and I assume it has something to do with the verbose
output indicating the wrong credential cache was used: "principal":
"HTTP/ipaserver.example.com(a)EXAMPLE.COM"
Any tips?
Thanks,
Ryan