summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/libnet_samsync_ldb.c304
1 files changed, 303 insertions, 1 deletions
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index cedb1e233e..56bc99a3e7 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -254,6 +254,8 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
ADD_OR_DEL(string, "profilePath", profile_path.string);
+#undef ADD_OR_DEL
+
acb = user->acct_flags;
if (acb & (ACB_WSTRUST)) {
cn_name[cn_name_len - 1] = '\0';
@@ -296,6 +298,39 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+static NTSTATUS samsync_ldb_delete_user(TALLOC_CTX *mem_ctx,
+ struct samsync_ldb_state *state,
+ struct creds_CredentialState *creds,
+ enum netr_SamDatabaseID database,
+ struct netr_DELTA_ENUM *delta)
+{
+ uint32_t rid = delta->delta_id_union.rid;
+ struct ldb_message **msgs;
+ int ret;
+ const char *attrs[] = { NULL };
+
+ /* search for the user, by rid */
+ ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
+ "(&(objectClass=user)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid)));
+
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ return NT_STATUS_NO_SUCH_USER;
+ } else if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
+ if (ret != 0) {
+ DEBUG(0,("Failed to delete user record %s: %s\n", msgs[0]->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
struct samsync_ldb_state *state,
struct creds_CredentialState *creds,
@@ -304,7 +339,238 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
{
uint32_t rid = delta->delta_id_union.rid;
struct netr_DELTA_GROUP *group = delta->delta_union.group;
- const char *groupname = group->group_name.string;
+ const char *container, *obj_class;
+ const char *cn_name;
+
+ struct ldb_message *msg;
+ struct ldb_message **msgs;
+ int ret;
+ BOOL add = False;
+ const char *attrs[] = { NULL };
+
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* search for the group, by rid */
+ ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
+ "(&(objectClass=group)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid)));
+
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ add = True;
+ } else if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else {
+ msg->dn = talloc_steal(mem_ctx, msgs[0]->dn);
+ }
+
+ cn_name = group->group_name.string;
+
+#define ADD_OR_DEL(type, attrib, field) do {\
+ if (group->field) { \
+ samdb_msg_add_ ## type(state->sam_ldb, mem_ctx, msg, \
+ attrib, group->field); \
+ } else if (!add) { \
+ samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg, \
+ attrib); \
+ } \
+ } while (0);
+
+ ADD_OR_DEL(string, "samAccountName", group_name.string);
+
+ if (samdb_msg_add_dom_sid(state->sam_ldb, mem_ctx, msg,
+ "objectSid", dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ADD_OR_DEL(string, "description", description.string);
+
+#undef ADD_OR_DEL
+
+ container = "Users";
+ obj_class = "group";
+
+ if (add) {
+ samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
+ "objectClass", obj_class);
+ msg->dn = talloc_asprintf(mem_ctx, "CN=%s,CN=%s,%s",
+ cn_name, container, state->base_dn[database]);
+ if (!msg->dn) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = samdb_add(state->sam_ldb, mem_ctx, msg);
+ if (ret != 0) {
+ DEBUG(0,("Failed to create group record %s: %s\n", msg->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ } else {
+ ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
+ if (ret != 0) {
+ DEBUG(0,("Failed to modify group record %s: %s\n", msg->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS samsync_ldb_delete_group(TALLOC_CTX *mem_ctx,
+ struct samsync_ldb_state *state,
+ struct creds_CredentialState *creds,
+ enum netr_SamDatabaseID database,
+ struct netr_DELTA_ENUM *delta)
+{
+ uint32_t rid = delta->delta_id_union.rid;
+ struct ldb_message **msgs;
+ int ret;
+ const char *attrs[] = { NULL };
+
+ /* search for the group, by rid */
+ ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
+ "(&(objectClass=group)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid)));
+
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ return NT_STATUS_NO_SUCH_GROUP;
+ } else if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
+ if (ret != 0) {
+ DEBUG(0,("Failed to delete group record %s: %s\n", msgs[0]->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
+ struct samsync_ldb_state *state,
+ struct creds_CredentialState *creds,
+ enum netr_SamDatabaseID database,
+ struct netr_DELTA_ENUM *delta)
+{
+ uint32_t rid = delta->delta_id_union.rid;
+ struct netr_DELTA_ALIAS *alias = delta->delta_union.alias;
+ const char *container, *obj_class;
+ const char *cn_name;
+
+ struct ldb_message *msg;
+ struct ldb_message **msgs;
+ int ret;
+ BOOL add = False;
+ const char *attrs[] = { NULL };
+
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* search for the alias, by rid */
+ ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
+ "(&(objectClass=group)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid)));
+
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ add = True;
+ } else if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else {
+ msg->dn = talloc_steal(mem_ctx, msgs[0]->dn);
+ }
+
+ cn_name = alias->alias_name.string;
+
+#define ADD_OR_DEL(type, attrib, field) do {\
+ if (alias->field) { \
+ samdb_msg_add_ ## type(state->sam_ldb, mem_ctx, msg, \
+ attrib, alias->field); \
+ } else if (!add) { \
+ samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg, \
+ attrib); \
+ } \
+ } while (0);
+
+ ADD_OR_DEL(string, "samAccountName", alias_name.string);
+
+ if (samdb_msg_add_dom_sid(state->sam_ldb, mem_ctx, msg,
+ "objectSid", dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ADD_OR_DEL(string, "description", description.string);
+
+#undef ADD_OR_DEL
+
+ samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "groupType", "0x80000004");
+
+ container = "Users";
+ obj_class = "group";
+
+ if (add) {
+ samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
+ "objectClass", obj_class);
+ msg->dn = talloc_asprintf(mem_ctx, "CN=%s,CN=%s,%s",
+ cn_name, container, state->base_dn[database]);
+ if (!msg->dn) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = samdb_add(state->sam_ldb, mem_ctx, msg);
+ if (ret != 0) {
+ DEBUG(0,("Failed to create alias record %s: %s\n", msg->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ } else {
+ ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
+ if (ret != 0) {
+ DEBUG(0,("Failed to modify alias record %s: %s\n", msg->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS samsync_ldb_delete_alias(TALLOC_CTX *mem_ctx,
+ struct samsync_ldb_state *state,
+ struct creds_CredentialState *creds,
+ enum netr_SamDatabaseID database,
+ struct netr_DELTA_ENUM *delta)
+{
+ uint32_t rid = delta->delta_id_union.rid;
+ struct ldb_message **msgs;
+ int ret;
+ const char *attrs[] = { NULL };
+
+ /* search for the alias, by rid */
+ ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
+ "(&(objectClass=group)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid)));
+
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ } else if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
+ if (ret != 0) {
+ DEBUG(0,("Failed to delete alias record %s: %s\n", msgs[0]->dn, ldb_errstring(state->sam_ldb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
return NT_STATUS_OK;
}
@@ -339,6 +605,15 @@ static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,
delta);
break;
}
+ case NETR_DELTA_DELETE_USER:
+ {
+ nt_status = samsync_ldb_delete_user(mem_ctx,
+ state,
+ creds,
+ database,
+ delta);
+ break;
+ }
case NETR_DELTA_GROUP:
{
nt_status = samsync_ldb_handle_group(mem_ctx,
@@ -348,6 +623,33 @@ static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,
delta);
break;
}
+ case NETR_DELTA_DELETE_GROUP:
+ {
+ nt_status = samsync_ldb_delete_group(mem_ctx,
+ state,
+ creds,
+ database,
+ delta);
+ break;
+ }
+ case NETR_DELTA_ALIAS:
+ {
+ nt_status = samsync_ldb_handle_alias(mem_ctx,
+ state,
+ creds,
+ database,
+ delta);
+ break;
+ }
+ case NETR_DELTA_DELETE_ALIAS:
+ {
+ nt_status = samsync_ldb_delete_alias(mem_ctx,
+ state,
+ creds,
+ database,
+ delta);
+ break;
+ }
default:
/* Can't dump them all right now */
break;