Open wiad opened 4 years ago
@wiad Could you attach the error log from the plugin ?
Does not say much (tried with DEBUG in foreman-proxy settings but that does not give any more regarding the error).
Adding realm to a host with existing computer account in AD:
2019-10-25T08:50:49 22bd6506 [I] Started POST /AD.EXAMPLE.COM/
2019-10-25T08:50:49 22bd6506 [I] Proxy::AdRealm: initialize...
2019-10-25T08:50:49 22bd6506 [I] Proxy::AdRealm: create... AD.EXAMPLE.COM, lxserv1105.example.com, {"update"=>"true", "hostname"=>"lxserv1105.example.com", "userclass"=>"tfolinux/ELIN/UTV", "splat"=>[], "captures"=>["AD.EXAMPLE.COM"], "realm"=>"AD.EXAMPLE.COM"}
2019-10-25T08:50:49 22bd6506 [E] The computer account LXSERV1105 already exists
2019-10-25T08:50:49 22bd6506 [I] Finished POST /AD.EXAMPLE.COM/ with 400 (217.16 ms)
I have applied the workaround for Authentication error
errors described in #20, not sure if that could have something to do with this?
I'm pretty certain that the problem with the computer account missing service principals is related to #20 . It is obvious from the logs when the join
succeeds directly and when the workaround kicks in and starts to loop/sleep. If the join
works as intended the serviceprincipal attributes are added, otherwise not.
So the issue with missing attributes in the computer account seems solved in #20 by getting the latest radcli from source.
That leaves the question why the plugin (or radcli?) errors out when there is an existing computer account created by another tool? When comparing accounts created with msktutil (our old accounts) and foremans realm-plugin I can't really see any major differences.
So, the error message The computer account %s already exists
originates from adcli
and it's function validate_computer_account
. This function takes a parameter allow_overwrite
as argument, and if this is false/0 then we get this error message if the account already exists. So to make the realm_ad plugin work with existing computer accounts, which would be very very nice, we need to pass the ADCLI_ENROLL_ALLOW_OVERWRITE
flag to adcli somehow - i'm guessing in radcli (function radenroll_join
, where the flag ADCLI_ENROLL_NO_KEYTAB
is already passed)?
Not really sure how to do this myself in C though.
I added the ADCLI_ENROLL_ALLOW_OVERWRITE
flag in radcli and then I can add the realm to a host with an existing computer account without the plugin/adcli erroring out. However, this also means that adcli
proceeds to update the account which renders the existing host keytab on the server useless.
Not sure how to solve this, I just want it to acknowledge that there already is an account and not do anything else but I don't know if that is possible.
When I was looking at this issue last year, the plugin did not allow this. I modified the code and added an option 'ignore_computername_exists', which, if present, will simply skip the 'join' command if the account already exists in AD. I'm not too familiar with ruby, so I never thought to submit a pull request for this.
Modified radcli_join
function in provider.rb
. Note that this code includes a manual patch to resolve issues with joining to domains with multiple DCs:
def radcli_join(hostfqdn, computername, password)
# Join computer
enroll = Adcli::AdEnroll.new(@adconn)
enroll.set_computer_name(computername)
enroll.set_host_fqdn(hostfqdn)
enroll.set_domain_ou(@ou) if @ou
enroll.set_computer_password(password)
begin
enroll.join
return true
rescue RuntimeError => ex
# raise ex unless ex.message =~ /Authentication error/
if 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
#
elsif ex.message =~ /already exists/
if ignore_computername_exists
return true
else
raise ex
end
else
raise ex
end
end
end
Modified the attr_reader
in provider.rb
to include the new option:
attr_reader :realm, :keytab_path, :principal, :domain_controller, :domain, :ou, :computername_prefix, :computername_hash, :computername_use_fqdn, :ignore_computername_exists
Added the line below to the initialize
section in provider.rb
:
@ignore_computername_exists = options.fetch(:ignore_computername_exists, false)
Added the below to settings.d/realm_ad.yml
# Optional: Ignore computer account already exists error (should only be used for computers already joined to Active Directory)
:ignore_computername_exists: true
Again, I don't do ruby so there may be issues with the code though, so please verify in a test environment first.
EDIT:
I believe the following line should be added to configuration_loader.rb
, but was not when I did this over a year ago.
ignore_computername_exists: settings[:ignore_computername_exists]
Thank you @Dragonpark , I tested your workaround and it works! (i didn't bother with making ignore_computername_exists
configurable so I can't say if those parts of the code works, but if this is turned into a PR I guess it might be a good idea to include that. )
I think that was the intent, so I may end up doing so. I believe I added it as there were hosts that were already joined to AD and I wanted that to be reflected in Satellite. This way I could temporarily enable the option as needed and then disable it again.
Sent with GitHawk
When i create a new host in Foreman a new computer account is set up with a couple of serviceprincipals:
This is all good and gives us a usable keytab file on my server.
BUT if I try to reinstall or apply the realm to an existing host the realm plugin errors out with
The computer account already exists
, even though the account used by the plugin to interact with AD has complete permissions in the OU where the account resides.Furthermore, if I delete the computer account and try the above again the plugin creates a new account, but it is missing the
servicePrincipalName
attributes which results in an incomplete keytab on the server.