]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r22728: Patch from Danilo Almeida <dalmeida@centeris.com>:
authorGerald Carter <jerry@samba.org>
Sun, 6 May 2007 21:45:53 +0000 (21:45 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:21:51 +0000 (12:21 -0500)
When asked to create a machine account in an OU as part
of "net ads join" and the account already exists in another
OU, simply move the machine object to the requested OU.

source/libads/ldap.c
source/utils/net_ads.c

index 5a34385c32a3c96c061b4e76b64a527126908020..af4347c1474405b22f8baa939ba4527b584707d2 100644 (file)
@@ -1688,6 +1688,76 @@ done:
        return ret;
 }
 
+/**
+ * move a machine account to another OU on the ADS server
+ * @param ads - An intialized ADS_STRUCT
+ * @param machine_name - the NetBIOS machine name of this account.
+ * @param org_unit - The LDAP path in which to place this account
+ * @param moved - whether we moved the machine account (optional)
+ * @return 0 upon success, or non-zero otherwise
+**/
+
+ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, 
+                                 const char *org_unit, BOOL *moved)
+{
+       ADS_STATUS rc;
+       int ldap_status;
+       LDAPMessage *res = NULL;
+       char *filter = NULL;
+       char *computer_dn = NULL;
+       char *parent_dn;
+       char *computer_rdn = NULL;
+       BOOL need_move = False;
+
+       if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) {
+               rc = ADS_ERROR(LDAP_NO_MEMORY);
+               goto done;
+       }
+
+       /* Find pre-existing machine */
+       rc = ads_search(ads, &res, filter, NULL);
+       if (!ADS_ERR_OK(rc)) {
+               goto done;
+       }
+
+       computer_dn = ads_get_dn(ads, res);
+       if (!computer_dn) {
+               rc = ADS_ERROR(LDAP_NO_MEMORY);
+               goto done;
+       }
+
+       parent_dn = ads_parent_dn(computer_dn);
+       if (strequal(parent_dn, org_unit)) {
+               goto done;
+       }
+
+       need_move = True;
+
+       if (asprintf(&computer_rdn, "CN=%s", machine_name) == -1) {
+               rc = ADS_ERROR(LDAP_NO_MEMORY);
+               goto done;
+       }
+
+       ldap_status = ldap_rename2_s(ads->ld, computer_dn, computer_rdn, org_unit, 1);
+       rc = ADS_ERROR(ldap_status);
+
+done:
+       ads_msgfree(ads, res);
+       SAFE_FREE(filter);
+       SAFE_FREE(computer_dn);
+       SAFE_FREE(computer_rdn);
+
+       if (!ADS_ERR_OK(rc)) {
+               need_move = False;
+       }
+
+       if (moved) {
+               *moved = need_move;
+       }
+
+       return rc;
+}
+
 /*
   dump a binary result from ldap
 */
index 37ede28a9767bf225924f9c4b3131c955baa0646..030c5762f3ec2b059a0935414c73f6f1b61d1eed 100644 (file)
@@ -1190,28 +1190,50 @@ done:
 static ADS_STATUS net_precreate_machine_acct( ADS_STRUCT *ads, const char *ou )
 {
        ADS_STATUS rc = ADS_ERROR(LDAP_SERVER_DOWN);
-       char *dn, *ou_str;
+       char *ou_str = NULL;
+       char *dn = NULL;
        LDAPMessage *res = NULL;
+       BOOL moved;
 
        ou_str = ads_ou_string(ads, ou);
-       if ((asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path)) == -1) {
-               SAFE_FREE(ou_str);
-               return ADS_ERROR(LDAP_NO_MEMORY);
+       if (asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path) == -1) {
+               rc = ADS_ERROR(LDAP_NO_MEMORY);
+               goto done;
        }
 
        rc = ads_search_dn(ads, &res, dn, NULL);
-       ads_msgfree(ads, res);
+       if (!ADS_ERR_OK(rc)) {
+               d_fprintf(stderr, "The specified OU does not exist.\n");
+               goto done;
+       }
 
-       if (ADS_ERR_OK(rc)) {
                /* Attempt to create the machine account and bail if this fails.
                   Assume that the admin wants exactly what they requested */
 
                rc = ads_create_machine_acct( ads, global_myname(), dn );
-               if ( rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_ALREADY_EXISTS ) {
-                       rc = ADS_SUCCESS;
+       if (ADS_ERR_OK(rc)) {
+               DEBUG(1, ("machine account created\n"));
+               goto done;
                }
+       if ( !(rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_ALREADY_EXISTS) ) {
+               DEBUG(1, ("machine account creation failed\n"));
+               goto done;
+       }
+
+       rc = ads_move_machine_acct(ads, global_myname(), dn, &moved);
+       if (!ADS_ERR_OK(rc)) {
+               DEBUG(1, ("failure to locate/move pre-existing machine account\n"));
+               goto done;
        }
 
+       if (moved) {
+               d_printf("The machine account was moved into the specified OU.\n");
+       } else {
+               d_printf("The machine account already exists in the specified OU.\n");
+       }
+
+done:
+       ads_msgfree(ads, res);
        SAFE_FREE( ou_str );
        SAFE_FREE( dn );
 
@@ -1528,7 +1550,7 @@ int net_ads_join(int argc, const char **argv)
                status = net_precreate_machine_acct( ads, create_in_ou );
                if ( !ADS_ERR_OK(status) ) {
                        d_fprintf( stderr, "Failed to pre-create the machine object "
-                               "in OU %s.\n", argv[0]);
+                               "in OU %s.\n", create_in_ou);
                        DEBUG(1, ("error calling net_precreate_machine_acct: %s\n", 
                                  ads_errstr(status)));
                        nt_status = ads_ntstatus(status);