Bug #12555
closedOnly first FreeIPA XMLRPC call succeeds Foreman proxy 1.10 and FreeIPA, version: 4.1.4
Description
D, [2015-11-20T14:17:00.951816 #10124] DEBUG -- : verifying remote client 1.1.1.1 against trusted_hosts ["cfg01.atl.XXXX.net"]
I, [2015-11-20T14:17:01.019800 #10124] INFO -- : freeipa: realm keytab is '/etc/foreman-proxy/freeipa.keytab' and using principal 'XXXX@XXXX.NET'
I, [2015-11-20T14:17:01.020059 #10124] INFO -- : freeipa: realm XXXX.NET
I, [2015-11-20T14:17:01.020636 #10124] INFO -- : freeipa: server is https://ipa.XXXX.net/ipa/xml
I, [2015-11-20T14:17:01.021306 #10124] INFO -- : Requesting credentials for Kerberos principal XXXX@XXXX.NET using keytab /etc/foreman-proxy/freeipa.keytab
D, [2015-11-20T14:17:01.059031 #10124] DEBUG -- : Kerberos credential cache initialised with principal: XXXX@XXXX.NET
I, [2015-11-20T14:17:02.301035 #10124] INFO -- : Attempting to host_add test2.atl.XXXX.net in FreeIPA
D, [2015-11-20T14:17:02.301183 #10124] DEBUG -- : {:setattr=>[], :random=>1, :force=>1}
E, [2015-11-20T14:17:02.322459 #10124] ERROR -- : Authorization failed.
HTTP-Error: 401 Unauthorized
D, [2015-11-20T14:17:02.322550 #10124] DEBUG -- : /usr/lib/ruby/1.9.1/xmlrpc/client.rb:547:in `do_rpc'
/usr/lib/ruby/1.9.1/xmlrpc/client.rb:420:in `call2'
/usr/lib/ruby/1.9.1/xmlrpc/client.rb:410:in `call'
/usr/share/foreman-proxy/modules/realm/freeipa.rb:103:in `create'
/usr/share/foreman-proxy/modules/realm/realm_api.rb:28:in `block in <class:Api>'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1541:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1541:in `block in compile!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:950:in `[]'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:950:in `block (3 levels) in route!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:966:in `route_eval'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:950:in `block (2 levels) in route!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:987:in `block in process_route'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:985:in `catch'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:985:in `process_route'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:948:in `block in route!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:947:in `each'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:947:in `route!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1059:in `block in dispatch!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `block in invoke'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `catch'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `invoke'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1056:in `dispatch!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:882:in `block in call!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `block in invoke'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `catch'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1041:in `invoke'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:882:in `call!'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:870:in `call'
/usr/lib/ruby/vendor_ruby/rack/commonlogger.rb:33:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:212:in `call'
/usr/share/foreman-proxy/lib/proxy/log.rb:58:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/xss_header.rb:18:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/path_traversal.rb:16:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/json_csrf.rb:18:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/base.rb:50:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/base.rb:50:in `call'
/usr/lib/ruby/vendor_ruby/rack/protection/frame_options.rb:31:in `call'
/usr/lib/ruby/vendor_ruby/rack/nulllogger.rb:9:in `call'
/usr/lib/ruby/vendor_ruby/rack/head.rb:11:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/showexceptions.rb:21:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:175:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1949:in `call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1449:in `block in call'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1726:in `synchronize'
/usr/lib/ruby/vendor_ruby/sinatra/base.rb:1449:in `call'
/usr/lib/ruby/vendor_ruby/rack/builder.rb:138:in `call'
/usr/lib/ruby/vendor_ruby/rack/urlmap.rb:65:in `block in call'
/usr/lib/ruby/vendor_ruby/rack/urlmap.rb:50:in `each'
/usr/lib/ruby/vendor_ruby/rack/urlmap.rb:50:in `call'
/usr/lib/ruby/vendor_ruby/rack/builder.rb:138:in `call'
/usr/lib/ruby/vendor_ruby/rack/handler/webrick.rb:60:in `service'
/usr/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
/usr/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
/usr/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
I, [2015-11-20T14:17:02.323003 #10124] INFO -- : 1.1.1.1 - - [20/Nov/2015 14:17:02] "POST /realm/XXXX.NET HTTP/1.1" 400 50 1.3738
'
Foreman/Foreman Proxy machine is Ubuntu 14, and is joined to the freeIPA realm.
If I mess with freeipa.rb and get a new token each time by doing this prior to each @ipa.call:
gssapi = GSSAPI::Simple.new(@ipa_server.host, "HTTP")
token = gssapi.init_context
@ipa.http_header_extra={ 'Authorization'=>"Negotiate #{strict_encode64(token)}",
'Referer' => @ipa_server.to_s,
'Content-Type' => 'text/xml; charset=utf-8'
}
then all calls work.
The only time this appears to be a problem is when multiple calls to the IPA server are issued. I am not enough of an expert on GSSAPI to know if there is additional negotiation needed after the first call, or if there is session data not being passed.
Updated by Michael Eklund about 10 years ago
IPA error logs
[Fri Nov 20 19:45:08.795455 2015] [wsgi:error] [pid 232] ipa: INFO: [xmlserver] XXXX@XXXX.NET: host_show(u'test2.atl.XXXX.net', version=u'2.51'): NotFound [Fri Nov 20 19:45:08.819009 2015] [auth_gssapi:error] [pid 423] [client 10.10.50.170:58792] gss_accept_sec_context() failed: [Unspecified GSS failure. Minor code may provide more information (Request is a replay)], referer: https://ipa.XXXX.net/ipa/xml
Updated by Michael Eklund about 10 years ago
probably related to IPA 4.1 Replay Protection
Updated by Dominic Cleal about 10 years ago
- Project changed from Foreman to Smart Proxy
- Category set to Realm
Updated by Daniel O about 10 years ago
Hi, any updates on this topic?
Same error with ipa-server 4.2 on rhel7.2 and foreman 1.9.2 on centos6.5.
Updated by Davy Stoffel about 10 years ago
Hi, same here too. rhel 7.2, ipa-server 4.2
Given workaround works too for us, please advise.
Updated by Michael Eklund about 10 years ago
here is my hack to make it send a new token on each call, this is most likely not the right way to fix this:
--- freeipa.rb 2015-11-30 12:14:10.374054744 -0500
+++ freeipa.rb.mod 2015-11-30 12:13:08.581208212 -0500
@@ -39,17 +39,12 @@
if errors.empty?
# Get krb5 token
init_krb5_ccache Proxy::Realm::Plugin.settings.realm_keytab, Proxy::Realm::Plugin.settings.realm_principal
- gssapi = GSSAPI::Simple.new(@ipa_server.host, "HTTP")
- token = gssapi.init_context
# FreeIPA API returns some nils, Ruby XML-RPC doesn't like this
XMLRPC::Config.module_eval { const_set(:ENABLE_NIL_PARSER, true) }
@ipa = XMLRPC::Client.new2(@ipa_server.to_s)
- @ipa.http_header_extra={ 'Authorization'=>"Negotiate #{strict_encode64(token)}",
- 'Referer' => @ipa_server.to_s,
- 'Content-Type' => 'text/xml; charset=utf-8'
- }
+ set_auth()
else
raise Proxy::Realm::Error.new errors.join(", ")
end
@@ -60,6 +55,7 @@
end
def find hostname
+ set_auth()
@ipa.call("host_show", [hostname])
rescue XMLRPC::FaultException => e
if e.message =~ /not found/
@@ -68,6 +64,15 @@
raise
end
end
+
+ def set_auth
+ gssapi = GSSAPI::Simple.new(@ipa_server.host, "HTTP")
+ token = gssapi.init_context
+ @ipa.http_header_extra={ 'Authorization'=>"Negotiate #{strict_encode64(token)}",
+ 'Referer' => @ipa_server.to_s,
+ 'Content-Type' => 'text/xml; charset=utf-8'
+ }
+ end
def create realm, params
check_realm realm
@@ -91,6 +96,7 @@
# disable it in order to revoke existing certs, keytabs, etc.
if host["result"]["has_keytab"]
logger.info "Attempting to disable host #{params[:hostname]} in FreeIPA"
+ set_auth()
@ipa.call("host_disable", [params[:hostname]])
end
end
@@ -98,6 +104,9 @@
end
begin
+ logger.info "Attempting to #{operation} #{params[:hostname]} in FreeIPA"
+ logger.debug "#{options.inspect}"
+ set_auth()
result = @ipa.call(operation, [params[:hostname]], options)
rescue => e
if e.message =~ /no modifications/
@@ -114,11 +123,13 @@
check_realm realm
raise Proxy::Realm::NotFound, "Host #{hostname} not found in realm!" unless find hostname
begin
+ set_auth()
result = @ipa.call("host_del", [hostname], "updatedns" => Proxy::Realm::Plugin.settings.freeipa_remove_dns)
rescue
if Proxy::Realm::Plugin.settings.freeipa_remove_dns
# If the host doesn't have a DNS record (e.g. deleting a system in Foreman before it's built)
# the above call will fail. Try again with updatedns => false
+ set_auth()
result = @ipa.call("host_del", [hostname], "updatedns" => false)
else
raise
Updated by Anonymous about 10 years ago
- Status changed from New to Assigned
- Assignee set to Anonymous
Updated by The Foreman Bot about 10 years ago
- Status changed from Assigned to Ready For Testing
- Pull request https://github.com/theforeman/smart-proxy/pull/353 added
Updated by Anonymous about 10 years ago
There is a fix available in the PR at https://github.com/theforeman/smart-proxy/pull/353. Please give it a try if you have a chance...
Updated by Dominic Cleal almost 10 years ago
- Translation missing: en.field_release set to 104
Thanks very much for the testing Michael and Davy! I've merged it on that basis.
Updated by Anonymous almost 10 years ago
- Status changed from Ready For Testing to Closed
- % Done changed from 0 to 100
Applied in changeset 07a6dae64560582b423abe921f5c6ff57946a5bb.
Updated by Donny Davis almost 10 years ago
Fix is also working for me on FreeIPA 4.2.3 with Foreman 1.9.3
Updated by Stephen Benjamin almost 10 years ago
- Bugzilla link changed from 1282539 to 1305402