summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libads/ldap.c70
-rw-r--r--source3/utils/net_ads.c40
2 files changed, 101 insertions, 9 deletions
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 5a34385c32..af4347c147 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -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
*/
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 37ede28a97..030c5762f3 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -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);