adcli/0014-enroll-Populate-Samba-s-secrets-database-using-offli.patch

178 lines
5.1 KiB
Diff

From 573216f40efd8aa1bcbaf606cd89d3906e648acb Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Thu, 7 Sep 2023 10:19:29 +0200
Subject: [PATCH 14/17] enroll: Populate Samba's secrets database using offline
domain join
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
---
library/adenroll.c | 146 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 146 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index c5a85a5..b6558ed 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -2363,6 +2363,150 @@ update_keytab_for_principals (adcli_enroll *enroll,
return ADCLI_SUCCESS;
}
+#if defined(SAMBA_NETAPI_HAS_COMPOSEODJ)
+
+#define CHECK_SNPRINTF(x, v) \
+ do { if ((x) < 0 || (x) >= sizeof((v))) { \
+ _adcli_err ("%s: Insufficient buffer for %s", __func__, #v); \
+ return ADCLI_ERR_FAIL; \
+ } } while (0)
+
+static adcli_result
+update_samba_data (adcli_enroll *enroll)
+{
+ int ret;
+ char dns_domain_name[128];
+ char netbios_domain_name[128];
+ char domain_sid[128];
+ char domain_guid[128];
+ char forest_name[128];
+ char machine_account_name[128];
+ char dc_name[128];
+ char dc_address[128];
+ char ldap_address[INET6_ADDRSTRLEN];
+ char *envp_composeodj[] = {"PASSWD_FD=0", NULL};
+ char *argv_composeodj[] = {
+ NULL,
+ "offlinejoin",
+ "composeodj",
+ dns_domain_name,
+ netbios_domain_name,
+ domain_sid,
+ domain_guid,
+ forest_name,
+ machine_account_name,
+ dc_name,
+ dc_address,
+ "printblob",
+ NULL};
+ char *argv_requestodj[] = {
+ NULL,
+ "offlinejoin",
+ "requestodj",
+ "-i",
+ NULL};
+ uint8_t *compose_out_data = NULL;
+ size_t compose_out_data_len = 0;
+ uint8_t *request_out_data = NULL;
+ size_t request_out_data_len = 0;
+
+ argv_composeodj[0] = (char *)adcli_enroll_get_samba_data_tool(enroll);
+ if (argv_composeodj[0] == NULL) {
+ _adcli_err("Samba data tool not available.");
+ return ADCLI_ERR_FAIL;
+ }
+ argv_requestodj[0] = argv_composeodj[0];
+
+ ret = adcli_sockaddr_to_string(adcli_conn_get_ldap_address(enroll->conn),
+ ldap_address, sizeof(ldap_address));
+ if (ret != ADCLI_SUCCESS) {
+ return ret;
+ }
+
+ ret = snprintf(dns_domain_name, sizeof(dns_domain_name), "--realm=%s",
+ adcli_conn_get_domain_name(enroll->conn));
+ CHECK_SNPRINTF(ret, dns_domain_name);
+
+ ret = snprintf(netbios_domain_name, sizeof(netbios_domain_name),
+ "--workgroup=%s", adcli_conn_get_domain_short(enroll->conn));
+ CHECK_SNPRINTF(ret, netbios_domain_name);
+
+ ret = snprintf(domain_sid, sizeof(domain_sid), "domain_sid=%s",
+ adcli_conn_get_domain_sid(enroll->conn));
+ CHECK_SNPRINTF(ret, domain_sid);
+
+ ret = snprintf(domain_guid, sizeof(domain_guid), "domain_guid=%s",
+ adcli_conn_get_domain_guid(enroll->conn));
+ CHECK_SNPRINTF(ret, domain_guid);
+
+ ret = snprintf(forest_name, sizeof(forest_name), "forest_name=%s",
+ adcli_conn_get_forest_name(enroll->conn));
+ CHECK_SNPRINTF(ret, forest_name);
+
+ ret = snprintf(machine_account_name, sizeof(machine_account_name),
+ "--user=%s", enroll->computer_sam);
+ CHECK_SNPRINTF(ret, machine_account_name);
+
+ ret = snprintf(dc_name, sizeof(dc_name), "--server=%s",
+ adcli_conn_get_domain_controller(enroll->conn));
+ CHECK_SNPRINTF(ret, dc_name);
+
+ ret = snprintf(dc_address, sizeof(dc_address), "--ipaddress=%s",
+ ldap_address);
+ CHECK_SNPRINTF(ret, dc_address);
+
+ _adcli_info("Trying to compose Samba ODJ blob.");
+ ret = _adcli_call_external_program(argv_composeodj[0],
+ argv_composeodj, envp_composeodj,
+ enroll->computer_password,
+ &compose_out_data, &compose_out_data_len);
+ if (ret != ADCLI_SUCCESS) {
+ while (compose_out_data && compose_out_data_len > 0 &&
+ compose_out_data[compose_out_data_len - 1] == '\n') {
+ compose_out_data_len--;
+ }
+ _adcli_err("Failed to compose Samba ODJ blob: %.*s",
+ (int)compose_out_data_len, (char *)compose_out_data);
+ goto out;
+ }
+
+ if (compose_out_data == NULL || compose_out_data_len == 0) {
+ _adcli_err("Failed to compose ODJ blob, no data returned.");
+ ret = ADCLI_ERR_FAIL;
+ goto out;
+ }
+
+ _adcli_info("Trying to request Samba ODJ.");
+ ret = _adcli_call_external_program(argv_requestodj[0],
+ argv_requestodj, NULL,
+ (const char *)compose_out_data,
+ &request_out_data, &request_out_data_len);
+ if (ret != ADCLI_SUCCESS) {
+ while (request_out_data && request_out_data_len > 0 &&
+ request_out_data[request_out_data_len - 1] == '\n') {
+ request_out_data_len--;
+ }
+ _adcli_err("Failed to request Samba ODJ: %.*s",
+ (int)request_out_data_len, request_out_data);
+ goto out;
+ }
+
+ ret = ADCLI_SUCCESS;
+out:
+ if (compose_out_data != NULL) {
+ /* Burn memory, the blob contains the machine password */
+ memset(compose_out_data, 0, compose_out_data_len);
+ free(compose_out_data);
+ }
+ if (request_out_data != NULL) {
+ free(request_out_data);
+ }
+
+ return ret;
+}
+
+#else /* defined(SAMBA_NETAPI_HAS_COMPOSEODJ) */
+
static adcli_result
update_samba_data (adcli_enroll *enroll)
{
@@ -2400,6 +2544,8 @@ update_samba_data (adcli_enroll *enroll)
return ret;
}
+#endif
+
static void
enroll_clear_state (adcli_enroll *enroll)
{
--
2.47.0