summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/passdb/pdb_ads.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c
index 45aab1c3df..c07003f4f7 100644
--- a/source3/passdb/pdb_ads.c
+++ b/source3/passdb/pdb_ads.c
@@ -19,15 +19,6 @@
#include "includes.h"
-static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
- struct samu *sam_acct,
- 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 {
struct tldap_context *ld;
struct dom_sid domainsid;
@@ -36,6 +27,17 @@ struct pdb_ads_state {
char *netbiosname;
};
+static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
+ struct samu *sam_acct,
+ 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);
+static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
+ const struct dom_sid *sid,
+ TALLOC_CTX *mem_ctx, char **pdn);
+
static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
time_t *ptime)
{
@@ -887,18 +889,74 @@ static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
return NT_STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
+ TALLOC_CTX *mem_ctx,
+ uint32 grouprid, uint32 memberrid,
+ 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 dom_sid groupsid, membersid;
+ char *groupdn, *memberdn;
+ struct tldap_mod *mods;
+ int rc;
+ NTSTATUS status;
+
+ sid_compose(&groupsid, &state->domainsid, grouprid);
+ sid_compose(&membersid, &state->domainsid, memberrid);
+
+ status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+ status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ 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, groupdn, 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_GROUP;
+ }
+ if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
+ return NT_STATUS_MEMBER_NOT_IN_GROUP;
+ }
+ return NT_STATUS_LDAP(rc);
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 member_rid)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
+ TLDAP_MOD_ADD);
}
static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 member_rid)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
+ TLDAP_MOD_DELETE);
}
static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,