a302cd
From 5eca1f995ced1ce4ddead4471ac7ac9037bedb73 Mon Sep 17 00:00:00 2001
a302cd
From: Sumit Bose <sbose@redhat.com>
a302cd
Date: Fri, 1 Jun 2018 21:26:47 +0200
a302cd
Subject: [PATCH 2/7] Only update attributes given on the command line
a302cd
a302cd
When updating attributes of the LDAP computer object we only want to
a302cd
update attributes which are related to options given on the command
a302cd
line. Otherwise a simple call of 'adcli update' to check if the machine
a302cd
account password needs an update might unexpectedly reset other
a302cd
attributes as well.
a302cd
a302cd
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547013
a302cd
           https://bugzilla.redhat.com/show_bug.cgi?id=1545568
a302cd
           https://bugzilla.redhat.com/show_bug.cgi?id=1538730
a302cd
---
a302cd
 library/adenroll.c | 35 ++++++++++++++++++++++++++++++-----
a302cd
 1 file changed, 30 insertions(+), 5 deletions(-)
a302cd
a302cd
diff --git a/library/adenroll.c b/library/adenroll.c
a302cd
index 7c59078..2be6796 100644
a302cd
--- a/library/adenroll.c
a302cd
+++ b/library/adenroll.c
a302cd
@@ -99,8 +99,11 @@ struct _adcli_enroll {
a302cd
 	int user_princpal_generate;
a302cd
 
a302cd
 	char *os_name;
a302cd
+	int os_name_explicit;
a302cd
 	char *os_version;
a302cd
+	int os_version_explicit;
a302cd
 	char *os_service_pack;
a302cd
+	int os_service_pack_explicit;
a302cd
 
a302cd
 	krb5_kvno kvno;
a302cd
 	char *keytab_name;
a302cd
@@ -113,6 +116,7 @@ struct _adcli_enroll {
a302cd
 	int computer_password_lifetime_explicit;
a302cd
 	char *samba_data_tool;
a302cd
 	bool trusted_for_delegation;
a302cd
+	int trusted_for_delegation_explicit;
a302cd
 };
a302cd
 
a302cd
 static adcli_result
a302cd
@@ -1212,7 +1216,11 @@ update_computer_account (adcli_enroll *enroll)
a302cd
 	ldap = adcli_conn_get_ldap_connection (enroll->conn);
a302cd
 	return_if_fail (ldap != NULL);
a302cd
 
a302cd
-	{
a302cd
+	/* Only update attributes which are explicitly given on the command
a302cd
+	 * line. Otherwise 'adcli update' must be always called with the same
a302cd
+	 * set of options to make sure existing attributes are not deleted or
a302cd
+	 * overwritten with different values. */
a302cd
+	if (enroll->host_fqdn_explicit) {
a302cd
 		char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
a302cd
 		LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } };
a302cd
 		LDAPMod *mods[] = { &dNSHostName, NULL };
a302cd
@@ -1220,7 +1228,7 @@ update_computer_account (adcli_enroll *enroll)
a302cd
 		res |= update_computer_attribute (enroll, ldap, mods);
a302cd
 	}
a302cd
 
a302cd
-	if (res == ADCLI_SUCCESS) {
a302cd
+	if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) {
a302cd
 		char *vals_userAccountControl[] = { NULL , NULL };
a302cd
 		LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
a302cd
 		LDAPMod *mods[] = { &userAccountControl, NULL };
a302cd
@@ -1240,12 +1248,25 @@ update_computer_account (adcli_enroll *enroll)
a302cd
 		LDAPMod operatingSystemVersion = { LDAP_MOD_REPLACE, "operatingSystemVersion", { vals_operatingSystemVersion, } };
a302cd
 		char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL };
a302cd
 		LDAPMod operatingSystemServicePack = { LDAP_MOD_REPLACE, "operatingSystemServicePack", { vals_operatingSystemServicePack, } };
a302cd
-		LDAPMod *mods[] = { &operatingSystem, &operatingSystemVersion, &operatingSystemServicePack, NULL };
a302cd
+		LDAPMod *mods[] = { NULL, NULL, NULL, NULL };
a302cd
+		size_t c = 0;
a302cd
 
a302cd
-		res |= update_computer_attribute (enroll, ldap, mods);
a302cd
+		if (enroll->os_name_explicit) {
a302cd
+			mods[c++] = &operatingSystem;
a302cd
+		}
a302cd
+		if (enroll->os_version_explicit) {
a302cd
+			mods[c++] = &operatingSystemVersion;
a302cd
+		}
a302cd
+		if (enroll->os_service_pack_explicit) {
a302cd
+			mods[c++] = &operatingSystemServicePack;
a302cd
+		}
a302cd
+
a302cd
+		if (c != 0) {
a302cd
+			res |= update_computer_attribute (enroll, ldap, mods);
a302cd
+		}
a302cd
 	}
a302cd
 
a302cd
-	if (res == ADCLI_SUCCESS) {
a302cd
+	if (res == ADCLI_SUCCESS && !enroll->user_princpal_generate) {
a302cd
 		char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
a302cd
 		LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, };
a302cd
 		LDAPMod *mods[] = { &userPrincipalName, NULL, };
a302cd
@@ -2337,6 +2358,7 @@ adcli_enroll_set_os_name (adcli_enroll *enroll,
a302cd
 	if (value && value[0] == '\0')
a302cd
 		value = NULL;
a302cd
 	_adcli_str_set (&enroll->os_name, value);
a302cd
+	enroll->os_name_explicit = 1;
a302cd
 }
a302cd
 
a302cd
 const char *
a302cd
@@ -2354,6 +2376,7 @@ adcli_enroll_set_os_version (adcli_enroll *enroll,
a302cd
 	if (value && value[0] == '\0')
a302cd
 		value = NULL;
a302cd
 	_adcli_str_set (&enroll->os_version, value);
a302cd
+	enroll->os_version_explicit = 1;
a302cd
 }
a302cd
 
a302cd
 const char *
a302cd
@@ -2371,6 +2394,7 @@ adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
a302cd
 	if (value && value[0] == '\0')
a302cd
 		value = NULL;
a302cd
 	_adcli_str_set (&enroll->os_service_pack, value);
a302cd
+	enroll->os_service_pack_explicit = 1;
a302cd
 }
a302cd
 
a302cd
 const char *
a302cd
@@ -2450,4 +2474,5 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
a302cd
 	return_if_fail (enroll != NULL);
a302cd
 
a302cd
 	enroll->trusted_for_delegation = value;
a302cd
+	enroll->trusted_for_delegation_explicit = 1;
a302cd
 }
a302cd
-- 
a302cd
2.14.4
a302cd