theforeman / smart_proxy_realm_ad_plugin

foreman-proxy realm plugin for Active Directory
GNU General Public License v3.0
9 stars 10 forks source link

Issue with password when creating a new object #27

Open KingDaveRa opened 5 months ago

KingDaveRa commented 5 months ago

Hello

I'm very keen to use this module with Satellite as I simply need to bind my servers to AD wth SSSD, so it's just what I need. However, it doesn't work!

Our domain is now on 2022 DCs, and 2012 R2 functional level.

I've got latest Satellite and the radcli, and this plugin installed. It runs, and it did once work (with previous 2012 DCs), but I had an issue whereby the kerberos ticket would age out and not refresh, so it would stop working. I'd usually find renewing the ticket got it going again. I want to get it working properly again, so I'm revisiting, but I'm hitting a total stop now.

When I create a new machine through Satellite, it fails:

Unable to save
Failed to create heath-fickling.mydomain.here's realm entry: ERF12-5287 [ProxyAPI::ProxyException]: Unable to create realm entry ([RestClient::BadRequest]: 400 Bad Request) for Capsule https://satelliteserver.mydomain.here:9090/realm/MYDOMAIN.HERE

From the debug logs:

2024-03-21T09:19:58 fac7eefe [I] Started POST /realm/MYDOMAIN.HERE/
2024-03-21T09:19:58 fac7eefe [D] verifying remote client 1.1.1.1 against trusted_hosts ["domaincontroller.MYDOMAIN.HERE"]
2024-03-21T09:19:58 fac7eefe [I] Proxy::AdRealm: initialize...
2024-03-21T09:19:58 fac7eefe [I] Proxy::AdRealm: create... MYDOMAIN.HERE, heath-fickling.MYDOMAIN.HERE, {"hostname"=>"heath-fickling.MYDOMAIN.HERE", "userclass"=>"BNU: RedHat 8", "realm"=>"MYDOMAIN.HERE"}
2024-03-21T09:19:58 fac7eefe [D] Requesting credentials for Kerberos principal satellite-user@MYDOMAIN.HERE using keytab /etc/foreman-proxy/realm_ad.keytab
2024-03-21T09:19:58 fac7eefe [D] Kerberos credential cache initialised with principal: satellite-user@MYDOMAIN.HERE
2024-03-21T09:19:59 fac7eefe [E] Cannot set computer password: Authentication error
2024-03-21T09:19:59 fac7eefe [W] Error details for Cannot set computer password: Authentication error: <RuntimeError>: Cannot set computer password: Authentication error
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:106:in `join'
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:106:in `radcli_join'
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:47:in `create'
/usr/share/foreman-proxy/modules/realm/realm_api.rb:13:in `block in <class:Api>'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1697:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1697:in `block in compile!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1030:in `block (3 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1049:in `route_eval'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1030:in `block (2 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1078:in `block in process_route'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1076:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1076:in `process_route'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1028:in `block in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1025:in `each'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1025:in `route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1147:in `block in dispatch!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1142:in `dispatch!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:956:in `block in call!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:956:in `call!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:945:in `call'
/usr/share/foreman-proxy/lib/proxy/log.rb:101:in `call'
/usr/share/foreman-proxy/lib/proxy/request_id_middleware.rb:11:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/xss_header.rb:18:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/path_traversal.rb:16:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/json_csrf.rb:26:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/frame_options.rb:31:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/null_logger.rb:11:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/head.rb:12:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/show_exceptions.rb:22:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:218:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:2004:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1564:in `block in call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1780:in `synchronize'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1564:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:74:in `block in call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:58:in `each'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:58:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/builder.rb:244:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/handler/webrick.rb:95:in `service'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/httpserver.rb:140:in `service'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/httpserver.rb:96:in `run'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/server.rb:310:in `block in start_thread'
/usr/share/gems/gems/logging-2.3.1/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
2024-03-21T09:19:59 fac7eefe [W] Cannot set computer password: Authentication error: <RuntimeError>: Cannot set computer password: Authentication error
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:106:in `join'
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:106:in `radcli_join'
/usr/local/share/gems/gems/smart_proxy_realm_ad_plugin-0.1/lib/smart_proxy_realm_ad/provider.rb:47:in `create'
/usr/share/foreman-proxy/modules/realm/realm_api.rb:13:in `block in <class:Api>'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1697:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1697:in `block in compile!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1030:in `block (3 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1049:in `route_eval'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1030:in `block (2 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1078:in `block in process_route'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1076:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1076:in `process_route'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1028:in `block in route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1025:in `each'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1025:in `route!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1147:in `block in dispatch!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1142:in `dispatch!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:956:in `block in call!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `catch'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1119:in `invoke'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:956:in `call!'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:945:in `call'
/usr/share/foreman-proxy/lib/proxy/log.rb:101:in `call'
/usr/share/foreman-proxy/lib/proxy/request_id_middleware.rb:11:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/xss_header.rb:18:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/path_traversal.rb:16:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/json_csrf.rb:26:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.4/lib/rack/protection/frame_options.rb:31:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/null_logger.rb:11:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/head.rb:12:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/show_exceptions.rb:22:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:218:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:2004:in `call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1564:in `block in call'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1780:in `synchronize'
/usr/share/gems/gems/sinatra-2.2.4/lib/sinatra/base.rb:1564:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:74:in `block in call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:58:in `each'
/usr/share/gems/gems/rack-2.2.7/lib/rack/urlmap.rb:58:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/builder.rb:244:in `call'
/usr/share/gems/gems/rack-2.2.7/lib/rack/handler/webrick.rb:95:in `service'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/httpserver.rb:140:in `service'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/httpserver.rb:96:in `run'
/usr/share/gems/gems/webrick-1.8.1/lib/webrick/server.rb:310:in `block in start_thread'
/usr/share/gems/gems/logging-2.3.1/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
2024-03-21T09:19:59 fac7eefe [I] Finished POST /realm/MYDOMAIN.HERE/ with 400 (841.26 ms)
2024-03-21T09:19:59  [D] close: 1.1.1.1:59008

HOWEVER - the computer object exists in AD, as it got created.

So my next step was to cobble together a basic script using adcli to try and bind and do a join (I forget where I borrowed most of this from).

require 'radcli'
require "rkerberos"

# Kinit using principal name and keytab.
principal = "satellite-user"
#keytab file over an unsecured network.
keytab="/etc/foreman-proxy/satellite.keytab"
krb5 = Kerberos::Krb5.new
ccache = Kerberos::Krb5::CredentialsCache.new
krb5.get_init_creds_keytab principal, keytab, nil, ccache

# Connect

adconn = Adcli::AdConn.new("mydomain.here")
adconn.set_domain_realm("MYDOMAIN.HERE")
adconn.set_domain_controller("domaincontroller.mydomain.here")

adconn.set_login_ccache_name("")

res = adconn.connect

enroll = Adcli::AdEnroll.new(adconn)
enroll.set_computer_name("jointest4")
enroll.set_host_fqdn("jointest4.mydomain.here")
enroll.set_computer_password("<random password>")

#enroll.join()
      begin
        enroll.join
        return true
      rescue RuntimeError => ex
        raise ex unless ex.message =~ /Authentication error/
        for i in 1..100
          sleep(0.3)
          begin
            if enroll.respond_to? :update
              enroll.update
            else
              enroll.password
            end
            return true
          rescue RuntimeError => ex
            raise ex unless i < 99 and ex.message =~ /Authentication error/
          end
        end
      end

As far as I can see, this works. No errors, and a seemingly complete AD computer object.

So my theory is that radcli is totally fine and working, but this plugin is failing to understand what it's returning, and falls on its face.

I've done a little bit of Ruby in the past so I'm happy to prod this about and try and make it work, just not 100% sure where in the code to look, or if this is even fixable. Looking for a steer as much as anything. I also notice this code is very old, so is it potentially a dead-end to try and fix? OR, is there a better way I don't know about? Plan b is I just script this all directly in Satellite... but then the fun of stored passwords comes back again.

All help most gratefully received.

martencassel commented 5 months ago

Thanks for your issue, apprieciate it :-)

Little curios to know what version of Red Hat Satellite are you using and what distro ? :-)

martencassel commented 5 months ago

As was previously suggested as a fix in previous issues, and in the workaround you provided we lack sane error handling code in the plugin. We just call enroll.join hoping it wont give us an exception. There are no sane error handling anywhere actually.

For example here https://github.com/theforeman/smart_proxy_realm_ad_plugin/blob/450184982d430bfc2d9051c5e68da885d7e871b7/lib/smart_proxy_realm_ad/provider.rb#L104.

In the initial work for this project, i had one DC in my dev environment, but every organization run multiple DCs.

KingDaveRa commented 5 months ago

Thanks for your issue, apprieciate it :-)

Little curios to know what version of Red Hat Satellite are you using and what distro ? :-)

The Satellite server is on Satellite 6.14.2 (latest I think?) and RHEL 8.9.

I do have multiple DCs in the domain, (six actually), but the config is nailed to the PDC. I suppose it's possible it's wandering to others? AD does like going everywhere but where you ask!

So I suppose a good starting point for me might be to try and catch the errors (if at all) coming back from radcli. It's odd, because it does create the object, but maybe it's failing at the next step. I'm wondering if the password generated is complex enough perhaps, or even the right length? I suppose just because the object exists doesn't mean it was 100% successful.

martencassel commented 3 weeks ago

Thanks again for your issue, im waiting to get my test environment setup before i can test this fix. See the current PR.