svn commit: samba r18446 - in branches/SAMBA_3_0/source: libads utils

jra at samba.org jra at samba.org
Wed Sep 13 09:03:43 GMT 2006


Author: jra
Date: 2006-09-13 09:03:42 +0000 (Wed, 13 Sep 2006)
New Revision: 18446

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18446

Log:
Add the ldap 'leave domain' code - call this as
a non-fatal error path if the 'disable machine
account' code succeeded.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/libads/ldap.c
   branches/SAMBA_3_0/source/utils/net_ads.c


Changeset:
Modified: branches/SAMBA_3_0/source/libads/ldap.c
===================================================================
--- branches/SAMBA_3_0/source/libads/ldap.c	2006-09-13 08:14:10 UTC (rev 18445)
+++ branches/SAMBA_3_0/source/libads/ldap.c	2006-09-13 09:03:42 UTC (rev 18446)
@@ -2818,4 +2818,178 @@
 	return name;
 }
 
+#if 0
+
+   SAVED CODE - we used to join via ldap - remember how we did this. JRA.
+
+/**
+ * Join a machine to a realm
+ *  Creates the machine account and sets the machine password
+ * @param ads connection to ads server
+ * @param machine name of host to add
+ * @param org_unit Organizational unit to place machine in
+ * @return status of join
+ **/
+ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
+			uint32 account_type, const char *org_unit)
+{
+	ADS_STATUS status;
+	LDAPMessage *res = NULL;
+	char *machine;
+
+	/* machine name must be lowercase */
+	machine = SMB_STRDUP(machine_name);
+	strlower_m(machine);
+
+	/*
+	status = ads_find_machine_acct(ads, (void **)&res, machine);
+	if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
+		DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine));
+		status = ads_leave_realm(ads, machine);
+		if (!ADS_ERR_OK(status)) {
+			DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n",
+				machine, ads->config.realm));
+			return status;
+		}
+	}
+	*/
+	status = ads_add_machine_acct(ads, machine, account_type, org_unit);
+	if (!ADS_ERR_OK(status)) {
+		DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status)));
+		SAFE_FREE(machine);
+		return status;
+	}
+
+	status = ads_find_machine_acct(ads, (void **)(void *)&res, machine);
+	if (!ADS_ERR_OK(status)) {
+		DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine));
+		SAFE_FREE(machine);
+		return status;
+	}
+
+	SAFE_FREE(machine);
+	ads_msgfree(ads, res);
+
+	return status;
+}
 #endif
+
+/**
+ * Delete a machine from the realm
+ * @param ads connection to ads server
+ * @param hostname Machine to remove
+ * @return status of delete
+ **/
+ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
+{
+	ADS_STATUS status;
+	void *msg;
+	LDAPMessage *res;
+	char *hostnameDN, *host;
+	int rc;
+	LDAPControl ldap_control;
+	LDAPControl  * pldap_control[2] = {NULL, NULL};
+
+	pldap_control[0] = &ldap_control;
+	memset(&ldap_control, 0, sizeof(LDAPControl));
+	ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID;
+
+	/* hostname must be lowercase */
+	host = SMB_STRDUP(hostname);
+	strlower_m(host);
+
+	status = ads_find_machine_acct(ads, &res, host);
+	if (!ADS_ERR_OK(status)) {
+		DEBUG(0, ("Host account for %s does not exist.\n", host));
+		SAFE_FREE(host);
+		return status;
+	}
+
+	msg = ads_first_entry(ads, res);
+	if (!msg) {
+		SAFE_FREE(host);
+		return ADS_ERROR_SYSTEM(ENOENT);
+	}
+
+	hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg);
+
+	rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL);
+	if (rc) {
+		DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc));
+	}else {
+		DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc));
+	}
+
+	ads_memfree(ads, hostnameDN);
+	if (rc != LDAP_SUCCESS) {
+		const char *attrs[] = { "cn", NULL };
+		void *msg_sub;
+
+		/* we only search with scope ONE, we do not expect any further
+		 * objects to be created deeper */
+
+		status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE,
+					"(objectclass=*)", attrs, &res);
+
+		if (!ADS_ERR_OK(status)) {
+			SAFE_FREE(host);
+			ads_memfree(ads, hostnameDN);
+			return status;
+		}
+
+		for (msg_sub = ads_first_entry(ads, res); msg_sub;
+			msg_sub = ads_next_entry(ads, msg_sub)) {
+
+			char *dn = NULL;
+
+			if ((dn = ads_get_dn(ads, msg_sub)) == NULL) {
+				SAFE_FREE(host);
+				ads_memfree(ads, hostnameDN);
+				return ADS_ERROR(LDAP_NO_MEMORY);
+			}
+
+			status = ads_del_dn(ads, dn);
+			if (!ADS_ERR_OK(status)) {
+				DEBUG(3,("failed to delete dn %s: %s\n", dn, ads_errstr(status)));
+				SAFE_FREE(host);
+				ads_memfree(ads, dn);
+				ads_memfree(ads, hostnameDN);
+				return status;
+			}
+
+			ads_memfree(ads, dn);
+		}
+
+		/* there should be no subordinate objects anymore */
+		status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE,
+					"(objectclass=*)", attrs, &res);
+
+		if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) {
+			SAFE_FREE(host);
+			ads_memfree(ads, hostnameDN);
+			return status;
+		}
+
+		/* delete hostnameDN now */
+		status = ads_del_dn(ads, hostnameDN);
+		if (!ADS_ERR_OK(status)) {
+			SAFE_FREE(host);
+			DEBUG(3,("failed to delete dn %s: %s\n", hostnameDN, ads_errstr(status)));
+			ads_memfree(ads, hostnameDN);
+			return status;
+		}
+	}
+
+	ads_memfree(ads, hostnameDN);
+
+	status = ads_find_machine_acct(ads, &res, host);
+	if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
+		DEBUG(3, ("Failed to remove host account.\n"));
+		SAFE_FREE(host);
+		return status;
+	}
+
+	SAFE_FREE(host);
+	return status;
+}
+#endif

Modified: branches/SAMBA_3_0/source/utils/net_ads.c
===================================================================
--- branches/SAMBA_3_0/source/utils/net_ads.c	2006-09-13 08:14:10 UTC (rev 18445)
+++ branches/SAMBA_3_0/source/utils/net_ads.c	2006-09-13 09:03:42 UTC (rev 18446)
@@ -758,6 +758,7 @@
 static int net_ads_leave(int argc, const char **argv)
 {
 	ADS_STRUCT *ads = NULL;
+	ADS_STATUS adsret;
 	int ret = -1;
 	struct cli_state *cli = NULL;
 	TALLOC_CTX *ctx;
@@ -800,11 +801,21 @@
 		goto done;
 	}
 	
-	d_printf("Disabled account for '%s' in realm '%s'\n", 
-		global_myname(), ads->config.realm);
-		
 	ret = 0;
 
+	/* Now we've disabled the account, try and delete it
+	   via LDAP - the old way we used to. Don't log a failure
+	   if this failed. */
+
+	adsret = ads_leave_realm(ads, global_myname());
+	if (ADS_ERR_OK(adsret)) {
+		d_printf("Deleted account for '%s' in realm '%s'\n",
+			global_myname(), ads->config.realm);
+	} else {
+		d_printf("Disabled account for '%s' in realm '%s'\n",
+			global_myname(), ads->config.realm);
+	}
+
 done:
 	if ( cli ) 
 		cli_shutdown(cli);



More information about the samba-cvs mailing list