Skip to content

Commit 3afd88a

Browse files
authored
CP-309972: Configurable between ldap and ldaps during join domain (#6934)
2 parents c3e54bc + e300f70 commit 3afd88a

4 files changed

Lines changed: 125 additions & 55 deletions

File tree

ocaml/tests/test_extauth_plugin_ADwinbind.ml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,25 @@ module ExtractOuConfig = Generic.MakeStateless (struct
1818
module Io = struct
1919
type input_t = (string * string) list
2020

21-
type output_t = (string * string) list * string list
21+
type output_t = string option * string list
2222

2323
let string_of_input_t = Test_printers.(assoc_list string string)
2424

25-
let string_of_output_t =
26-
Test_printers.(pair (assoc_list string string) (list string))
25+
let string_of_output_t = Test_printers.(pair (option string) (list string))
2726
end
2827

2928
let transform x = Extauth_plugin_ADwinbind.extract_ou_config ~config_params:x
3029

3130
let tests =
3231
`QuickAndAutoDocumented
3332
[
34-
([("auth-type", "AD"); ("service-name", "conappada.local")], ([], []))
33+
([("auth-type", "AD"); ("service-name", "conappada.local")], (None, []))
3534
; ( [
3635
("auth-type", "AD")
3736
; ("service-name", "conappada.local")
3837
; ("ou", "TOU")
3938
]
40-
, ([("ou", "TOU")], ["createcomputer=TOU"])
39+
, (Some "TOU", ["createcomputer=TOU"])
4140
)
4241
]
4342
end)

ocaml/xapi/extauth_plugin_ADwinbind.ml

Lines changed: 112 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,14 @@ let err_msg_to_tag_map =
8989

9090
type domain_info = {
9191
service_name: string
92+
; user: string
9293
; workgroup: string option
9394
(* For upgrade case, the legacy db does not contain workgroup *)
9495
; netbios_name: string option
9596
(* Persist netbios_name to support hostname change *)
97+
; ldaps: bool (* Use ldaps instead of ldap *)
9698
; machine_pwd_last_change_time: float option
99+
; ou: string option
97100
}
98101

99102
let generic_error msg =
@@ -196,16 +199,25 @@ let get_domain_info_from_db () =
196199
let service_name =
197200
Db.Host.get_external_auth_service_name ~__context ~self:host
198201
in
199-
let workgroup, netbios_name, machine_pwd_last_change_time =
200-
Db.Host.get_external_auth_configuration ~__context ~self:host
201-
|> fun config ->
202-
( List.assoc_opt "workgroup" config
203-
, List.assoc_opt "netbios_name" config
204-
, List.assoc_opt "machine_pwd_last_change_time" config
205-
|> Option.map (fun s -> float_of_string s)
206-
)
202+
let config = Db.Host.get_external_auth_configuration ~__context ~self:host in
203+
let user = List.assoc "user" config in
204+
let workgroup = List.assoc_opt "workgroup" config in
205+
let netbios_name = List.assoc_opt "netbios_name" config in
206+
let machine_pwd_last_change_time =
207+
List.assoc_opt "machine_pwd_last_change_time" config
208+
|> Option.map (fun s -> float_of_string s)
207209
in
208-
{service_name; workgroup; netbios_name; machine_pwd_last_change_time}
210+
let ldaps = Helpers.ldaps_enabled_in_config ~config in
211+
let ou = List.assoc_opt "ou" config in
212+
{
213+
service_name
214+
; user
215+
; workgroup
216+
; netbios_name
217+
; ldaps
218+
; machine_pwd_last_change_time
219+
; ou
220+
}
209221

210222
let update_extauth_configuration ~__context ~k ~v =
211223
let self = Helpers.get_localhost ~__context in
@@ -778,16 +790,29 @@ let query_domain_workgroup ~domain =
778790
workgroup_from_server kdc |> Result.get_ok
779791
with _ -> raise (Auth_service_error (E_LOOKUP, err_msg))
780792

781-
let config_winbind_daemon ~workgroup ~netbios_name ~domain =
793+
let config_winbind_daemon domain_info =
782794
let smb_config = "/etc/samba/smb.conf" in
783795
let extra_conf = "/etc/samba/smb.extra.conf" in
796+
(* Will change to following config after trusted certs feature
797+
tls cafile = /etc/trusted-certs/ca-bundle-[ldaps|general].pem
798+
*)
799+
let certs_dir = "/etc/stunnel/certs" in
784800
let string_of_bool = function true -> "yes" | false -> "no" in
785801

786802
let scan_trusted_domains =
787803
string_of_bool !Xapi_globs.winbind_scan_trusted_domains
788804
in
789-
( match (workgroup, netbios_name, domain) with
790-
| Some wkgroup, Some netbios, Some dom ->
805+
806+
( match domain_info with
807+
| Some
808+
{
809+
service_name= dom
810+
; workgroup= Some wkgroup
811+
; netbios_name= Some netbios
812+
; ldaps
813+
; _
814+
} ->
815+
let ldaps_conf = match ldaps with true -> "ldaps" | _ -> "seal" in
791816
[
792817
Printf.sprintf "# This file is managed by xapi, update %s instead"
793818
extra_conf
@@ -802,6 +827,10 @@ let config_winbind_daemon ~workgroup ~netbios_name ~domain =
802827
; "winbind refresh tickets = yes"
803828
; "winbind enum groups = no"
804829
; "winbind enum users = no"
830+
; Printf.sprintf "client ldap sasl wrapping= %s" ldaps_conf
831+
; "tls trust system cas = yes"
832+
; "tls verify peer = ca_and_name_if_available"
833+
; Printf.sprintf "tls ca directories = %s" certs_dir
805834
; Printf.sprintf "winbind scan trusted domains = %s"
806835
scan_trusted_domains
807836
; "winbind use krb5 enterprise principals = yes"
@@ -832,7 +861,7 @@ let clear_winbind_config () =
832861
if !Xapi_globs.winbind_keep_configuration then
833862
()
834863
else
835-
config_winbind_daemon ~workgroup:None ~netbios_name:None ~domain:None
864+
config_winbind_daemon None
836865

837866
let from_config ~name ~err_msg ~config_params =
838867
match List.assoc_opt name config_params with
@@ -865,26 +894,44 @@ let assert_domain_equal_service_name ~service_name ~config_params =
865894
let extract_ou_config ~config_params =
866895
try
867896
let ou = from_config ~name:"ou" ~err_msg:"" ~config_params in
868-
([("ou", ou)], [Printf.sprintf "createcomputer=%s" ou])
869-
with Auth_service_error _ -> ([], [])
897+
(Some ou, [Printf.sprintf "createcomputer=%s" ou])
898+
with Auth_service_error _ -> (None, [])
870899

871-
let persist_extauth_config ~domain ~user ~ou_conf ~workgroup ~netbios_name
872-
~machine_pwd_last_change_time =
900+
let persist_extauth_config ~domain_info =
873901
let value =
874-
match
875-
(domain, user, workgroup, netbios_name, machine_pwd_last_change_time)
876-
with
877-
| Some dom, Some u, Some wkg, Some netbios, Some pwd_time ->
902+
match domain_info with
903+
| None ->
904+
[]
905+
| Some
906+
{
907+
service_name
908+
; user
909+
; workgroup
910+
; netbios_name
911+
; machine_pwd_last_change_time
912+
; ldaps
913+
; ou
914+
} -> (
878915
[
879-
("domain", dom)
880-
; ("user", u)
881-
; ("workgroup", wkg)
882-
; ("netbios_name", netbios)
883-
; ("machine_pwd_last_change_time", pwd_time)
916+
("domain", service_name)
917+
; ("user", user)
918+
; ("ldaps", string_of_bool ldaps)
884919
]
885-
@ ou_conf
886-
| _ ->
887-
[]
920+
@ (match workgroup with Some w -> [("workgroup", w)] | None -> [])
921+
@ ( match netbios_name with
922+
| Some n ->
923+
[("netbios_name", n)]
924+
| None ->
925+
[]
926+
)
927+
@ (match ou with Some o -> [("ou", o)] | None -> [])
928+
@
929+
match machine_pwd_last_change_time with
930+
| Some t ->
931+
[("machine_pwd_last_change_time", string_of_float t)]
932+
| None ->
933+
[]
934+
)
888935
in
889936
Server_helpers.exec_with_new_task "update external_auth_configuration"
890937
@@ fun __context ->
@@ -970,28 +1017,34 @@ module Winbind = struct
9701017
let configure ~__context =
9711018
(* Refresh winbind configuration to handle upgrade from PBIS
9721019
* The winbind configuration needs to be refreshed before start winbind daemon *)
973-
let {service_name; workgroup; netbios_name; _} =
974-
get_domain_info_from_db ()
975-
in
1020+
let domain_info = get_domain_info_from_db () in
9761021
let netbios_name =
977-
match netbios_name with
1022+
match domain_info.netbios_name with
9781023
| None ->
9791024
Migrate_from_pbis.migrate_netbios_name ~__context
9801025
| Some name ->
9811026
name
9821027
in
9831028
let workgroup =
984-
match workgroup with
1029+
match domain_info.workgroup with
9851030
| None ->
986-
let workgroup = query_domain_workgroup ~domain:service_name in
1031+
let workgroup =
1032+
query_domain_workgroup ~domain:domain_info.service_name
1033+
in
9871034
(* Persist the workgroup to avoid lookup again on next startup *)
9881035
update_workgroup ~__context ~workgroup ;
9891036
workgroup
9901037
| Some workgroup ->
9911038
workgroup
9921039
in
993-
config_winbind_daemon ~domain:(Some service_name)
994-
~workgroup:(Some workgroup) ~netbios_name:(Some netbios_name)
1040+
let domain_info =
1041+
{
1042+
domain_info with
1043+
netbios_name= Some netbios_name
1044+
; workgroup= Some workgroup
1045+
}
1046+
in
1047+
config_winbind_daemon (Some domain_info)
9951048

9961049
let init_service ~__context =
9971050
if is_ad_enabled ~__context then (
@@ -1527,17 +1580,32 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
15271580

15281581
assert_hostname_valid ~hostname:netbios_name ;
15291582

1530-
let {service_name; _} = get_domain_info_from_db () in
1583+
let service_name =
1584+
Helpers.get_localhost ~__context |> fun self ->
1585+
Db.Host.get_external_auth_service_name ~__context ~self
1586+
in
15311587
assert_domain_equal_service_name ~service_name ~config_params ;
15321588

15331589
let workgroup =
15341590
(* Query new domain workgroup during join domain *)
15351591
query_domain_workgroup ~domain:service_name
15361592
in
1537-
config_winbind_daemon ~domain:(Some service_name)
1538-
~workgroup:(Some workgroup) ~netbios_name:(Some netbios_name) ;
1593+
let ldaps = Helpers.ldaps_enabled_in_config ~config:config_params in
1594+
1595+
let ou, ou_param = extract_ou_config ~config_params in
1596+
let domain_info =
1597+
{
1598+
service_name
1599+
; user
1600+
; workgroup= Some workgroup
1601+
; netbios_name= Some netbios_name
1602+
; machine_pwd_last_change_time= Some (Unix.time ())
1603+
; ldaps
1604+
; ou
1605+
}
1606+
in
15391607

1540-
let ou_conf, ou_param = extract_ou_config ~config_params in
1608+
config_winbind_daemon (Some domain_info) ;
15411609

15421610
let args =
15431611
[
@@ -1563,11 +1631,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
15631631
(* Need to restart to refresh cache *)
15641632
Winbind.restart ~timeout:5. ~wait_until_success:true ;
15651633
Winbind.check_ready_to_serve ~timeout:300. ;
1566-
let machine_pwd_last_change_time = Unix.time () |> string_of_float in
1567-
persist_extauth_config ~domain:(Some service_name) ~user:(Some user)
1568-
~ou_conf ~workgroup:(Some workgroup)
1569-
~machine_pwd_last_change_time:(Some machine_pwd_last_change_time)
1570-
~netbios_name:(Some netbios_name) ;
1634+
persist_extauth_config ~domain_info:(Some domain_info) ;
15711635
(* Trigger right now *)
15721636
RotateMachinePassword.trigger_rotate ~start:0. ;
15731637
ConfigHosts.join ~domain:service_name ~name:netbios_name ;
@@ -1588,7 +1652,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
15881652
| Xapi_systemctl.Systemctl_fail _ ->
15891653
let msg = Printf.sprintf "Failed to start %s" Winbind.name in
15901654
error "Start daemon error: %s" msg ;
1591-
config_winbind_daemon ~domain:None ~workgroup:None ~netbios_name:None ;
1655+
config_winbind_daemon None ;
15921656
ConfigHosts.leave ~domain:service_name ~name:netbios_name ;
15931657
raise (Auth_service_error (E_GENERIC, msg))
15941658
| e ->
@@ -1623,8 +1687,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
16231687
) ;
16241688

16251689
(* Clean extauth config *)
1626-
persist_extauth_config ~domain:None ~user:None ~ou_conf:[] ~workgroup:None
1627-
~machine_pwd_last_change_time:None ~netbios_name:None ;
1690+
persist_extauth_config ~domain_info:None ;
16281691
RotateMachinePassword.stop_rotate () ;
16291692
(* The caller disable external auth even disable machine account failed,
16301693
* We run clear_machine_account after some necessary resources get cleared *)

ocaml/xapi/extauth_plugin_ADwinbind.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module AuthADWinbind : sig val methods : Auth_signature.t end
3434

3535
(* Expose function to make compiler happy for unittest *)
3636
val extract_ou_config :
37-
config_params:(string * string) list -> (string * string) list * string list
37+
config_params:(string * string) list -> string option * string list
3838

3939
val domainify_uname : domain:string -> string -> string
4040

ocaml/xapi/helpers.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,3 +2466,11 @@ module AuthenticationCache = struct
24662466
None
24672467
end
24682468
end
2469+
2470+
let ldaps_enabled_in_config ~config =
2471+
match List.assoc_opt "ldaps" config with
2472+
(* Default to false, true iff v = true (case-insensitive) *)
2473+
| Some v when bool_of_string_opt (String.lowercase_ascii v) = Some true ->
2474+
true
2475+
| _ ->
2476+
false

0 commit comments

Comments
 (0)