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);

Reply via email to