const DOM_SID *sid);
static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
DOM_SID *sid);
+static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
+ struct dom_sid *psid);
struct pdb_ads_state {
ret &= tldap_make_mod_fmt(
existing, mem_ctx, pnum_mods, pmods, "displayName",
- pdb_get_fullname(sam));
+ "%s", pdb_get_fullname(sam));
ret &= tldap_make_mod_blob(
existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
}
if (talloc_array_length(group) != 1) {
DEBUG(10, ("Expected 1 user, got %d\n",
- talloc_array_length(group)));
+ (int)talloc_array_length(group)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
TALLOC_CTX *mem_ctx, uint32 rid)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ struct dom_sid sid;
+ char *sidstr;
+ struct tldap_message **msg;
+ char *dn;
+ int rc;
+
+ sid_compose(&sid, &state->domainsid, rid);
+
+ sidstr = sid_binstring(talloc_tos(), &sid);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ NULL, 0, 0, talloc_tos(), &msg,
+ ("(&(objectSid=%s)(objectClass=group))"),
+ sidstr);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+
+ switch talloc_array_length(msg) {
+ case 0:
+ return NT_STATUS_NO_SUCH_GROUP;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (!tldap_entry_dn(msg[0], &dn)) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ rc = tldap_delete(state->ld, dn, NULL, NULL);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_delete failed: %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ TALLOC_FREE(dn);
+ return NT_STATUS_LDAP(rc);
+ }
+
+ TALLOC_FREE(msg);
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
TALLOC_CTX *mem_ctx,
const DOM_SID *group,
- uint32 **pp_member_rids,
- size_t *p_num_members)
+ uint32 **pmembers,
+ size_t *pnum_members)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ const char *attrs[1] = { "member" };
+ char *sidstr;
+ struct tldap_message **msg;
+ int i, rc, num_members;
+ DATA_BLOB *blobs;
+ uint32_t *members;
+
+ sidstr = sid_binstring(talloc_tos(), group);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
+ "(objectsid=%s)", sidstr);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+ switch talloc_array_length(msg) {
+ case 0:
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ break;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ break;
+ }
+
+ if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ members = talloc_array(mem_ctx, uint32_t, num_members);
+ if (members == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<num_members; i++) {
+ struct dom_sid sid;
+ if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
+ || !sid_peek_rid(&sid, &members[i])) {
+ TALLOC_FREE(members);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ }
+
+ *pmembers = members;
+ *pnum_members = num_members;
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
}
if (talloc_array_length(alias) != 1) {
DEBUG(10, ("Expected 1 alias, got %d\n",
- talloc_array_length(alias)));
+ (int)talloc_array_length(alias)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
if (!tldap_entry_dn(alias[0], &dn)) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
+ const struct dom_sid *sid,
+ TALLOC_CTX *mem_ctx, char **pdn)
+{
+ struct tldap_message **msg;
+ char *sidstr, *dn;
+ int rc;
+
+ sidstr = sid_binstring(talloc_tos(), sid);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ NULL, 0, 0, talloc_tos(), &msg,
+ "(objectsid=%s)", sidstr);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+
+ switch talloc_array_length(msg) {
+ case 0:
+ return NT_STATUS_NOT_FOUND;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (!tldap_entry_dn(msg[0], &dn)) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ dn = talloc_strdup(mem_ctx, dn);
+ if (dn == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ TALLOC_FREE(msg);
+
+ *pdn = dn;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
+ const DOM_SID *alias,
+ const DOM_SID *member,
+ int mod_op)
+{
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tldap_mod *mods;
+ int rc;
+ char *aliasdn, *memberdn;
+ NTSTATUS status;
+
+ status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
+ sid_string_dbg(alias), nt_errstr(status)));
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+ status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
+ sid_string_dbg(member), nt_errstr(status)));
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ mods = NULL;
+
+ if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
+ "member", memberdn)) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
+ TALLOC_FREE(frame);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_modify failed: %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
+ return NT_STATUS_MEMBER_IN_ALIAS;
+ }
+ if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
+ return NT_STATUS_MEMBER_NOT_IN_ALIAS;
+ }
+ return NT_STATUS_LDAP(rc);
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
const DOM_SID *alias,
const DOM_SID *member)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
}
static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
const DOM_SID *alias,
const DOM_SID *member)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
+}
+
+static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
+ struct dom_sid *psid)
+{
+ const char *attrs[1] = { "objectSid" };
+ struct tldap_message **msg;
+ char *dn;
+ size_t len;
+ int rc;
+ bool ret;
+
+ if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
+ dnblob->data, dnblob->length, &dn, &len,
+ false)) {
+ return false;
+ }
+ rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(objectclass=*)");
+ TALLOC_FREE(dn);
+ if (talloc_array_length(msg) != 1) {
+ DEBUG(10, ("Got %d objects, expected one\n",
+ (int)talloc_array_length(msg)));
+ TALLOC_FREE(msg);
+ return false;
+ }
+
+ ret = tldap_pull_binsid(msg[0], "objectSid", psid);
+ TALLOC_FREE(msg);
+ return ret;
}
static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
- const DOM_SID *alias, DOM_SID **members,
- size_t *p_num_members)
+ const DOM_SID *alias,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID **pmembers,
+ size_t *pnum_members)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ const char *attrs[1] = { "member" };
+ char *sidstr;
+ struct tldap_message **msg;
+ int i, rc, num_members;
+ DATA_BLOB *blobs;
+ struct dom_sid *members;
+
+ sidstr = sid_binstring(talloc_tos(), alias);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
+ "(objectsid=%s)", sidstr);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+ switch talloc_array_length(msg) {
+ case 0:
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ break;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ break;
+ }
+
+ if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ members = talloc_array(mem_ctx, struct dom_sid, num_members);
+ if (members == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<num_members; i++) {
+ if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
+ TALLOC_FREE(members);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ }
+
+ *pmembers = members;
+ *pnum_members = num_members;
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,