Skip to content

Commit 936f9c2

Browse files
Lin Liurobhoes
authored andcommitted
XSI-2088: CA-422080: Code refine for comments
- Protect domain_netbios_name_map with Automic - Some other minor update Signed-off-by: Lin Liu <[email protected]> (cherry picked from commit 525daf6)
1 parent c7954f0 commit 936f9c2

File tree

2 files changed

+45
-41
lines changed

2 files changed

+45
-41
lines changed

ocaml/xapi/extauth_plugin_ADwinbind.ml

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,15 @@ let ( <!> ) x f = Rresult.R.reword_error f x
3636

3737
let ( >>| ) = Rresult.( >>| )
3838

39+
let min_debug_level = 0
40+
3941
let max_debug_level = 10
4042

4143
let default_debug_level = 2
4244

45+
let clamp v ~low ~high ~default =
46+
match v with n when n >= low && n <= high -> n | _ -> default
47+
4348
let maybe_raise (x : ('a, exn) result) : 'a =
4449
match x with Ok x -> x | Error e -> raise e
4550

@@ -69,13 +74,10 @@ let tdb_tool = !Xapi_globs.tdb_tool
6974

7075
let domain_krb5_dir = Filename.concat Xapi_globs.samba_dir "lock/smb_krb5"
7176

72-
let debug_level =
73-
( match !Xapi_globs.winbind_debug_level with
74-
| n when n >= 0 && n <= max_debug_level ->
75-
n
76-
| _ ->
77-
default_debug_level
78-
)
77+
let debug_level () =
78+
clamp
79+
!Xapi_globs.winbind_debug_level
80+
~low:min_debug_level ~high:max_debug_level ~default:default_debug_level
7981
|> string_of_int
8082

8183
let err_msg_to_tag_map =
@@ -108,8 +110,11 @@ let is_samba_updated =
108110
let kerberos_opt =
109111
match is_samba_updated with true -> [] | false -> ["--kerberos"]
110112

111-
(* Global cache for netbios name to domain name mapping *)
112-
let domain_netbios_name_map : (string, string) Hashtbl.t = Hashtbl.create 10
113+
(* Global cache for netbios name to domain name mapping using atomic map for thread safety *)
114+
module StringMap = Map.Make (String)
115+
116+
let domain_netbios_name_map : string StringMap.t Atomic.t =
117+
Atomic.make StringMap.empty
113118

114119
let krb5_conf_path ~domain_netbios =
115120
Filename.concat domain_krb5_dir (Printf.sprintf "krb5.conf.%s" domain_netbios)
@@ -414,7 +419,7 @@ module Ldap = struct
414419
; "sid"
415420
; sid
416421
; "-d"
417-
; debug_level
422+
; debug_level ()
418423
; "--server"
419424
; kdc
420425
; "--machine-pass"
@@ -438,7 +443,7 @@ module Ldap = struct
438443
domain_netbios
439444
in
440445
let args =
441-
["ads"; "search"; "-d"; debug_level; "--machine-pass"; query; key]
446+
["ads"; "search"; "-d"; debug_level (); "--machine-pass"; query; key]
442447
in
443448
try
444449
Helpers.call_script ~env !Xapi_globs.net_cmd args
@@ -452,7 +457,7 @@ module Ldap = struct
452457
(* Escape name to avoid injection detection *)
453458
let query = Printf.sprintf "(|(sAMAccountName=%s)(name=%s))" name name in
454459
let args =
455-
["ads"; "search"; "-d"; debug_level; "--server"; kdc; "--machine-pass"]
460+
["ads"; "search"; "-d"; debug_level (); "--server"; kdc; "--machine-pass"]
456461
@ kerberos_opt
457462
@ [query; key]
458463
in
@@ -741,7 +746,7 @@ end
741746
let kdcs_of_domain domain =
742747
try
743748
Helpers.call_script ~log_output:On_failure net_cmd
744-
(["lookup"; "kdc"; domain; "-d"; debug_level] @ kerberos_opt)
749+
(["lookup"; "kdc"; domain; "-d"; debug_level ()] @ kerberos_opt)
745750
(* Result like 10.71.212.25:88\n10.62.1.25:88\n*)
746751
|> String.split_on_char '\n'
747752
|> List.filter (fun x -> String.trim x <> "") (* Remove empty lines *)
@@ -755,7 +760,9 @@ let workgroup_from_server kdc =
755760
let key = "Pre-Win2k Domain" in
756761
try
757762
Helpers.call_script ~log_output:On_failure net_cmd
758-
(["ads"; "lookup"; "-S"; KDC.server kdc; "-d"; debug_level] @ kerberos_opt)
763+
(["ads"; "lookup"; "-S"; KDC.server kdc; "-d"; debug_level ()]
764+
@ kerberos_opt
765+
)
759766
|> Xapi_cmd_result.of_output ~sep:':' ~key
760767
|> Result.ok
761768
with _ ->
@@ -829,8 +836,8 @@ let config_winbind_daemon ~workgroup ~netbios_name ~domain =
829836
; Printf.sprintf "workgroup = %s" wkgroup
830837
; Printf.sprintf "netbios name = %s" netbios
831838
; "idmap config * : backend = autorid"
832-
; "idmap config * : range = 2000000-99999999"
833-
; Printf.sprintf "log level = %s" debug_level
839+
; Printf.sprintf "idmap config * : range = %d-%d" 2_000_000 99_999_999
840+
; Printf.sprintf "log level = %s" (debug_level ())
834841
; "" (* Empty line at the end *)
835842
]
836843
| _ ->
@@ -910,7 +917,9 @@ let clear_machine_account ~service_name = function
910917
| Some u, Some p -> (
911918
(* Disable machine account in DC *)
912919
let env = [|Printf.sprintf "PASSWD=%s" p|] in
913-
let args = ["ads"; "leave"; "-U"; u; "-d"; debug_level] @ kerberos_opt in
920+
let args =
921+
["ads"; "leave"; "-U"; u; "-d"; debug_level ()] @ kerberos_opt
922+
in
914923
try
915924
Helpers.call_script ~env net_cmd args |> ignore ;
916925
debug "Succeed to clear the machine account for domain %s" service_name
@@ -1079,7 +1088,7 @@ module Winbind = struct
10791088
; "set"
10801089
; "--machine-pass"
10811090
; "-d"
1082-
; debug_level
1091+
; debug_level ()
10831092
; Printf.sprintf "%s$" netbios_name
10841093
; Printf.sprintf "%d"
10851094
(Kerberos_encryption_types.Winbind.to_encoding
@@ -1305,26 +1314,33 @@ let domain_name_of_netbios netbios =
13051314
(*
13061315
* Query the domain name from netbios name with caching
13071316
* Check cache first, if not found, perform LDAP query and cache the result
1317+
* Thread-safe using atomic map
13081318
*)
1309-
match Hashtbl.find_opt domain_netbios_name_map netbios with
1319+
let cache_domain netbios domain_name current_map =
1320+
let new_map = StringMap.add netbios domain_name current_map in
1321+
if Atomic.compare_and_set domain_netbios_name_map current_map new_map = true
1322+
then (* Just ignore it if update fail, as it will be cached next time *)
1323+
debug "Cached netbios '%s' -> domain '%s'" netbios domain_name
1324+
in
1325+
1326+
let current_map = Atomic.get domain_netbios_name_map in
1327+
match StringMap.find_opt netbios current_map with
13101328
| Some domain_name ->
13111329
debug "Cache hit for netbios '%s' -> domain '%s'" netbios domain_name ;
13121330
Ok domain_name
13131331
| None -> (
13141332
let {service_name; workgroup; _} = get_domain_info_from_db () in
13151333
match netbios = Option.value workgroup ~default:"" with
13161334
| true ->
1317-
Hashtbl.replace domain_netbios_name_map netbios service_name ;
1318-
debug "Cached netbios '%s' -> domain '%s' as joined domain" netbios
1319-
service_name ;
1335+
cache_domain netbios service_name current_map ;
1336+
debug "Netbios '%s' is the joined domain" netbios ;
13201337
Ok service_name (* It is joined domain *)
13211338
| false ->
13221339
debug "Cache miss for netbios '%s', performing LDAP query" netbios ;
13231340
let result = Ldap.query_trusted_domain_name netbios in
13241341
( match result with
13251342
| Ok domain_name ->
1326-
Hashtbl.replace domain_netbios_name_map netbios domain_name ;
1327-
debug "Cached netbios '%s' -> domain '%s'" netbios domain_name
1343+
cache_domain netbios domain_name current_map
13281344
| Error _ ->
13291345
debug "Failed to query domain name for netbios '%s'" netbios
13301346
) ;
@@ -1358,7 +1374,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
13581374
)
13591375
in
13601376
(* Query kdc of the domain, so user in trusted domain is supported as well *)
1361-
let* kdc = Wbinfo.kdc_of_domain (Result.get_ok domain) in
1377+
let* kdc = Wbinfo.kdc_of_domain (domain |> maybe_raise) in
13621378
Ldap.query_sid ~name ~kdc
13631379

13641380
(* subject_id get_subject_identifier(string subject_name)
@@ -1442,18 +1458,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
14421458
let sam_uname = user_name in
14431459
let* domain_netbios, user = user_of_sam user_name in
14441460
(* permit unnkown domain if ldap query failed, update subject task will update it later *)
1445-
let unkown_domain = "Unkown_domain" in
1446-
let domain =
1447-
match domain_name_of_netbios domain_netbios with
1448-
| Ok domain_name ->
1449-
Some domain_name
1450-
| Error _ ->
1451-
debug
1452-
"Failed to query domain name for netbios '%s', using '%s as \
1453-
fallback"
1454-
domain_netbios unkown_domain ;
1455-
None
1456-
in
1461+
let domain = domain_name_of_netbios domain_netbios |> Result.to_option in
14571462
let default_account =
14581463
Ldap.
14591464
{
@@ -1512,8 +1517,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
15121517
, if upn <> "" then
15131518
upn
15141519
else
1515-
Printf.sprintf "%s@%s" user
1516-
(Option.value domain ~default:unkown_domain)
1520+
Printf.sprintf "%s@%s" user (Option.value domain ~default:"unknown")
15171521
)
15181522
; ("subject-account-disabled", string_of_bool account_disabled)
15191523
; ("subject-account-locked", string_of_bool account_locked)
@@ -1622,7 +1626,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
16221626
; "-n"
16231627
; netbios_name
16241628
; "-d"
1625-
; debug_level
1629+
; debug_level ()
16261630
; "--no-dns-updates"
16271631
]
16281632
@ kerberos_opt

ocaml/xapi/xapi_globs.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1631,7 +1631,7 @@ let other_options =
16311631
; ( "winbind_scan_trusted_domains"
16321632
, Arg.Set winbind_scan_trusted_domains
16331633
, (fun () -> string_of_bool !winbind_scan_trusted_domains)
1634-
, "Whether periodically scan for new trusted domains"
1634+
, "Whether to periodically scan trusted domains"
16351635
)
16361636
; ( "winbind_keep_configuration"
16371637
, Arg.Set winbind_keep_configuration

0 commit comments

Comments
 (0)