summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
authorSteven Danneman <steven.danneman@isilon.com>2008-10-27 23:37:55 -0700
committerSteven Danneman <steven.danneman@isilon.com>2008-11-18 16:04:04 -0800
commit00c6271d5cbbfe808b81906d5be2b328e4f25b30 (patch)
treec6ce249e7596290249e8efd3577cd28c12d0d9be /source3/winbindd
parent041c5cf3b5a2fba6ad49e049601b626d5b04ac3e (diff)
downloadsamba-00c6271d5cbbfe808b81906d5be2b328e4f25b30.tar.gz
samba-00c6271d5cbbfe808b81906d5be2b328e4f25b30.tar.bz2
samba-00c6271d5cbbfe808b81906d5be2b328e4f25b30.zip
Added ability to remove id mappings in wbinfo and libwbclient.
The idmap_tdb backend already provides an interface to remove existing id mappings. This commit plumbs that ability up through, winbindd, libwbclient, and wbinfo. Added new winbindd command: WINBINDD_REMOVE_MAPPING Added new libwbclient interfaces: wbcRemoveUidMapping() and wbcRemoveGidMapping() Added new wbinfo options: --remove-uid-mapping --remove-gid-mapping Increased libwbclient version to 0.2 Increased winbind interface version to 20
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/idmap.c17
-rw-r--r--source3/winbindd/idmap_tdb.c14
-rw-r--r--source3/winbindd/winbindd.c1
-rw-r--r--source3/winbindd/winbindd_idmap.c63
-rw-r--r--source3/winbindd/winbindd_proto.h6
-rw-r--r--source3/winbindd/winbindd_sid.c42
6 files changed, 141 insertions, 2 deletions
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
index cfc5597f42..054df9be05 100644
--- a/source3/winbindd/idmap.c
+++ b/source3/winbindd/idmap.c
@@ -788,3 +788,20 @@ NTSTATUS idmap_set_mapping(const struct id_map *map)
return dom->methods->set_mapping(dom, map);
}
+
+NTSTATUS idmap_remove_mapping(const struct id_map *map)
+{
+ struct idmap_domain *dom;
+
+ dom = idmap_find_domain(NULL);
+ if (dom == NULL) {
+ DEBUG(3, ("no default domain, no place to write\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (dom->methods->remove_mapping == NULL) {
+ DEBUG(3, ("default domain not writable\n"));
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+
+ return dom->methods->remove_mapping(dom, map);
+}
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index f9d3a9fbff..7c4de5f6fb 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -875,8 +875,13 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
ksid = string_term_tdb_data(ksidstr);
/* *DELETE* previous mappings if any.
- * This is done both SID and [U|G]ID passed in */
-
+ * This is done for both the SID and [U|G]ID passed in */
+
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -981,6 +986,11 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
ksid = string_term_tdb_data(ksidstr);
kid = string_term_tdb_data(kidstr);
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index ce1a1fe52f..9e8a5a613e 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -343,6 +343,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" },
{ WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" },
+ { WINBINDD_REMOVE_MAPPING, winbindd_remove_mapping, "REMOVE_MAPPING" },
{ WINBINDD_SET_HWM, winbindd_set_hwm, "SET_HWMS" },
/* Miscellaneous */
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
index d8c67dc21c..94a8c78a85 100644
--- a/source3/winbindd/winbindd_idmap.c
+++ b/source3/winbindd/winbindd_idmap.c
@@ -111,6 +111,65 @@ enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+static void winbindd_remove_mapping_recv(TALLOC_CTX *mem_ctx, bool success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, bool succ) = (void (*)(void *, bool))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger idmap_remove_mapping\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap_remove_mapping returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx,
+ const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_REMOVE_MAPPING;
+ request.data.dual_idmapset.id = map->xid.id;
+ request.data.dual_idmapset.type = map->xid.type;
+ sid_to_fstring(request.data.dual_idmapset.sid, map->sid);
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_remove_mapping_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_remove_mapping(
+ struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: dual_idmapremove\n", (unsigned long)state->pid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
+ return WINBINDD_ERROR;
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+ map.status = ID_MAPPED;
+
+ result = idmap_remove_mapping(&map);
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, bool success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -486,6 +545,10 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
.struct_cmd = WINBINDD_DUAL_SET_MAPPING,
.struct_fn = winbindd_dual_set_mapping,
},{
+ .name = "DUAL_REMOVE_MAPPING",
+ .struct_cmd = WINBINDD_DUAL_REMOVE_MAPPING,
+ .struct_fn = winbindd_dual_remove_mapping,
+ },{
.name = "DUAL_SET_HWMS",
.struct_cmd = WINBINDD_DUAL_SET_HWM,
.struct_fn = winbindd_dual_set_hwm,
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 65ad47dd03..4f3d10f57f 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -353,6 +353,11 @@ void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
void *private_data);
enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data);
+enum winbindd_result winbindd_dual_remove_mapping(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state);
void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
void (*cont)(void *private_data, bool success),
void *private_data);
@@ -505,6 +510,7 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state);
void winbindd_sid_to_gid(struct winbindd_cli_state *state);
void winbindd_sids_to_unixids(struct winbindd_cli_state *state);
void winbindd_set_mapping(struct winbindd_cli_state *state);
+void winbindd_remove_mapping(struct winbindd_cli_state *state);
void winbindd_set_hwm(struct winbindd_cli_state *state);
void winbindd_uid_to_sid(struct winbindd_cli_state *state);
void winbindd_gid_to_sid(struct winbindd_cli_state *state);
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index 274786fa63..d8bd863037 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -415,6 +415,48 @@ void winbindd_set_mapping(struct winbindd_cli_state *state)
set_mapping_recv, state);
}
+static void remove_mapping_recv(void *private_data, bool success)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (!success) {
+ DEBUG(5, ("Could not remove sid mapping\n"));
+ request_error(state);
+ return;
+ }
+
+ request_ok(state);
+}
+
+void winbindd_remove_mapping(struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+
+ DEBUG(3, ("[%5lu]: remove id map\n", (unsigned long)state->pid));
+
+ if ( ! state->privileged) {
+ DEBUG(0, ("Only root is allowed to remove mappings!\n"));
+ request_error(state);
+ return;
+ }
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.sid));
+ request_error(state);
+ return;
+ }
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+
+ winbindd_remove_mapping_async(state->mem_ctx, &map,
+ remove_mapping_recv, state);
+}
+
static void set_hwm_recv(void *private_data, bool success)
{
struct winbindd_cli_state *state =