@@ -1347,13 +1347,28 @@ module HostsConfFunc (T : LocalHostTag) : HostsConf = struct
1347
1347
let name = String. lowercase_ascii name in
1348
1348
let domain = String. lowercase_ascii domain in
1349
1349
let fqdn = Printf. sprintf " %s.%s" name domain in
1350
+ let rec add_hostname pre line =
1351
+ match line with
1352
+ | ip :: alias when ip = T. local_ip ->
1353
+ (* Add localhost IP *)
1354
+ add_hostname [ip] alias
1355
+ | sp :: left when sp = " " ->
1356
+ (* Add space to reserve the indent *)
1357
+ add_hostname (pre @ [sp]) left
1358
+ | alias :: left ->
1359
+ (* hosts entry: ip fqdn alias1 alias2 ... *)
1360
+ pre @ [fqdn; name; alias] @ left
1361
+ | [] ->
1362
+ failwith " Can not add local hostname to non local IP"
1363
+ in
1364
+
1350
1365
match interest line with
1351
1366
| false ->
1352
1367
line
1353
1368
| true ->
1354
1369
String. split_on_char sep line
1355
1370
|> List. filter (fun x -> x <> name && x <> fqdn)
1356
- |> (fun x -> match op with Add -> x @ [name; fqdn] | Remove -> x)
1371
+ |> (fun x -> match op with Add -> add_hostname [] x | Remove -> x)
1357
1372
|> String. concat sep_str
1358
1373
1359
1374
let leave ~name ~domain ~lines =
@@ -1369,8 +1384,8 @@ module HostsConfFunc (T : LocalHostTag) : HostsConf = struct
1369
1384
| false ->
1370
1385
(* Does not found and updated the conf, then add one *)
1371
1386
[
1372
- Printf. sprintf " %s%s%s%s%s. %s" T. local_ip sep_str name sep_str name
1373
- domain
1387
+ Printf. sprintf " %s%s%s. %s%s%s" T. local_ip sep_str name domain sep_str
1388
+ name
1374
1389
]
1375
1390
@ x
1376
1391
end
@@ -1386,18 +1401,90 @@ module ConfigHosts = struct
1386
1401
let join ~name ~domain =
1387
1402
read_lines ~path |> fun lines ->
1388
1403
HostsConfIPv4. join ~name ~domain ~lines |> fun lines ->
1389
- HostsConfIPv6. join ~name ~domain ~lines
1404
+ HostsConfIPv6. join ~name ~domain ~lines |> fun x ->
1405
+ x @ [" " ] (* Add final line break *)
1390
1406
|> String. concat " \n "
1391
1407
|> write_string_to_file path
1392
1408
1393
1409
let leave ~name ~domain =
1394
1410
read_lines ~path |> fun lines ->
1395
1411
HostsConfIPv4. leave ~name ~domain ~lines |> fun lines ->
1396
- HostsConfIPv6. leave ~name ~domain ~lines
1412
+ HostsConfIPv6. leave ~name ~domain ~lines |> fun x ->
1413
+ x @ [" " ] (* Add final line break *)
1397
1414
|> String. concat " \n "
1398
1415
|> write_string_to_file path
1399
1416
end
1400
1417
1418
+ module ResolveConfig = struct
1419
+ let path = " /etc/resolv.conf"
1420
+
1421
+ type t = Add | Remove
1422
+
1423
+ let handle op domain =
1424
+ let open Xapi_stdext_unix.Unixext in
1425
+ let config = Printf. sprintf " search %s" domain in
1426
+ read_lines ~path |> List. filter (fun x -> x <> config) |> fun x ->
1427
+ (match op with Add -> config :: x | Remove -> x) |> fun x ->
1428
+ x @ [" " ] |> String. concat " \n " |> write_string_to_file path
1429
+
1430
+ let join ~domain = handle Add domain
1431
+
1432
+ let leave ~domain = handle Remove domain
1433
+ end
1434
+
1435
+ module DNSSync = struct
1436
+ let task_name = " Sync hostname with DNS"
1437
+
1438
+ type t = Register | Unregister
1439
+
1440
+ let handle op hostname netbios_name domain =
1441
+ (* By default, hostname should equal to netbios_name, just register it to DNS server*)
1442
+ try
1443
+ let ops =
1444
+ match op with Register -> " register" | Unregister -> " unregister"
1445
+ in
1446
+ let netbios_fqdn = Printf. sprintf " %s.%s" netbios_name domain in
1447
+ let args = [" ads" ; " dns" ] @ [ops] @ [" --machine-pass" ] in
1448
+ Helpers. call_script net_cmd (args @ [netbios_fqdn]) |> ignore ;
1449
+ if hostname <> netbios_name then
1450
+ let hostname_fqdn = Printf. sprintf " %s.%s" hostname domain in
1451
+ (* netbios_name is compressed, op on extra hostname *)
1452
+ Helpers. call_script net_cmd (args @ [hostname_fqdn]) |> ignore
1453
+ with e ->
1454
+ debug " Register/unregister with DNS failed %s" (ExnHelper. string_of_exn e)
1455
+
1456
+ let register hostname netbios_name domain =
1457
+ handle Register hostname netbios_name domain
1458
+
1459
+ let unregister hostname netbios_name domain =
1460
+ handle Unregister hostname netbios_name domain
1461
+
1462
+ let sync () =
1463
+ Server_helpers. exec_with_new_task " sync hostname with DNS"
1464
+ @@ fun __context ->
1465
+ let host = Helpers. get_localhost ~__context in
1466
+ let service_name =
1467
+ Db.Host. get_external_auth_service_name ~__context ~self: host
1468
+ in
1469
+ let netbios_name =
1470
+ Db.Host. get_external_auth_configuration ~__context ~self: host
1471
+ |> fun config -> List. assoc_opt " netbios_name" config
1472
+ in
1473
+ let hostname = Db.Host. get_hostname ~__context ~self: host in
1474
+ match netbios_name with
1475
+ | Some netbios ->
1476
+ register hostname netbios service_name
1477
+ | None ->
1478
+ debug " Netbios name is none, skip sync hostname to DNS"
1479
+
1480
+ let trigger_sync ~start =
1481
+ debug " Trigger task: %s" task_name ;
1482
+ Scheduler. add_to_queue task_name
1483
+ (Scheduler. Periodic ! Xapi_globs. winbind_dns_sync_interval) start sync
1484
+
1485
+ let stop_sync () = Scheduler. remove_from_queue task_name
1486
+ end
1487
+
1401
1488
let build_netbios_name ~config_params =
1402
1489
let key = " netbios-name" in
1403
1490
match List. assoc_opt key config_params with
@@ -1721,20 +1808,24 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
1721
1808
ClosestKdc. trigger_update ~start: 0. ;
1722
1809
RotateMachinePassword. trigger_rotate ~start: 0. ;
1723
1810
ConfigHosts. join ~domain: service_name ~name: netbios_name ;
1811
+ ResolveConfig. join ~domain: service_name ;
1812
+ DNSSync. trigger_sync ~start: 0. ;
1724
1813
Winbind. set_machine_account_encryption_type netbios_name ;
1725
1814
debug " Succeed to join domain %s" service_name
1726
1815
with
1727
1816
| Forkhelpers. Spawn_internal_error (_ , stdout , _ ) ->
1728
1817
error " Join domain: %s error: %s" service_name stdout ;
1729
1818
clear_winbind_config () ;
1730
1819
ConfigHosts. leave ~domain: service_name ~name: netbios_name ;
1820
+ ResolveConfig. leave ~domain: service_name ;
1731
1821
(* The configure is kept for debug purpose with max level *)
1732
1822
raise (Auth_service_error (stdout |> tag_from_err_msg, stdout))
1733
1823
| Xapi_systemctl. Systemctl_fail _ ->
1734
1824
let msg = Printf. sprintf " Failed to start %s" Winbind. name in
1735
1825
error " Start daemon error: %s" msg ;
1736
1826
config_winbind_daemon ~domain: None ~workgroup: None ~netbios_name: None ;
1737
1827
ConfigHosts. leave ~domain: service_name ~name: netbios_name ;
1828
+ ResolveConfig. leave ~domain: service_name ;
1738
1829
raise (Auth_service_error (E_GENERIC , msg))
1739
1830
| e ->
1740
1831
let msg =
@@ -1746,6 +1837,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
1746
1837
error " Enable extauth error: %s" msg ;
1747
1838
clear_winbind_config () ;
1748
1839
ConfigHosts. leave ~domain: service_name ~name: netbios_name ;
1840
+ ResolveConfig. leave ~domain: service_name ;
1749
1841
raise (Auth_service_error (E_GENERIC , msg))
1750
1842
1751
1843
(* unit on_disable()
@@ -1760,9 +1852,13 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
1760
1852
let user = List. assoc_opt " user" config_params in
1761
1853
let pass = List. assoc_opt " pass" config_params in
1762
1854
let {service_name; netbios_name; _} = get_domain_info_from_db () in
1855
+ ResolveConfig. leave ~domain: service_name ;
1856
+ DNSSync. stop_sync () ;
1763
1857
( match netbios_name with
1764
- | Some name ->
1765
- ConfigHosts. leave ~domain: service_name ~name
1858
+ | Some netbios ->
1859
+ ConfigHosts. leave ~domain: service_name ~name: netbios ;
1860
+ let hostname = get_localhost_name () in
1861
+ DNSSync. unregister hostname netbios service_name
1766
1862
| _ ->
1767
1863
()
1768
1864
) ;
@@ -1792,6 +1888,7 @@ module AuthADWinbind : Auth_signature.AUTH_MODULE = struct
1792
1888
ClosestKdc. trigger_update ~start: ClosestKdc. startup_delay ;
1793
1889
RotateMachinePassword. trigger_rotate ~start: 5. ;
1794
1890
Winbind. check_ready_to_serve ~timeout: 300. ;
1891
+ DNSSync. trigger_sync ~start: 5. ;
1795
1892
1796
1893
let {service_name; netbios_name; _} = get_domain_info_from_db () in
1797
1894
match netbios_name with
0 commit comments