Project

General

Profile

Actions

Bug #12555

closed

Only first FreeIPA XMLRPC call succeeds Foreman proxy 1.10 and FreeIPA, version: 4.1.4

Added by Michael Eklund about 9 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
Realm
Target version:
Difficulty:
Triaged:
Fixed in Releases:
Found in Releases:

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.

Actions #1

Updated by Michael Eklund about 9 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
Actions #2

Updated by Michael Eklund about 9 years ago

probably related to IPA 4.1 Replay Protection

Actions #3

Updated by Dominic Cleal about 9 years ago

  • Project changed from Foreman to Smart Proxy
  • Category set to Realm
Actions #4

Updated by Daniel O about 9 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.

Actions #5

Updated by Davy Stoffel about 9 years ago

Hi, same here too. rhel 7.2, ipa-server 4.2
Given workaround works too for us, please advise.

Actions #6

Updated by Michael Eklund about 9 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

Actions #7

Updated by Anonymous about 9 years ago

  • Status changed from New to Assigned
  • Assignee set to Anonymous
Actions #8

Updated by The Foreman Bot about 9 years ago

  • Status changed from Assigned to Ready For Testing
  • Pull request https://github.com/theforeman/smart-proxy/pull/353 added
Actions #9

Updated by Anonymous about 9 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...

Actions #10

Updated by Michael Eklund about 9 years ago

Confirmed to work for me.

Actions #11

Updated by Davy Stoffel about 9 years ago

Confirmed to work for us too.

Actions #12

Updated by Dominic Cleal about 9 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.

Actions #13

Updated by Anonymous about 9 years ago

  • Status changed from Ready For Testing to Closed
  • % Done changed from 0 to 100
Actions #14

Updated by Donny Davis about 9 years ago

Fix is also working for me on FreeIPA 4.2.3 with Foreman 1.9.3

Actions #15

Updated by Stephen Benjamin almost 9 years ago

  • Bugzilla link set to 1282539
Actions #16

Updated by Stephen Benjamin almost 9 years ago

  • Bugzilla link changed from 1282539 to 1305402
Actions

Also available in: Atom PDF