Skip to content

Commit 794844f

Browse files
authored
CP-309846: Select proper AD certificate (#6975)
Select CA bundles to setup TLS connection to DC in following preference - /etc/trusted-certs/ca-bundle-ldaps.pem - /etc/trusted-certs/ca-bundle-general.pem - /etc/stunnel/certs (Legacy, will be removed with trusted certs) Raise proper error code when no certs exists
2 parents 596b991 + 0e1394a commit 794844f

6 files changed

Lines changed: 68 additions & 13 deletions

File tree

ocaml/idl/datamodel_errors.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ let _ =
754754
~doc:"The host failed to enable external authentication." () ;
755755
error Api_errors.auth_enable_failed_invalid_certs ["message"]
756756
~doc:"The host failed to enable external authentication." () ;
757+
error Api_errors.auth_enable_failed_no_certs ["message"]
758+
~doc:"The host failed to enable external authentication." () ;
757759
error Api_errors.auth_disable_failed ["message"]
758760
~doc:"The host failed to disable external authentication." () ;
759761
error Api_errors.auth_disable_failed_wrong_credentials ["message"]
@@ -845,6 +847,8 @@ let _ =
845847
~doc:"The pool failed to enable external authentication." () ;
846848
error Api_errors.pool_auth_enable_failed_invalid_certs ["host"; "message"]
847849
~doc:"The pool failed to enable external authentication." () ;
850+
error Api_errors.pool_auth_enable_failed_no_certs ["host"; "message"]
851+
~doc:"The pool failed to enable external authentication." () ;
848852
error Api_errors.auth_set_ldaps_failed ["host"; "message"]
849853
~doc:"The pool failed to set LDAPS configuration." () ;
850854
error Api_errors.pool_auth_disable_failed ["host"; "message"]

ocaml/tests/test_extauth_plugin_ADwinbind.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ module Errtag = Generic.MakeStateless (struct
9292
"E_INVALID_ACCOUNT"
9393
| E_INVALID_CERTS ->
9494
"E_INVALID_CERTS"
95+
| E_NO_CERTS ->
96+
"E_NO_CERTS"
9597
end
9698

9799
let transform = Extauth_plugin_ADwinbind.tag_from_err_msg

ocaml/xapi-consts/api_errors.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,8 @@ let auth_is_disabled = add_error "AUTH_IS_DISABLED"
10251025

10261026
let auth_invalid_certs = add_error "AUTH_INVALID_CERTS"
10271027

1028+
let auth_no_certs = add_error "AUTH_NO_CERTS"
1029+
10281030
let auth_suffix_wrong_credentials = "_WRONG_CREDENTIALS"
10291031

10301032
let auth_suffix_permission_denied = "_PERMISSION_DENIED"
@@ -1039,6 +1041,8 @@ let auth_suffix_invalid_account = "_INVALID_ACCOUNT"
10391041

10401042
let auth_suffix_invalid_certs = "_INVALID_CERTS"
10411043

1044+
let auth_suffix_no_certs = "_NO_CERTS"
1045+
10421046
let auth_enable_failed = add_error "AUTH_ENABLE_FAILED"
10431047

10441048
let auth_enable_failed_wrong_credentials =
@@ -1062,6 +1066,9 @@ let auth_enable_failed_invalid_account =
10621066
let auth_enable_failed_invalid_certs =
10631067
add_error $ auth_enable_failed ^ auth_suffix_invalid_certs
10641068

1069+
let auth_enable_failed_no_certs =
1070+
add_error $ auth_enable_failed ^ auth_suffix_no_certs
1071+
10651072
let auth_disable_failed = add_error "AUTH_DISABLE_FAILED"
10661073

10671074
let auth_disable_failed_wrong_credentials =
@@ -1097,6 +1104,9 @@ let pool_auth_enable_failed_invalid_account =
10971104
let pool_auth_enable_failed_invalid_certs =
10981105
add_error $ pool_auth_enable_failed ^ auth_suffix_invalid_certs
10991106

1107+
let pool_auth_enable_failed_no_certs =
1108+
add_error $ pool_auth_enable_failed ^ auth_suffix_no_certs
1109+
11001110
let pool_auth_enable_failed_duplicate_hostname =
11011111
add_error $ pool_auth_enable_failed ^ "_DUPLICATE_HOSTNAME"
11021112

ocaml/xapi/auth_signature.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type auth_service_error_tag =
3232
| E_INVALID_OU
3333
| E_INVALID_ACCOUNT
3434
| E_INVALID_CERTS
35+
| E_NO_CERTS
3536

3637
exception Auth_service_error of auth_service_error_tag * string
3738

@@ -55,6 +56,8 @@ let suffix_of_tag errtag =
5556
Api_errors.auth_suffix_invalid_account
5657
| E_INVALID_CERTS ->
5758
Api_errors.auth_suffix_invalid_certs
59+
| E_NO_CERTS ->
60+
Api_errors.auth_suffix_no_certs
5861

5962
(* required fields in subject.other_config *)
6063
let subject_information_field_subject_name = "subject-name"

ocaml/xapi/extauth.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ let call_with_exception_handler fn =
205205
raise (Api_errors.Server_error (Api_errors.subject_cannot_be_resolved, []))
206206
| Auth_signature.Auth_service_error (E_INVALID_CERTS, msg) ->
207207
raise (Api_errors.Server_error (Api_errors.auth_invalid_certs, [msg]))
208+
| Auth_signature.Auth_service_error (E_NO_CERTS, msg) ->
209+
raise (Api_errors.Server_error (Api_errors.auth_no_certs, [msg]))
208210
| Auth_signature.Auth_service_error (_, msg) ->
209211
raise (Api_errors.Server_error (Api_errors.auth_service_error, [msg]))
210212
| e ->

ocaml/xapi/extauth_plugin_ADwinbind.ml

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,13 @@ let auth_ex uname =
7777
let msg = Printf.sprintf "failed to authenticate user '%s'" uname in
7878
Auth_signature.(Auth_failure msg)
7979

80-
let generic_ex fmt =
80+
let gen_ex tag fmt =
8181
Printf.ksprintf
82-
(fun msg -> Auth_signature.(Auth_service_error (E_GENERIC, msg)))
82+
(fun msg -> Auth_signature.(Auth_service_error (tag, msg)))
8383
fmt
8484

85+
let generic_ex fmt = gen_ex E_GENERIC fmt
86+
8587
let net_cmd = !Xapi_globs.net_cmd
8688

8789
let wb_cmd = !Xapi_globs.wb_cmd
@@ -90,6 +92,31 @@ let tdb_tool = !Xapi_globs.tdb_tool
9092

9193
let domain_krb5_dir = Filename.concat Xapi_globs.samba_dir "lock/smb_krb5"
9294

95+
(* Legacy certificates folder *)
96+
let certs_dir = "/etc/stunnel/certs"
97+
98+
let ldaps_ca_bundle = "/etc/trusted-certs/ca-bundle-ldaps.pem"
99+
100+
let general_ca_bundle = "/etc/trusted-certs/ca-bundle-general.pem"
101+
102+
(** Return the best available CA bundle/cert path, in priority order:
103+
ldaps-specific bundle > general bundle > legacy certs dir.
104+
Returns [None] if none exist. *)
105+
106+
let ca_bundle_path () =
107+
[ldaps_ca_bundle; general_ca_bundle; certs_dir]
108+
|> List.find_opt Sys.file_exists
109+
110+
let assert_ca_exists = function
111+
| true ->
112+
ca_bundle_path ()
113+
|> Option.to_result
114+
~none:(gen_ex E_NO_CERTS "No certs to setup TLS connection to DC")
115+
|> maybe_raise
116+
|> ignore
117+
| false ->
118+
()
119+
93120
let debug_level () =
94121
clamp
95122
!Xapi_globs.winbind_debug_level
@@ -880,16 +907,10 @@ let query_domain_workgroup ~domain =
880907
let config_winbind_daemon domain_info =
881908
let smb_config = "/etc/samba/smb.conf" in
882909
let extra_conf = "/etc/samba/smb.extra.conf" in
883-
(* Will change to following config after trusted certs feature
884-
tls cafile = /etc/trusted-certs/ca-bundle-[ldaps|general].pem
885-
*)
886-
let certs_dir = "/etc/stunnel/certs" in
887910
let string_of_bool = function true -> "yes" | false -> "no" in
888-
889911
let scan_trusted_domains =
890912
string_of_bool !Xapi_globs.winbind_scan_trusted_domains
891913
in
892-
893914
( match domain_info with
894915
| Some
895916
{
@@ -902,6 +923,17 @@ let config_winbind_daemon domain_info =
902923
let ldaps_conf =
903924
match ldaps with Some true -> "ldaps" | _ -> "seal"
904925
in
926+
let tls_ca =
927+
match ca_bundle_path () with
928+
| Some path when Sys.is_directory path ->
929+
Printf.sprintf "tls ca directories = %s" path
930+
| Some path ->
931+
Printf.sprintf "tls cafile = %s" path
932+
| None ->
933+
(* Presuming assert_ca_exists is called before reach here,
934+
so ldaps is not enabled here, this item does not matter *)
935+
Printf.sprintf "tls cafile = %s" ldaps_ca_bundle
936+
in
905937
[
906938
Printf.sprintf "# This file is managed by xapi, update %s instead"
907939
extra_conf
@@ -916,10 +948,10 @@ let config_winbind_daemon domain_info =
916948
; "winbind refresh tickets = yes"
917949
; "winbind enum groups = no"
918950
; "winbind enum users = no"
919-
; Printf.sprintf "client ldap sasl wrapping= %s" ldaps_conf
951+
; Printf.sprintf "client ldap sasl wrapping = %s" ldaps_conf
920952
; "tls trust system cas = yes"
921953
; "tls verify peer = ca_and_name_if_available"
922-
; Printf.sprintf "tls ca directories = %s" certs_dir
954+
; tls_ca
923955
; Printf.sprintf "winbind scan trusted domains = %s"
924956
scan_trusted_domains
925957
; "winbind use krb5 enterprise principals = yes"
@@ -1190,7 +1222,8 @@ let set_ldaps ~__context ~ldaps ~force =
11901222
if old_domain_info.ldaps = Some ldaps && not force then
11911223
raise (generic_ex "ldaps is already %s" (string_of_bool ldaps)) ;
11921224

1193-
(* check certificate exists *)
1225+
assert_ca_exists ldaps ;
1226+
11941227
let new_domain_info = {old_domain_info with ldaps= Some ldaps} in
11951228
(* Apply new configuration to winbind daemon for trial *)
11961229
Winbind.configure ~__context ~domain_info:new_domain_info () ;
@@ -1662,7 +1695,8 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
16621695
(* Query new domain workgroup during join domain *)
16631696
query_domain_workgroup ~domain:service_name
16641697
in
1665-
let ldaps = Some (Helpers.ldaps_enabled_in_config ~config:config_params) in
1698+
let ldaps = Helpers.ldaps_enabled_in_config ~config:config_params in
1699+
assert_ca_exists ldaps ;
16661700

16671701
let ou, ou_param = extract_ou_config ~config_params in
16681702
let domain_info =
@@ -1672,7 +1706,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
16721706
; workgroup= Some workgroup
16731707
; netbios_name= Some netbios_name
16741708
; machine_pwd_last_change_time= Some (Unix.time ())
1675-
; ldaps
1709+
; ldaps= Some ldaps
16761710
; ou
16771711
}
16781712
in

0 commit comments

Comments
 (0)