-
Notifications
You must be signed in to change notification settings - Fork 292
CA-408550: XSI-1834: Host netbios name should be added to local hosts file to avoid DNS lookup #6386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CA-408550: XSI-1834: Host netbios name should be added to local hosts file to avoid DNS lookup #6386
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -828,48 +828,39 @@ let config_winbind_daemon ~workgroup ~netbios_name ~domain = | |
let conf_contents = | ||
match (workgroup, netbios_name, domain) with | ||
| Some wkgroup, Some netbios, Some dom -> | ||
String.concat "\n" | ||
[ | ||
"# auto-generated by xapi" | ||
; "[global]" | ||
; "kerberos method = secrets and keytab" | ||
; Printf.sprintf "realm = %s" dom | ||
; "security = ADS" | ||
; "template shell = /bin/bash" | ||
; "winbind refresh tickets = yes" | ||
; "winbind enum groups = no" | ||
; "winbind enum users = no" | ||
; "winbind scan trusted domains = yes" | ||
; "winbind use krb5 enterprise principals = yes" | ||
; Printf.sprintf "winbind cache time = %d" | ||
!Xapi_globs.winbind_cache_time | ||
; Printf.sprintf "machine password timeout = 0" | ||
; Printf.sprintf "kerberos encryption types = %s" | ||
(Kerberos_encryption_types.Winbind.to_string | ||
!Xapi_globs.winbind_kerberos_encryption_type | ||
) | ||
; Printf.sprintf "workgroup = %s" wkgroup | ||
; Printf.sprintf "netbios name = %s" netbios | ||
; "idmap config * : range = 3000000-3999999" | ||
; Printf.sprintf "idmap config %s: backend = rid" dom | ||
; Printf.sprintf "idmap config %s: range = 2000000-2999999" dom | ||
; Printf.sprintf "log level = %s" (debug_level ()) | ||
; Printf.sprintf "allow kerberos auth fallback = %s" allow_fallback | ||
; "idmap config * : backend = tdb" | ||
; "" (* Empty line at the end *) | ||
] | ||
[ | ||
"# autogenerated by xapi" | ||
; "[global]" | ||
; "kerberos method = secrets and keytab" | ||
; Printf.sprintf "realm = %s" dom | ||
; "security = ADS" | ||
; "template shell = /bin/bash" | ||
; "winbind refresh tickets = yes" | ||
; "winbind enum groups = no" | ||
; "winbind enum users = no" | ||
; "winbind scan trusted domains = yes" | ||
; "winbind use krb5 enterprise principals = yes" | ||
; Printf.sprintf "winbind cache time = %d" | ||
!Xapi_globs.winbind_cache_time | ||
; Printf.sprintf "machine password timeout = 0" | ||
; Printf.sprintf "kerberos encryption types = %s" | ||
(Kerberos_encryption_types.Winbind.to_string | ||
!Xapi_globs.winbind_kerberos_encryption_type | ||
) | ||
; Printf.sprintf "workgroup = %s" wkgroup | ||
; Printf.sprintf "netbios name = %s" netbios | ||
; "idmap config * : range = 3000000-3999999" | ||
; Printf.sprintf "idmap config %s: backend = rid" dom | ||
; Printf.sprintf "idmap config %s: range = 2000000-2999999" dom | ||
; Printf.sprintf "log level = %s" (debug_level ()) | ||
; Printf.sprintf "allow kerberos auth fallback = %s" allow_fallback | ||
; "idmap config * : backend = tdb" | ||
; "" (* Empty line at the end *) | ||
] | ||
| _ -> | ||
String.concat "\n" | ||
[ | ||
"# autogenerated by xapi"; "[global]"; "" (* Empty line at the end *) | ||
] | ||
["# autogenerated by xapi"; "[global]"; "" (* Empty line at the end *)] | ||
in | ||
|
||
let len = String.length conf_contents in | ||
Unixext.atomic_write_to_file smb_config 0o0644 (fun fd -> | ||
let (_ : int) = Unix.single_write_substring fd conf_contents 0 len in | ||
Unix.fsync fd | ||
) | ||
Helpers.ListFile.to_path smb_config conf_contents | ||
|
||
let clear_winbind_config () = | ||
(* Keep the winbind configuration if xapi config file specified explictly, | ||
|
@@ -1222,27 +1213,21 @@ module RotateMachinePassword = struct | |
in | ||
|
||
let conf_contents = | ||
String.concat "\n" | ||
([ | ||
"# auto-generated by xapi" | ||
; "[libdefaults]" | ||
; Printf.sprintf "default_realm = %s" realm | ||
; "[realms]" | ||
; Printf.sprintf "%s={" realm | ||
; Printf.sprintf "kpasswd_server=%s" kdc_fqdn | ||
; Printf.sprintf "kdc=%s" kdc_fqdn | ||
; "}" (* include winbind generated configure if exists *) | ||
] | ||
@ include_item | ||
@ [""] (* Empty line at the end *) | ||
) | ||
[ | ||
"# autogenerated by xapi" | ||
; "[libdefaults]" | ||
; Printf.sprintf "default_realm = %s" realm | ||
; "[realms]" | ||
; Printf.sprintf "%s={" realm | ||
; Printf.sprintf "kpasswd_server=%s" kdc_fqdn | ||
; Printf.sprintf "kdc=%s" kdc_fqdn | ||
; "}" (* include winbind generated configure if exists *) | ||
] | ||
@ include_item | ||
@ [""] | ||
(* Empty line at the end *) | ||
in | ||
|
||
let len = String.length conf_contents in | ||
Unixext.atomic_write_to_file tmp_krb5_conf 0o0644 (fun fd -> | ||
let (_ : int) = Unix.single_write_substring fd conf_contents 0 len in | ||
Unix.fsync fd | ||
) | ||
Helpers.ListFile.to_path tmp_krb5_conf conf_contents | ||
|
||
let clear_tmp_krb5_conf () = | ||
if !Xapi_globs.winbind_keep_configuration then | ||
|
@@ -1307,6 +1292,83 @@ module RotateMachinePassword = struct | |
let stop_rotate () = Scheduler.remove_from_queue task_name | ||
end | ||
|
||
module type LocalHostTag = sig | ||
val local_ip : string | ||
end | ||
|
||
module HostsConfTagIPv4 : LocalHostTag = struct let local_ip = "127.0.0.1" end | ||
|
||
module HostsConfTagIPv6 : LocalHostTag = struct let local_ip = "::1" end | ||
|
||
module type HostsConf = sig | ||
(* add the domain info into conf*) | ||
val join : name:string -> domain:string -> lines:string list -> string list | ||
|
||
(* remove the domain info from conf*) | ||
val leave : name:string -> domain:string -> lines:string list -> string list | ||
end | ||
|
||
module HostsConfFunc (T : LocalHostTag) : HostsConf = struct | ||
let sep = ' ' | ||
|
||
let sep_str = String.make 1 sep | ||
|
||
type t = Add | Remove | ||
|
||
let interest line = String.starts_with ~prefix:T.local_ip line | ||
|
||
let handle op name domain line = | ||
let line = String.lowercase_ascii line in | ||
let name = String.lowercase_ascii name in | ||
let domain = String.lowercase_ascii domain in | ||
let fqdn = Printf.sprintf "%s.%s" name domain in | ||
match interest line with | ||
| false -> | ||
line | ||
| true -> | ||
String.split_on_char sep line | ||
|> List.filter (fun x -> x <> name && x <> fqdn) | ||
|> (fun x -> match op with Add -> x @ [name; fqdn] | Remove -> x) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before we add something, should we make sure there is not previous entry for it? That is - should an addition always include a removal of any existing entry such that the new entry is the definitive one? Is that even possible? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this still work when name or fqdn changes? So: the file contains an outdated entry; and the current name or fqdn does not match the previous one. |
||
|> String.concat sep_str | ||
|
||
let leave ~name ~domain ~lines = | ||
List.map (fun line -> handle Remove name domain line) lines | ||
(* If no name for local ip left, just remove it *) | ||
|> List.filter (fun x -> String.trim x <> T.local_ip) | ||
|
||
let join ~name ~domain ~lines = | ||
List.map (fun line -> handle Add name domain line) lines |> fun x -> | ||
match List.exists (fun l -> interest l) x with | ||
| true -> | ||
x | ||
| false -> | ||
(* Does not found and updated the conf, then add one *) | ||
[ | ||
Printf.sprintf "%s%s%s%s%s.%s" T.local_ip sep_str name sep_str name | ||
domain | ||
] | ||
@ x | ||
end | ||
|
||
module HostsConfIPv4 = HostsConfFunc (HostsConfTagIPv4) | ||
module HostsConfIPv6 = HostsConfFunc (HostsConfTagIPv6) | ||
|
||
module ConfigHosts = struct | ||
let path = "/etc/hosts" | ||
|
||
let join ~name ~domain = | ||
Helpers.ListFile.of_path path | ||
|> HostsConfIPv4.join ~name ~domain | ||
|> HostsConfIPv6.join ~name ~domain | ||
|> Helpers.ListFile.to_path path | ||
|
||
let leave ~name ~domain = | ||
Helpers.ListFile.of_path path | ||
|> HostsConfIPv4.leave ~name ~domain | ||
|> HostsConfIPv6.leave ~name ~domain | ||
|> Helpers.ListFile.to_path path | ||
end | ||
|
||
let build_netbios_name ~config_params = | ||
let key = "netbios-name" in | ||
match List.assoc_opt key config_params with | ||
|
@@ -1628,18 +1690,21 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct | |
~netbios_name:(Some netbios_name) ; | ||
ClosestKdc.trigger_update ~start:0. ; | ||
RotateMachinePassword.trigger_rotate ~start:0. ; | ||
ConfigHosts.join ~domain:service_name ~name:netbios_name ; | ||
(* Trigger right now *) | ||
debug "Succeed to join domain %s" service_name | ||
with | ||
| Forkhelpers.Spawn_internal_error (_, stdout, _) -> | ||
error "Join domain: %s error: %s" service_name stdout ; | ||
clear_winbind_config () ; | ||
ConfigHosts.leave ~domain:service_name ~name:netbios_name ; | ||
(* The configure is kept for debug purpose with max level *) | ||
raise (Auth_service_error (stdout |> tag_from_err_msg, stdout)) | ||
| Xapi_systemctl.Systemctl_fail _ -> | ||
let msg = Printf.sprintf "Failed to start %s" Winbind.name in | ||
error "Start daemon error: %s" msg ; | ||
config_winbind_daemon ~domain:None ~workgroup:None ~netbios_name:None ; | ||
ConfigHosts.leave ~domain:service_name ~name:netbios_name ; | ||
raise (Auth_service_error (E_GENERIC, msg)) | ||
| e -> | ||
let msg = | ||
|
@@ -1650,6 +1715,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct | |
in | ||
error "Enable extauth error: %s" msg ; | ||
clear_winbind_config () ; | ||
ConfigHosts.leave ~domain:service_name ~name:netbios_name ; | ||
raise (Auth_service_error (E_GENERIC, msg)) | ||
|
||
(* unit on_disable() | ||
|
@@ -1663,7 +1729,14 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct | |
let@ __context = Context.with_tracing ~__context __FUNCTION__ in | ||
let user = List.assoc_opt "user" config_params in | ||
let pass = List.assoc_opt "pass" config_params in | ||
let {service_name; _} = get_domain_info_from_db () in | ||
let {service_name; workgroup; netbios_name; _} = | ||
get_domain_info_from_db () | ||
in | ||
( if Option.is_some netbios_name then | ||
Option.get netbios_name |> fun name -> | ||
ConfigHosts.leave ~domain:service_name ~name | ||
) ; | ||
liulinC marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
(* Clean extauth config *) | ||
persist_extauth_config ~domain:None ~user:None ~ou_conf:[] ~workgroup:None | ||
~machine_pwd_last_change_time:None ~netbios_name:None ; | ||
|
@@ -1688,7 +1761,14 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct | |
Winbind.start ~timeout:5. ~wait_until_success:true ; | ||
ClosestKdc.trigger_update ~start:ClosestKdc.startup_delay ; | ||
RotateMachinePassword.trigger_rotate ~start:5. ; | ||
Winbind.check_ready_to_serve ~timeout:300. | ||
Winbind.check_ready_to_serve ~timeout:300. ; | ||
|
||
let {service_name; workgroup; netbios_name; _} = | ||
get_domain_info_from_db () | ||
in | ||
if Option.is_some netbios_name then | ||
Option.get netbios_name |> fun name -> | ||
ConfigHosts.join ~domain:service_name ~name | ||
|
||
(* unit on_xapi_exit() | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.