summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-04-04 16:02:17 +0200
committerJelmer Vernooij <jelmer@samba.org>2008-04-04 16:02:17 +0200
commit30ccc36b8d61f2d09c3f0adeec4db0ab540619b8 (patch)
tree740fd5c06ebffb4991ede45182447d317603d115
parentadc09857420c4a9306148e8d15ff5faf633ba7a5 (diff)
parentc26387a473fd26ac51c74c001b520d7fd7d353ec (diff)
downloadsamba-30ccc36b8d61f2d09c3f0adeec4db0ab540619b8.tar.gz
samba-30ccc36b8d61f2d09c3f0adeec4db0ab540619b8.tar.bz2
samba-30ccc36b8d61f2d09c3f0adeec4db0ab540619b8.zip
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into openchange
Conflicts: source/headermap.txt (This used to be commit 1b084e85c1f5963d924f7764ae751f8cd8e57364)
-rw-r--r--WHATSNEW.txt5
-rw-r--r--source4/headermap.txt2
-rw-r--r--source4/lib/messaging/irpc.h4
-rw-r--r--source4/lib/util/util.c15
-rw-r--r--source4/lib/util/util.h7
-rw-r--r--source4/libcli/config.mk1
-rw-r--r--source4/libcli/wbclient/config.mk6
-rw-r--r--source4/libcli/wbclient/wbclient.c210
-rw-r--r--source4/libcli/wbclient/wbclient.h50
-rw-r--r--source4/librpc/idl/lsa.idl2
-rw-r--r--source4/librpc/idl/winbind.idl34
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c100
-rw-r--r--source4/ntvfs/posix/pvfs_acl_nfs4.c106
-rw-r--r--source4/ntvfs/posix/vfs_posix.c6
-rw-r--r--source4/ntvfs/posix/vfs_posix.h3
-rw-r--r--source4/ntvfs/unixuid/vfs_unixuid.c72
-rw-r--r--source4/pidl/config.m49
-rw-r--r--source4/rpc_server/config.mk3
-rw-r--r--source4/rpc_server/lsa/lsa.h1
-rw-r--r--source4/rpc_server/lsa/lsa_init.c5
-rw-r--r--source4/rpc_server/lsa/lsa_lookup.c5
-rw-r--r--source4/rpc_server/unixinfo/dcesrv_unixinfo.c160
-rw-r--r--source4/scripting/python/samba/idmap.py73
-rw-r--r--source4/scripting/python/samba/provision.py93
-rw-r--r--source4/scripting/python/samba/samdb.py19
-rw-r--r--source4/winbind/idmap.c145
-rw-r--r--source4/winbind/idmap.h20
-rw-r--r--source4/winbind/wb_irpc.c70
-rw-r--r--source4/winbind/wb_xids2sids.c4
29 files changed, 943 insertions, 287 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 1e8f803f43..f58df497f5 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -97,6 +97,11 @@ continued to evolve, but you may particularly notice these areas:
better integration with Windows administrative tools, especially
Active Directory Users and Computers.
+ ID mapping: Samba4 now handles ID mapping via winbind. The mappings
+ are stored in a central ldb that could be shared across multiple
+ machines using LDAP. Internal callers access this interface via a new
+ wbclient library.
+
These are just some of the highlights of the work done in the past few
months. More details can be found in our GIT history.
diff --git a/source4/headermap.txt b/source4/headermap.txt
index 7984149837..fbfc56e127 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -66,6 +66,8 @@ param/share.h: share.h
lib/util/util_tdb.h: util_tdb.h
lib/util/util_ldb.h: util_ldb.h
lib/util/wrap_xattr.h: wrap_xattr.h
+lib/events/events.h: events/events.h
+lib/events/events_internal.h: events/events_internal.h
libcli/ldap/ldap_ndr.h: ldap_ndr.h
lib/events/events.h: events.h
lib/events/events_internal.h: events_internal.h
diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h
index d596c6721e..f44c0af3ec 100644
--- a/source4/lib/messaging/irpc.h
+++ b/source4/lib/messaging/irpc.h
@@ -19,6 +19,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef IRPC_H
+#define IRPC_H
+
#include "librpc/gen_ndr/irpc.h"
/*
@@ -123,4 +126,5 @@ struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, TALLOC_
void irpc_remove_name(struct messaging_context *msg_ctx, const char *name);
NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status);
+#endif
diff --git a/source4/lib/util/util.c b/source4/lib/util/util.c
index 7b6bfeeb7b..b5bb75358e 100644
--- a/source4/lib/util/util.c
+++ b/source4/lib/util/util.c
@@ -582,3 +582,18 @@ _PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count)
return realloc(ptr, el_size * count);
}
+_PUBLIC_ void *talloc_check_name_abort(const void *ptr, const char *name)
+{
+ void *result;
+
+ result = talloc_check_name(ptr, name);
+ if (result != NULL)
+ return result;
+
+ DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
+ name, talloc_get_name(ptr)));
+ smb_panic("talloc type mismatch");
+ /* Keep the compiler happy */
+ return NULL;
+}
+
diff --git a/source4/lib/util/util.h b/source4/lib/util/util.h
index 60c8437634..3bf6b98d2f 100644
--- a/source4/lib/util/util.h
+++ b/source4/lib/util/util.h
@@ -803,4 +803,11 @@ bool pm_process( const char *fileName,
bool (*pfunc)(const char *, const char *, void *),
void *userdata);
+/**
+ * Add-on to talloc_get_type
+ */
+_PUBLIC_ void *talloc_check_name_abort(const void *ptr, const char *name);
+#define talloc_get_type_abort(ptr, type) \
+ (type *)talloc_check_name_abort(ptr, #type)
+
#endif /* _SAMBA_UTIL_H_ */
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index b85fbe7066..0c00fa2740 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -1,6 +1,7 @@
mkinclude auth/config.mk
mkinclude ldap/config.mk
mkinclude security/config.mk
+mkinclude wbclient/config.mk
[SUBSYSTEM::LIBSAMBA-ERRORS]
OBJ_FILES = util/doserr.o \
diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk
new file mode 100644
index 0000000000..32f2f5aeed
--- /dev/null
+++ b/source4/libcli/wbclient/config.mk
@@ -0,0 +1,6 @@
+[SUBSYSTEM::LIBWBCLIENT]
+OBJ_FILES = wbclient.o
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS
+PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING
+
+PUBLIC_HEADERS += libcli/wbclient/wbclient.h
diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c
new file mode 100644
index 0000000000..1b2d314824
--- /dev/null
+++ b/source4/libcli/wbclient/wbclient.c
@@ -0,0 +1,210 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client library.
+
+ Copyright (C) 2008 Kai Blin <kai@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/wbclient/wbclient.h"
+
+/**
+ * Get the server_id of the winbind task.
+ *
+ * \param[in] msg_ctx message context to use
+ * \param[in] mem_ctx talloc context to use
+ * \param[out] ids array of server_id structs containing the winbind id
+ * \return NT_STATUS_OK on success, NT_STATUS_INTERNAL_ERROR on failure
+ */
+static NTSTATUS get_server_id(struct messaging_context *msg_ctx,
+ TALLOC_CTX *mem_ctx, struct server_id **ids)
+{
+ *ids = irpc_servers_byname(msg_ctx, mem_ctx, "winbind_server");
+ if (*ids == NULL || (*ids)[0].id == 0) {
+ DEBUG(0, ("Geting the winbind server ID failed.\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ return NT_STATUS_OK;
+}
+
+/**
+ * Initialize the wbclient context, talloc_free() when done.
+ *
+ * \param mem_ctx talloc context to allocate memory from
+ * \param msg_ctx message context to use
+ * \param
+ */
+struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ struct event_context *event_ctx)
+{
+ struct wbc_context *ctx;
+ NTSTATUS status;
+
+ ctx = talloc(mem_ctx, struct wbc_context);
+ if (ctx == NULL) return NULL;
+
+ status = get_server_id(msg_ctx, mem_ctx, &ctx->ids);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(ctx);
+ return NULL;
+ }
+
+ ctx->msg_ctx = msg_ctx;
+ ctx->event_ctx = event_ctx;
+
+ return ctx;
+}
+
+struct wbc_idmap_state {
+ struct composite_context *ctx;
+ struct winbind_get_idmap *req;
+ struct irpc_request *irpc_req;
+ struct id_mapping *ids;
+};
+
+static void sids_to_xids_recv_ids(struct irpc_request *req);
+
+struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
+ TALLOC_CTX *mem_ctx,
+ uint32_t count,
+ struct id_mapping *ids)
+{
+ struct composite_context *ctx;
+ struct wbc_idmap_state *state;
+
+ DEBUG(5, ("wbc_sids_to_xids called\n"));
+
+ ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
+ if (ctx == NULL) return NULL;
+
+ state = talloc(ctx, struct wbc_idmap_state);
+ if (composite_nomem(state, ctx)) return ctx;
+ ctx->private_data = state;
+
+ state->req = talloc(state, struct winbind_get_idmap);
+ if (composite_nomem(state->req, ctx)) return ctx;
+
+ state->req->in.count = count;
+ state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS;
+ state->req->in.ids = ids;
+ state->ctx = ctx;
+
+ state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0],
+ winbind, WINBIND_GET_IDMAP, state->req,
+ state);
+ if (composite_nomem(state->irpc_req, ctx)) return ctx;
+
+ composite_continue_irpc(ctx, state->irpc_req, sids_to_xids_recv_ids,
+ state);
+ return ctx;
+}
+
+static void sids_to_xids_recv_ids(struct irpc_request *req)
+{
+ struct wbc_idmap_state *state = talloc_get_type_abort(
+ req->async.private,
+ struct wbc_idmap_state);
+
+ state->ctx->status = irpc_call_recv(state->irpc_req);
+ if (!composite_is_ok(state->ctx)) return;
+
+ state->ids = state->req->out.ids;
+ composite_done(state->ctx);
+}
+
+NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
+ struct id_mapping **ids)
+{
+ NTSTATUS status = composite_wait(ctx);
+ DEBUG(5, ("wbc_sids_to_xids_recv called\n"));
+ if (NT_STATUS_IS_OK(status)) {
+ struct wbc_idmap_state *state = talloc_get_type_abort(
+ ctx->private_data,
+ struct wbc_idmap_state);
+ *ids = state->ids;
+ }
+
+ return status;
+}
+
+static void xids_to_sids_recv_ids(struct irpc_request *req);
+
+struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
+ TALLOC_CTX *mem_ctx,
+ uint32_t count,
+ struct id_mapping *ids)
+{
+ struct composite_context *ctx;
+ struct wbc_idmap_state *state;
+
+ DEBUG(5, ("wbc_xids_to_sids called\n"));
+
+ ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
+ if (ctx == NULL) return NULL;
+
+ state = talloc(ctx, struct wbc_idmap_state);
+ if (composite_nomem(state, ctx)) return ctx;
+ ctx->private_data = state;
+
+ state->req = talloc(state, struct winbind_get_idmap);
+ if (composite_nomem(state->req, ctx)) return ctx;
+
+ state->req->in.count = count;
+ state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS;
+ state->req->in.ids = ids;
+ state->ctx = ctx;
+
+ state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0],
+ winbind, WINBIND_GET_IDMAP, state->req,
+ state);
+ if (composite_nomem(state->irpc_req, ctx)) return ctx;
+
+ composite_continue_irpc(ctx, state->irpc_req, xids_to_sids_recv_ids,
+ state);
+
+ return ctx;
+}
+
+static void xids_to_sids_recv_ids(struct irpc_request *req)
+{
+ struct wbc_idmap_state *state = talloc_get_type_abort(
+ req->async.private,
+ struct wbc_idmap_state);
+
+ state->ctx->status = irpc_call_recv(state->irpc_req);
+ if (!composite_is_ok(state->ctx)) return;
+
+ state->ids = state->req->out.ids;
+ composite_done(state->ctx);
+}
+
+NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
+ struct id_mapping **ids)
+{
+ NTSTATUS status = composite_wait(ctx);
+ DEBUG(5, ("wbc_xids_to_sids_recv called\n"));
+ if (NT_STATUS_IS_OK(status)) {
+ struct wbc_idmap_state *state = talloc_get_type_abort(
+ ctx->private_data,
+ struct wbc_idmap_state);
+ *ids = state->ids;
+ }
+
+ return status;
+}
+
diff --git a/source4/libcli/wbclient/wbclient.h b/source4/libcli/wbclient/wbclient.h
new file mode 100644
index 0000000000..099abaa511
--- /dev/null
+++ b/source4/libcli/wbclient/wbclient.h
@@ -0,0 +1,50 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client library.
+
+ Copyright (C) 2008 Kai Blin <kai@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "lib/messaging/irpc.h"
+#include "libcli/composite/composite.h"
+#include "librpc/gen_ndr/ndr_winbind.h"
+
+struct wbc_context {
+ struct messaging_context *msg_ctx;
+ struct event_context *event_ctx;
+ struct server_id *ids;
+};
+
+struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ struct event_context *event_ctx);
+
+struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
+ TALLOC_CTX *mem_ctx,
+ uint32_t count,
+ struct id_mapping *ids);
+
+NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
+ struct id_mapping **ids);
+
+struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
+ TALLOC_CTX *mem_ctx,
+ uint32_t count,
+ struct id_mapping *ids);
+
+NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
+ struct id_mapping **ids);
+
diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl
index 6d15822ea6..e36e79f5c4 100644
--- a/source4/librpc/idl/lsa.idl
+++ b/source4/librpc/idl/lsa.idl
@@ -338,7 +338,7 @@ import "misc.idl", "security.idl";
/******************/
/* Function: 0x0e */
- typedef enum {
+ typedef [public] enum {
SID_NAME_USE_NONE = 0,/* NOTUSED */
SID_NAME_USER = 1, /* user */
SID_NAME_DOM_GRP = 2, /* domain group */
diff --git a/source4/librpc/idl/winbind.idl b/source4/librpc/idl/winbind.idl
index 29649c0ea7..5cefb38f75 100644
--- a/source4/librpc/idl/winbind.idl
+++ b/source4/librpc/idl/winbind.idl
@@ -3,8 +3,8 @@
*/
#include "idl_types.h"
-
-import "netlogon.idl";
+
+import "netlogon.idl", "lsa.idl", "security.idl";
[
uuid("245f3e6b-3c5d-6e21-3a2d-2a3d645b7221"),
@@ -16,6 +16,24 @@ interface winbind
typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
typedef [switch_type(uint16)] union netr_Validation netr_Validation;
+ typedef enum {
+ ID_TYPE_NOT_SPECIFIED,
+ ID_TYPE_UID,
+ ID_TYPE_GID,
+ ID_TYPE_BOTH
+ } id_type;
+
+ typedef struct {
+ uint32 id;
+ id_type type;
+ } unixid;
+
+ typedef struct {
+ unixid *unixid;
+ dom_sid *sid;
+ NTSTATUS status;
+ } id_mapping;
+
/* a call to get runtime informations */
void winbind_information(/* TODO */);
@@ -35,4 +53,16 @@ interface winbind
[out] [switch_is(validation_level)] netr_Validation validation,
[out] uint8 authoritative
);
+
+ typedef [v1_enum] enum {
+ WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS = 1,
+ WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS = 2
+ } winbind_get_idmap_level;
+
+ NTSTATUS winbind_get_idmap(
+ [in] winbind_get_idmap_level level,
+ [in] uint32 count,
+ [in,out] [size_is(count)] id_mapping ids[]
+ );
+
}
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index 5070f6852d..2393a2e7a3 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -126,6 +126,8 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
NTSTATUS status;
struct security_ace ace;
mode_t mode;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
*psd = security_descriptor_initialise(req);
if (*psd == NULL) {
@@ -133,15 +135,33 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
}
sd = *psd;
- status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ ids = talloc_array(sd, struct id_mapping, 2);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids[0].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
+
+ ids[0].unixid->id = name->st.st_uid;
+ ids[0].unixid->type = ID_TYPE_UID;
+ ids[0].sid = NULL;
+ ids[1].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
+
+ ids[1].unixid->id = name->st.st_gid;
+ ids[1].unixid->type = ID_TYPE_GID;
+ ids[1].sid = NULL;
+
+ ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_xids_to_sids_recv(ctx, &ids);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ sd->owner_sid = talloc_steal(sd, ids[0].sid);
+ sd->group_sid = talloc_steal(sd, ids[1].sid);
+
+ talloc_free(ids);
sd->type |= SEC_DESC_DACL_PRESENT;
mode = name->st.st_mode;
@@ -248,6 +268,8 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
gid_t old_gid = -1;
uid_t new_uid = -1;
gid_t new_gid = -1;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
if (pvfs->acl_ops != NULL) {
status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
@@ -259,6 +281,12 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
return status;
}
+ ids = talloc(req, struct id_mapping);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+ ids->unixid = NULL;
+ ids->sid = NULL;
+ ids->status = NT_STATUS_NONE_MAPPED;
+
new_sd = info->set_secdesc.in.sd;
orig_sd = *sd;
@@ -271,8 +299,16 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
return NT_STATUS_ACCESS_DENIED;
}
if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
- status = sidmap_sid_to_unixuid(pvfs->sidmap, new_sd->owner_sid, &new_uid);
+ ids->sid = new_sd->owner_sid;
+ ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+ status = wbc_sids_to_xids_recv(ctx, &ids);
NT_STATUS_NOT_OK_RETURN(status);
+
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_UID) {
+ new_uid = ids->unixid->id;
+ }
}
sd->owner_sid = new_sd->owner_sid;
}
@@ -281,8 +317,17 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
return NT_STATUS_ACCESS_DENIED;
}
if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
- status = sidmap_sid_to_unixgid(pvfs->sidmap, new_sd->group_sid, &new_gid);
+ ids->sid = new_sd->group_sid;
+ ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+ status = wbc_sids_to_xids_recv(ctx, &ids);
NT_STATUS_NOT_OK_RETURN(status);
+
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_GID) {
+ new_gid = ids->unixid->id;
+ }
+
}
sd->group_sid = new_sd->group_sid;
}
@@ -664,6 +709,8 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
struct pvfs_filename *parent;
struct security_descriptor *parent_sd, *sd;
bool container;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
/* form the parents path */
status = pvfs_resolve_parent(pvfs, req, name, &parent);
@@ -705,14 +752,31 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
return NT_STATUS_NO_MEMORY;
}
- status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ ids = talloc_array(sd, struct id_mapping, 2);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids[0].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
+ ids[0].unixid->id = name->st.st_uid;
+ ids[0].unixid->type = ID_TYPE_UID;
+ ids[0].sid = NULL;
+ ids[0].status = NT_STATUS_NONE_MAPPED;
+
+ ids[1].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
+ ids[1].unixid->id = name->st.st_gid;
+ ids[1].unixid->type = ID_TYPE_GID;
+ ids[1].sid = NULL;
+ ids[1].status = NT_STATUS_NONE_MAPPED;
+
+ ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_xids_to_sids_recv(ctx, &ids);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ sd->owner_sid = talloc_steal(sd, ids[0].sid);
+ sd->group_sid = talloc_steal(sd, ids[1].sid);
sd->type |= SEC_DESC_DACL_PRESENT;
diff --git a/source4/ntvfs/posix/pvfs_acl_nfs4.c b/source4/ntvfs/posix/pvfs_acl_nfs4.c
index 2abb1482a4..fa855555b2 100644
--- a/source4/ntvfs/posix/pvfs_acl_nfs4.c
+++ b/source4/ntvfs/posix/pvfs_acl_nfs4.c
@@ -38,7 +38,9 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename
NTSTATUS status;
struct nfs4acl *acl;
struct security_descriptor *sd;
- int i;
+ int i, num_ids;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
acl = talloc_zero(mem_ctx, struct nfs4acl);
NT_STATUS_HAVE_NO_MEMORY(acl);
@@ -57,25 +59,57 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename
sd = *psd;
sd->type |= acl->a_flags;
- status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
- NT_STATUS_NOT_OK_RETURN(status);
- status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
+
+ /* the number of ids to map is the acl count plus uid and gid */
+ num_ids = acl->a_count +2;
+ ids = talloc_array(sd, struct id_mapping, num_ids);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids[0].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
+ ids[0].unixid->id = name->st.st_uid;
+ ids[0].unixid->type = ID_TYPE_UID;
+ ids[0].sid = NULL;
+ ids[0].status = NT_STATUS_NONE_MAPPED;
+
+ ids[1].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
+ ids[1].unixid->id = name->st.st_gid;
+ ids[1].unixid->type = ID_TYPE_GID;
+ ids[1].sid = NULL;
+ ids[1].status = NT_STATUS_NONE_MAPPED;
+
+ for (i=0;i<acl->a_count;i++) {
+ struct nfs4ace *a = &acl->ace[i];
+ ids[i+2].unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids[i+2].unixid);
+ ids[i+2].unixid->id = a->e_id;
+ if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
+ ids[i+2].unixid->type = ID_TYPE_GID;
+ } else {
+ ids[i+2].unixid->type = ID_TYPE_UID;
+ }
+ ids[i+2].sid = NULL;
+ ids[i+2].status = NT_STATUS_NONE_MAPPED;
+ }
+
+ /* Allocate memory for the sids from the security descriptor to be on
+ * the safe side. */
+ ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, sd, num_ids, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+ status = wbc_xids_to_sids_recv(ctx, &ids);
NT_STATUS_NOT_OK_RETURN(status);
+ sd->owner_sid = talloc_steal(sd, ids[0].sid);
+ sd->group_sid = talloc_steal(sd, ids[1].sid);
+
for (i=0;i<acl->a_count;i++) {
struct nfs4ace *a = &acl->ace[i];
struct security_ace ace;
- struct dom_sid *sid;
ace.type = a->e_type;
ace.flags = a->e_flags;
ace.access_mask = a->e_mask;
- if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
- status = sidmap_gid_to_sid(pvfs->sidmap, sd, a->e_id, &sid);
- } else {
- status = sidmap_uid_to_sid(pvfs->sidmap, sd, a->e_id, &sid);
- }
- NT_STATUS_NOT_OK_RETURN(status);
- ace.trustee = *sid;
+ ace.trustee = *ids[i+2].sid;
security_descriptor_dacl_add(sd, &ace);
}
@@ -93,6 +127,8 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename
struct nfs4acl acl;
int i;
TALLOC_CTX *tmp_ctx;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
tmp_ctx = talloc_new(pvfs);
NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
@@ -110,30 +146,44 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename
return NT_STATUS_NO_MEMORY;
}
+ ids = talloc_array(tmp_ctx, struct id_mapping, acl.a_count);
+ if (ids == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0;i<acl.a_count;i++) {
+ struct security_ace *ace = &sd->dacl->aces[i];
+ ids[i].unixid = NULL;
+ ids[i].sid = dom_sid_dup(ids, &ace->trustee);
+ if (ids[i].sid == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ ids[i].status = NT_STATUS_NONE_MAPPED;
+ }
+
+ ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx,ids, acl.a_count, ids);
+ if (ctx == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = wbc_sids_to_xids_recv(ctx, &ids);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return status;
+ }
+
for (i=0;i<acl.a_count;i++) {
struct nfs4ace *a = &acl.ace[i];
struct security_ace *ace = &sd->dacl->aces[i];
a->e_type = ace->type;
a->e_flags = ace->flags;
a->e_mask = ace->access_mask;
- if (sidmap_sid_is_group(pvfs->sidmap, &ace->trustee)) {
- gid_t gid;
+ if (ids[i].unixid->type != ID_TYPE_UID) {
a->e_flags |= ACE4_IDENTIFIER_GROUP;
- status = sidmap_sid_to_unixgid(pvfs->sidmap, &ace->trustee, &gid);
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(tmp_ctx);
- return status;
- }
- a->e_id = gid;
- } else {
- uid_t uid;
- status = sidmap_sid_to_unixuid(pvfs->sidmap, &ace->trustee, &uid);
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(tmp_ctx);
- return status;
- }
- a->e_id = uid;
}
+ a->e_id = ids[i].unixid->id;
a->e_who = "";
}
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index ca874d1db1..ebc2d88e70 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -222,8 +222,10 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
event_context_find(pvfs),
pvfs->ntvfs->ctx->config);
- pvfs->sidmap = sidmap_open(pvfs, pvfs->ntvfs->ctx->lp_ctx);
- if (pvfs->sidmap == NULL) {
+ pvfs->wbc_ctx = wbc_init(pvfs,
+ pvfs->ntvfs->ctx->msg_ctx,
+ pvfs->ntvfs->ctx->event_ctx);
+ if (pvfs->wbc_ctx == NULL) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 4d22a91714..441424142f 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -26,6 +26,7 @@
#include "system/filesys.h"
#include "ntvfs/ntvfs.h"
#include "ntvfs/common/ntvfs_common.h"
+#include "libcli/wbclient/wbclient.h"
#include "dsdb/samdb/samdb.h"
struct pvfs_wait;
@@ -46,7 +47,7 @@ struct pvfs_state {
struct brl_context *brl_context;
struct odb_context *odb_context;
struct notify_context *notify_context;
- struct sidmap_context *sidmap;
+ struct wbc_context *wbc_ctx;
/* a list of pending async requests. Needed to support
ntcancel */
diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c
index 63889c6677..66c2cfaf4c 100644
--- a/source4/ntvfs/unixuid/vfs_unixuid.c
+++ b/source4/ntvfs/unixuid/vfs_unixuid.c
@@ -25,11 +25,11 @@
#include "system/passwd.h"
#include "auth/auth.h"
#include "ntvfs/ntvfs.h"
-#include "dsdb/samdb/samdb.h"
+#include "libcli/wbclient/wbclient.h"
#include "param/param.h"
struct unixuid_private {
- struct sidmap_context *sidmap;
+ struct wbc_context *wbc_ctx;
struct unix_sec_ctx *last_sec_ctx;
struct security_token *last_token;
};
@@ -100,9 +100,11 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs,
struct security_token *token,
struct unix_sec_ctx **sec)
{
- struct unixuid_private *private = ntvfs->private_data;
+ struct unixuid_private *priv = ntvfs->private_data;
int i;
NTSTATUS status;
+ struct id_mapping *ids;
+ struct composite_context *ctx;
*sec = talloc(req, struct unix_sec_ctx);
/* we can't do unix security without a user and group */
@@ -110,29 +112,53 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs,
return NT_STATUS_ACCESS_DENIED;
}
- status = sidmap_sid_to_unixuid(private->sidmap,
- token->user_sid, &(*sec)->uid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ ids = talloc_array(req, struct id_mapping, token->num_sids);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
- status = sidmap_sid_to_unixgid(private->sidmap,
- token->group_sid, &(*sec)->gid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ ids[0].unixid = NULL;
+ ids[0].sid = token->user_sid;
+ ids[0].status = NT_STATUS_NONE_MAPPED;
+
+ ids[1].unixid = NULL;
+ ids[1].sid = token->group_sid;
+ ids[1].status = NT_STATUS_NONE_MAPPED;
(*sec)->ngroups = token->num_sids - 2;
(*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups);
- if ((*sec)->groups == NULL) {
- return NT_STATUS_NO_MEMORY;
+ NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);
+
+ for (i=0;i<(*sec)->ngroups;i++) {
+ ids[i+2].unixid = NULL;
+ ids[i+2].sid = token->sids[i+2];
+ ids[i+2].status = NT_STATUS_NONE_MAPPED;
+ }
+
+ ctx = wbc_sids_to_xids_send(priv->wbc_ctx, ids, token->num_sids, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_sids_to_xids_recv(ctx, &ids);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ if (ids[0].unixid->type == ID_TYPE_BOTH ||
+ ids[0].unixid->type == ID_TYPE_UID) {
+ (*sec)->uid = ids[0].unixid->id;
+ } else {
+ return NT_STATUS_INVALID_SID;
+ }
+
+ if (ids[1].unixid->type == ID_TYPE_BOTH ||
+ ids[1].unixid->type == ID_TYPE_GID) {
+ (*sec)->gid = ids[1].unixid->id;
+ } else {
+ return NT_STATUS_INVALID_SID;
}
for (i=0;i<(*sec)->ngroups;i++) {
- status = sidmap_sid_to_unixgid(private->sidmap,
- token->sids[i+2], &(*sec)->groups[i]);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (ids[i+2].unixid->type == ID_TYPE_BOTH ||
+ ids[i+2].unixid->type == ID_TYPE_GID) {
+ (*sec)->groups[i] = ids[i+2].unixid->id;
+ } else {
+ return NT_STATUS_INVALID_SID;
}
}
@@ -216,9 +242,11 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
return NT_STATUS_NO_MEMORY;
}
- private->sidmap = sidmap_open(private, ntvfs->ctx->lp_ctx);
- if (private->sidmap == NULL) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ private->wbc_ctx = wbc_init(private, ntvfs->ctx->msg_ctx,
+ ntvfs->ctx->event_ctx);
+ if (private->wbc_ctx == NULL) {
+ talloc_free(private);
+ return NT_STATUS_INTERNAL_ERROR;
}
ntvfs->private_data = private;
diff --git a/source4/pidl/config.m4 b/source4/pidl/config.m4
new file mode 100644
index 0000000000..8b8bc5acf0
--- /dev/null
+++ b/source4/pidl/config.m4
@@ -0,0 +1,9 @@
+# Check whether ExtUtils::ExtMaker is available
+
+if perl -e "use ExtUtils::MakeMaker" 2>/dev/null; then
+ HAVE_PERL_EXTUTILS_MAKEMAKER=1
+else
+ HAVE_PERL_EXTUTILS_MAKEMAKER=0
+fi
+
+AC_SUBST(HAVE_PERL_EXTUTILS_MAKEMAKER)
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index 1d1c51cc6e..d6d77dd0d9 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -82,7 +82,8 @@ PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SAMDB \
NDR_UNIXINFO \
- NSS_WRAPPER
+ NSS_WRAPPER \
+ LIBWBCLIENT
# End MODULE dcerpc_unixinfo
################################################
diff --git a/source4/rpc_server/lsa/lsa.h b/source4/rpc_server/lsa/lsa.h
index db148d3dcb..b7c41486a2 100644
--- a/source4/rpc_server/lsa/lsa.h
+++ b/source4/rpc_server/lsa/lsa.h
@@ -40,7 +40,6 @@
struct lsa_policy_state {
struct dcesrv_handle *handle;
struct ldb_context *sam_ldb;
- struct sidmap_context *sidmap;
uint32_t access_mask;
struct ldb_dn *domain_dn;
struct ldb_dn *forest_dn;
diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c
index 57599b96a2..4dcd606435 100644
--- a/source4/rpc_server/lsa/lsa_init.c
+++ b/source4/rpc_server/lsa/lsa_init.c
@@ -57,11 +57,6 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
- state->sidmap = sidmap_open(state, dce_call->conn->dce_ctx->lp_ctx);
- if (state->sidmap == NULL) {
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
/* work out the domain_dn - useful for so many calls its worth
fetching here */
state->domain_dn = samdb_base_dn(state->sam_ldb);
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index e01efa8233..c6b9e3bd40 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -360,7 +360,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
return NT_STATUS_OK;
}
- /* need to add a call into sidmap to check for a allocated sid */
+ /* need to check for an allocated sid */
return NT_STATUS_INVALID_SID;
}
@@ -466,8 +466,7 @@ static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX
return NT_STATUS_OK;
}
- /* need to re-add a call into sidmap to check for a allocated sid */
- /* status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, rtype); */
+ /* need to re-add a check for an allocated sid */
return NT_STATUS_NOT_FOUND;
}
diff --git a/source4/rpc_server/unixinfo/dcesrv_unixinfo.c b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c
index 2c08d501d1..e6313b771c 100644
--- a/source4/rpc_server/unixinfo/dcesrv_unixinfo.c
+++ b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c
@@ -23,53 +23,100 @@
#include "rpc_server/dcerpc_server.h"
#include "rpc_server/common/common.h"
#include "librpc/gen_ndr/ndr_unixinfo.h"
+#include "libcli/wbclient/wbclient.h"
#include "lib/events/events.h"
-#include "dsdb/samdb/samdb.h"
#include "system/passwd.h"
#include "param/param.h"
+static NTSTATUS dcerpc_unixinfo_bind(struct dcesrv_call_state *dce_call,
+ const struct dcesrv_interface *iface)
+{
+ struct wbc_context *wbc_ctx;
+
+ wbc_ctx = wbc_init(dce_call->context, dce_call->msg_ctx,
+ dce_call->event_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(wbc_ctx);
+
+ dce_call->context->private = wbc_ctx;
+
+ return NT_STATUS_OK;
+}
+
+#define DCESRV_INTERFACE_UNIXINFO_BIND dcerpc_unixinfo_bind
+
static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct unixinfo_SidToUid *r)
{
NTSTATUS status;
- struct sidmap_context *sidmap;
- uid_t uid;
+ struct wbc_context *wbc_ctx = talloc_get_type_abort(
+ dce_call->context->private,
+ struct wbc_context);
+ struct id_mapping *ids;
+ struct composite_context *ctx;
- sidmap = sidmap_open(mem_ctx, dce_call->conn->dce_ctx->lp_ctx);
- if (sidmap == NULL) {
- DEBUG(10, ("sidmap_open failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n"));
+
+ ids = talloc(mem_ctx, struct id_mapping);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
- status = sidmap_sid_to_unixuid(sidmap, &r->in.sid, &uid);
+ ids->sid = &r->in.sid;
+ ids->status = NT_STATUS_NONE_MAPPED;
+ ids->unixid = NULL;
+ ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_sids_to_xids_recv(ctx, &ids);
NT_STATUS_NOT_OK_RETURN(status);
- *r->out.uid = uid;
- return NT_STATUS_OK;
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_UID) {
+ *r->out.uid = ids->unixid->id;
+ return NT_STATUS_OK;
+ } else {
+ return NT_STATUS_INVALID_SID;
+ }
}
static NTSTATUS dcesrv_unixinfo_UidToSid(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct unixinfo_UidToSid *r)
{
- struct sidmap_context *sidmap;
- uid_t uid;
-
- sidmap = sidmap_open(mem_ctx, dce_call->conn->dce_ctx->lp_ctx);
- if (sidmap == NULL) {
- DEBUG(10, ("sidmap_open failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ struct wbc_context *wbc_ctx = talloc_get_type_abort(
+ dce_call->context->private,
+ struct wbc_context);
+ struct id_mapping *ids;
+ struct composite_context *ctx;
+ uint32_t uid;
+ NTSTATUS status;
- uid = r->in.uid; /* This cuts uid to (probably) 32 bit */
+ DEBUG(5, ("dcesrv_unixinfo_UidToSid called\n"));
+ uid = r->in.uid; /* This cuts uid to 32 bit */
if ((uint64_t)uid != r->in.uid) {
DEBUG(10, ("uid out of range\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- return sidmap_uid_to_sid(sidmap, mem_ctx, uid, &r->out.sid);
+ ids = talloc(mem_ctx, struct id_mapping);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids->sid = NULL;
+ ids->status = NT_STATUS_NONE_MAPPED;
+ ids->unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids->unixid);
+
+ ids->unixid->id = uid;
+ ids->unixid->type = ID_TYPE_UID;
+
+ ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_xids_to_sids_recv(ctx, &ids);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ r->out.sid = ids->sid;
+ return NT_STATUS_OK;
}
static NTSTATUS dcesrv_unixinfo_SidToGid(struct dcesrv_call_state *dce_call,
@@ -77,43 +124,74 @@ static NTSTATUS dcesrv_unixinfo_SidToGid(struct dcesrv_call_state *dce_call,
struct unixinfo_SidToGid *r)
{
NTSTATUS status;
- struct sidmap_context *sidmap;
- gid_t gid;
+ struct wbc_context *wbc_ctx = talloc_get_type_abort(
+ dce_call->context->private,
+ struct wbc_context);
+ struct id_mapping *ids;
+ struct composite_context *ctx;
- sidmap = sidmap_open(mem_ctx, dce_call->conn->dce_ctx->lp_ctx);
- if (sidmap == NULL) {
- DEBUG(10, ("sidmap_open failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n"));
- status = sidmap_sid_to_unixgid(sidmap, &r->in.sid, &gid);
+ ids = talloc(mem_ctx, struct id_mapping);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids->sid = &r->in.sid;
+ ids->status = NT_STATUS_NONE_MAPPED;
+ ids->unixid = NULL;
+ ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_sids_to_xids_recv(ctx, &ids);
NT_STATUS_NOT_OK_RETURN(status);
- *r->out.gid = gid;
- return NT_STATUS_OK;
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_GID) {
+ *r->out.gid = ids->unixid->id;
+ return NT_STATUS_OK;
+ } else {
+ return NT_STATUS_INVALID_SID;
+ }
}
static NTSTATUS dcesrv_unixinfo_GidToSid(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct unixinfo_GidToSid *r)
{
- struct sidmap_context *sidmap;
- gid_t gid;
-
- sidmap = sidmap_open(mem_ctx, dce_call->conn->dce_ctx->lp_ctx);
- if (sidmap == NULL) {
- DEBUG(10, ("sidmap_open failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ struct wbc_context *wbc_ctx = talloc_get_type_abort(
+ dce_call->context->private,
+ struct wbc_context);
+ struct id_mapping *ids;
+ struct composite_context *ctx;
+ uint32_t gid;
+ NTSTATUS status;
- gid = r->in.gid; /* This cuts gid to (probably) 32 bit */
+ DEBUG(5, ("dcesrv_unixinfo_GidToSid called\n"));
+ gid = r->in.gid; /* This cuts gid to 32 bit */
if ((uint64_t)gid != r->in.gid) {
DEBUG(10, ("gid out of range\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- return sidmap_gid_to_sid(sidmap, mem_ctx, gid, &r->out.sid);
+ ids = talloc(mem_ctx, struct id_mapping);
+ NT_STATUS_HAVE_NO_MEMORY(ids);
+
+ ids->sid = NULL;
+ ids->status = NT_STATUS_NONE_MAPPED;
+ ids->unixid = talloc(ids, struct unixid);
+ NT_STATUS_HAVE_NO_MEMORY(ids->unixid);
+
+ ids->unixid->id = gid;
+ ids->unixid->type = ID_TYPE_GID;
+
+ ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ status = wbc_xids_to_sids_recv(ctx, &ids);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ r->out.sid = ids->sid;
+ return NT_STATUS_OK;
}
static NTSTATUS dcesrv_unixinfo_GetPWUid(struct dcesrv_call_state *dce_call,
diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py
new file mode 100644
index 0000000000..355565968a
--- /dev/null
+++ b/source4/scripting/python/samba/idmap.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation.
+# Copyright (C) 2008 Kai Blin <kai@samba.org>
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Convenience functions for using the idmap database."""
+
+import samba
+import ldb
+
+class IDmapDB(samba.Ldb):
+ """The IDmap database."""
+
+ # Mappings for ID_TYPE_UID, ID_TYPE_GID and ID_TYPE_BOTH
+ TYPE_UID = 1
+ TYPE_GID = 2
+ TYPE_BOTH = 3
+
+ def __init__(self, url=None, session_info=None, credentials=None,
+ modules_dir=None, lp=None):
+ """Open the IDmap Database.
+
+ :param url: URL of the database.
+ """
+ super(IDmapDB, self).__init__(session_info=session_info, credentials=credentials,
+ modules_dir=modules_dir, lp=lp)
+ if url:
+ self.connect(url)
+
+
+ def setup_name_mapping(self, sid, type, unixid):
+ """Setup a mapping between a sam name and a unix name.
+
+ :param sid: SID of the NT-side of the mapping.
+ :param unixname: Unix name to map to.
+ """
+ type_string = ""
+ if type == self.TYPE_UID:
+ type_string = "ID_TYPE_UID"
+ elif type == self.TYPE_GID:
+ type_string = "ID_TYPE_GID"
+ elif type == self.TYPE_BOTH:
+ type_string = "ID_TYPE_BOTH"
+ else:
+ return
+
+ mod = """
+dn: CN=%s
+xidNumber: %s
+objectSid: %s
+objectClass: sidMap
+type: %s
+cn: %s
+
+""" % (sid, unixid, sid, type_string, sid)
+ self.add(self.parse_ldif(mod).next()[1])
+
+
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index dfeb61e52b..6917aa1a54 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -35,6 +35,7 @@ import samba
from auth import system_session
from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
from samba.samdb import SamDB
+from samba.idmap import IDmapDB
import security
import urllib
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
@@ -397,45 +398,30 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol
return lp
-def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
- wheel, backup):
+def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid,
+ users_gid, wheel_gid):
"""setup reasonable name mappings for sam names to unix names.
-
- :param ldb: SamDB object.
+
+ :param samdb: SamDB object.
+ :param idmap: IDmap db object.
:param sid: The domain sid.
:param domaindn: The domain DN.
- :param root: Name of the UNIX root user.
- :param nobody: Name of the UNIX nobody user.
- :param nogroup: Name of the unix nobody group.
- :param users: Name of the unix users group.
- :param wheel: Name of the wheel group (users that can become root).
- :param backup: Name of the backup group."""
+ :param root_uid: uid of the UNIX root user.
+ :param nobody_uid: uid of the UNIX nobody user.
+ :param users_gid: gid of the UNIX users group.
+ :param wheel_gid: gid of the UNIX wheel group."""
# add some foreign sids if they are not present already
- ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous")
- ldb.add_foreign(domaindn, "S-1-1-0", "World")
- ldb.add_foreign(domaindn, "S-1-5-2", "Network")
- ldb.add_foreign(domaindn, "S-1-5-18", "System")
- ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users")
-
- # some well known sids
- ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody)
- ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup)
- ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup)
- ldb.setup_name_mapping(domaindn, "S-1-5-18", root)
- ldb.setup_name_mapping(domaindn, "S-1-5-11", users)
- ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel)
- ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users)
- ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup)
- ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup)
-
- # and some well known domain rids
- ldb.setup_name_mapping(domaindn, sid + "-500", root)
- ldb.setup_name_mapping(domaindn, sid + "-518", wheel)
- ldb.setup_name_mapping(domaindn, sid + "-519", wheel)
- ldb.setup_name_mapping(domaindn, sid + "-512", wheel)
- ldb.setup_name_mapping(domaindn, sid + "-513", users)
- ldb.setup_name_mapping(domaindn, sid + "-520", wheel)
+ samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous")
+ samdb.add_foreign(domaindn, "S-1-1-0", "World")
+ samdb.add_foreign(domaindn, "S-1-5-2", "Network")
+ samdb.add_foreign(domaindn, "S-1-5-18", "System")
+ samdb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users")
+
+ idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid)
+ idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid)
+ idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid)
+ idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid)
def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
credentials, names,
@@ -663,8 +649,8 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp):
if os.path.exists(path):
os.unlink(path)
- idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials,
- lp=lp)
+ idmap_ldb = IDmapDB(path, session_info=session_info,
+ credentials=credentials, lp=lp)
idmap_ldb.erase()
idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif"))
@@ -924,18 +910,21 @@ def provision(setup_dir, message, session_info,
if dnspass is None:
dnspass = misc.random_password(12)
if root is None:
- root = findnss(pwd.getpwnam, ["root"])[0]
+ root_uid = findnss(pwd.getpwnam, ["root"])[2]
+ else:
+ root_uid = findnss(pwd.getpwnam, [root])[2]
if nobody is None:
- nobody = findnss(pwd.getpwnam, ["nobody"])[0]
- if nogroup is None:
- nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0]
+ nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2]
+ else:
+ nobody_uid = findnss(pwd.getpwnam, [nobody])[2]
if users is None:
- users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown",
- "usr"])[0]
+ users_gid = findnss(grp.getgrnam, ["users"])[2]
+ else:
+ users_gid = findnss(grp.getgrnam, [users])[2]
if wheel is None:
- wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0]
- if backup is None:
- backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0]
+ wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2]
+ else:
+ wheel_gid = findnss(grp.getgrnam, [wheel])[2]
if aci is None:
aci = "# no aci for local ldb"
@@ -994,8 +983,8 @@ def provision(setup_dir, message, session_info,
credentials=credentials, lp=lp)
message("Setting up idmap db")
- setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info,
- credentials=credentials, lp=lp)
+ idmap = setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info,
+ credentials=credentials, lp=lp)
samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info,
credentials=credentials, lp=lp, names=names,
@@ -1026,11 +1015,11 @@ def provision(setup_dir, message, session_info,
machinepass=machinepass, dnsdomain=names.dnsdomain)
if samdb_fill == FILL_FULL:
- setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root,
- nobody=nobody, nogroup=nogroup, wheel=wheel,
- users=users, backup=backup)
-
- message("Compleating sam.ldb setup by marking as synchronized")
+ setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn,
+ root_uid=root_uid, nobody_uid=nobody_uid,
+ users_gid=users_gid, wheel_gid=wheel_gid)
+
+ message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
# Only make a zone file on the first DC, it should be replicated with DNS replication
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index de0fd4ba04..bc3eef7879 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -53,25 +53,6 @@ description: %s
for msg in self.parse_ldif(add):
self.add(msg[1])
- def setup_name_mapping(self, domaindn, sid, unixname):
- """Setup a mapping between a sam name and a unix name.
-
- :param domaindn: DN of the domain.
- :param sid: SID of the NT-side of the mapping.
- :param unixname: Unix name to map to.
- """
- res = self.search(domaindn, ldb.SCOPE_SUBTREE,
- "objectSid=%s" % sid, ["dn"])
- assert len(res) == 1, "Failed to find record for objectSid %s" % sid
-
- mod = """
-dn: %s
-changetype: modify
-replace: unixName
-unixName: %s
-""" % (res[0].dn, unixname)
- self.modify(self.parse_ldif(mod).next()[1])
-
def enable_account(self, user_dn):
"""Enable an account.
diff --git a/source4/winbind/idmap.c b/source4/winbind/idmap.c
index de8a43ec02..92ac41f1d2 100644
--- a/source4/winbind/idmap.c
+++ b/source4/winbind/idmap.c
@@ -210,13 +210,26 @@ NTSTATUS idmap_xid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
NTSTATUS status = NT_STATUS_NONE_MAPPED;
struct ldb_context *ldb = idmap_ctx->ldb_ctx;
struct ldb_result *res = NULL;
- uint32_t low, high;
struct dom_sid *unix_sid, *new_sid;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ const char *id_type;
+
+ switch (unixid->type) {
+ case ID_TYPE_UID:
+ id_type = "ID_TYPE_UID";
+ break;
+ case ID_TYPE_GID:
+ id_type = "ID_TYPE_GID";
+ break;
+ default:
+ DEBUG(1, ("unixid->type must be type gid or uid\n"));
+ status = NT_STATUS_NONE_MAPPED;
+ goto failed;
+ }
ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
- unixid->id);
+ NULL, "(&(|(type=ID_TYPE_BOTH)(type=%s))"
+ "(xidNumber=%u))", id_type, unixid->id);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
status = NT_STATUS_NONE_MAPPED;
@@ -235,40 +248,9 @@ NTSTATUS idmap_xid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- DEBUG(6, ("xid not found in idmap db, trying to allocate SID.\n"));
-
- /* Now redo the search to make sure noone added a mapping for that SID
- * while we weren't looking.*/
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
- unixid->id);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count > 0) {
- DEBUG(1, ("sidMap modified while trying to add a mapping.\n"));
- status = NT_STATUS_RETRY;
- goto failed;
- }
-
- ret = idmap_get_bounds(idmap_ctx, &low, &high);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to get id bounds from db: %u\n", ret));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (unixid->id >= low && unixid->id <= high) {
- /* An existing xid would have been mapped before */
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
+ DEBUG(6, ("xid not found in idmap db, create S-1-22- SID.\n"));
- /* For local users, we just create a rid = uid +1, so root doesn't end
- * up with a 0 rid */
+ /* For local users/groups , we just create a rid = uid/gid */
if (unixid->type == ID_TYPE_UID) {
unix_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-1");
} else {
@@ -279,7 +261,7 @@ NTSTATUS idmap_xid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- new_sid = dom_sid_add_rid(mem_ctx, unix_sid, unixid->id + 1);
+ new_sid = dom_sid_add_rid(mem_ctx, unix_sid, unixid->id);
if (new_sid == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
@@ -326,42 +308,27 @@ NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
bool hwm_entry_exists;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(objectSid=%s))",
- ldap_encode_ndr_dom_sid(tmp_ctx, sid));
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count == 1) {
- new_xid = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber",
- -1);
- if (new_xid == (uint32_t) -1) {
- DEBUG(1, ("Invalid xid mapping.\n"));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
+ if (dom_sid_in_domain(idmap_ctx->unix_users_sid, sid)) {
+ uint32_t rid;
+ DEBUG(6, ("This is a local unix uid, just calculate that.\n"));
+ status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
*unixid = talloc(mem_ctx, struct unixid);
if (*unixid == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
-
- (*unixid)->id = new_xid;
- (*unixid)->type = ID_TYPE_BOTH;
+ (*unixid)->id = rid;
+ (*unixid)->type = ID_TYPE_UID;
talloc_free(tmp_ctx);
return NT_STATUS_OK;
}
- DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
-
- if (dom_sid_in_domain(idmap_ctx->unix_users_sid, sid)) {
+ if (dom_sid_in_domain(idmap_ctx->unix_groups_sid, sid)) {
uint32_t rid;
- DEBUG(6, ("This is a local unix uid, just calculate that.\n"));
+ DEBUG(6, ("This is a local unix gid, just calculate that.\n"));
status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
if (!NT_STATUS_IS_OK(status)) goto failed;
@@ -370,30 +337,60 @@ NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
status = NT_STATUS_NO_MEMORY;
goto failed;
}
- (*unixid)->id = rid - 1;
- (*unixid)->type = ID_TYPE_UID;
+ (*unixid)->id = rid;
+ (*unixid)->type = ID_TYPE_GID;
talloc_free(tmp_ctx);
return NT_STATUS_OK;
+ }
+
+ ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
+ NULL, "(&(objectClass=sidMap)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(tmp_ctx, sid));
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
+ status = NT_STATUS_NONE_MAPPED;
+ goto failed;
}
- if (dom_sid_in_domain(idmap_ctx->unix_groups_sid, sid)) {
- uint32_t rid;
- DEBUG(6, ("This is a local unix gid, just calculate that.\n"));
- status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
- if (!NT_STATUS_IS_OK(status)) goto failed;
+ if (res->count == 1) {
+ const char *type = ldb_msg_find_attr_as_string(res->msgs[0],
+ "type", NULL);
+ new_xid = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber",
+ -1);
+ if (new_xid == (uint32_t) -1) {
+ DEBUG(1, ("Invalid xid mapping.\n"));
+ status = NT_STATUS_NONE_MAPPED;
+ goto failed;
+ }
+
+ if (type == NULL) {
+ DEBUG(1, ("Invalid type for mapping entry.\n"));
+ status = NT_STATUS_NONE_MAPPED;
+ goto failed;
+ }
*unixid = talloc(mem_ctx, struct unixid);
if (*unixid == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
- (*unixid)->id = rid - 1;
- (*unixid)->type = ID_TYPE_GID;
+
+ (*unixid)->id = new_xid;
+
+ if (strcmp(type, "ID_TYPE_BOTH") == 0) {
+ (*unixid)->type = ID_TYPE_BOTH;
+ } else if (strcmp(type, "ID_TYPE_UID") == 0) {
+ (*unixid)->type = ID_TYPE_UID;
+ } else {
+ (*unixid)->type = ID_TYPE_GID;
+ }
talloc_free(tmp_ctx);
return NT_STATUS_OK;
- }
+ }
+
+ DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
trans = ldb_transaction_start(ldb);
if (trans != LDB_SUCCESS) {
@@ -585,6 +582,12 @@ NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
+ ret = ldb_msg_add_string(map_msg, "type", "ID_TYPE_BOTH");
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NONE_MAPPED;
+ goto failed;
+ }
+
ret = ldb_msg_add_string(map_msg, "cn", sid_string);
if (ret != LDB_SUCCESS) {
status = NT_STATUS_NONE_MAPPED;
diff --git a/source4/winbind/idmap.h b/source4/winbind/idmap.h
index 045d50c568..6eae92cc68 100644
--- a/source4/winbind/idmap.h
+++ b/source4/winbind/idmap.h
@@ -22,6 +22,8 @@
#ifndef _IDMAP_H_
#define _IDMAP_H_
+#include "librpc/gen_ndr/winbind.h"
+
struct idmap_context {
struct loadparm_context *lp_ctx;
struct ldb_context *ldb_ctx;
@@ -29,24 +31,6 @@ struct idmap_context {
struct dom_sid *unix_users_sid;
};
-enum id_type {
- ID_TYPE_NOT_SPECIFIED = 0,
- ID_TYPE_UID,
- ID_TYPE_GID,
- ID_TYPE_BOTH
-};
-
-struct unixid {
- uint32_t id;
- enum id_type type;
-};
-
-struct id_mapping {
- struct unixid *unixid;
- struct dom_sid *sid;
- NTSTATUS status;
-};
-
#include "winbind/idmap_proto.h"
#endif
diff --git a/source4/winbind/wb_irpc.c b/source4/winbind/wb_irpc.c
index 5d7f7fd7a6..0535045adb 100644
--- a/source4/winbind/wb_irpc.c
+++ b/source4/winbind/wb_irpc.c
@@ -22,6 +22,7 @@
#include "winbind/wb_server.h"
#include "lib/messaging/irpc.h"
#include "libcli/composite/composite.h"
+#include "libcli/security/proto.h"
#include "librpc/gen_ndr/ndr_winbind.h"
#include "smbd/service_task.h"
@@ -71,6 +72,71 @@ static void wb_irpc_SamLogon_callback(struct composite_context *ctx)
irpc_send_reply(s->msg, status);
}
+struct wb_irpc_get_idmap_state {
+ struct irpc_message *msg;
+ struct winbind_get_idmap *req;
+ int level;
+};
+
+static void wb_irpc_get_idmap_callback(struct composite_context *ctx);
+
+static NTSTATUS wb_irpc_get_idmap(struct irpc_message *msg,
+ struct winbind_get_idmap *req)
+{
+ struct wbsrv_service *service = talloc_get_type(msg->private,
+ struct wbsrv_service);
+ struct wb_irpc_get_idmap_state *s;
+ struct composite_context *ctx;
+
+ DEBUG(5, ("wb_irpc_get_idmap called\n"));
+
+ s = talloc(msg, struct wb_irpc_get_idmap_state);
+ NT_STATUS_HAVE_NO_MEMORY(s);
+
+ s->msg = msg;
+ s->req = req;
+ s->level = req->in.level;
+
+ switch(s->level) {
+ case WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS:
+ ctx = wb_sids2xids_send(msg, service, req->in.count,
+ req->in.ids);
+ break;
+ case WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS:
+ ctx = wb_xids2sids_send(msg, service, req->in.count,
+ req->in.ids);
+ break;
+ }
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ composite_continue(ctx, ctx, wb_irpc_get_idmap_callback, s);
+ msg->defer_reply = true;
+
+ return NT_STATUS_OK;
+}
+
+static void wb_irpc_get_idmap_callback(struct composite_context *ctx)
+{
+ struct wb_irpc_get_idmap_state *s;
+ NTSTATUS status;
+
+ DEBUG(5, ("wb_irpc_get_idmap_callback called\n"));
+
+ s = talloc_get_type(ctx->async.private_data,
+ struct wb_irpc_get_idmap_state);
+
+ switch(s->level) {
+ case WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS:
+ status = wb_sids2xids_recv(ctx, &s->req->out.ids);
+ break;
+ case WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS:
+ status = wb_xids2sids_recv(ctx, &s->req->out.ids);
+ break;
+ }
+
+ irpc_send_reply(s->msg, status);
+}
+
NTSTATUS wbsrv_init_irpc(struct wbsrv_service *service)
{
NTSTATUS status;
@@ -81,5 +147,9 @@ NTSTATUS wbsrv_init_irpc(struct wbsrv_service *service)
wb_irpc_SamLogon, service);
NT_STATUS_NOT_OK_RETURN(status);
+ status = IRPC_REGISTER(service->task->msg_ctx, winbind, WINBIND_GET_IDMAP,
+ wb_irpc_get_idmap, service);
+ NT_STATUS_NOT_OK_RETURN(status);
+
return NT_STATUS_OK;
}
diff --git a/source4/winbind/wb_xids2sids.c b/source4/winbind/wb_xids2sids.c
index 843d292c07..1be394d276 100644
--- a/source4/winbind/wb_xids2sids.c
+++ b/source4/winbind/wb_xids2sids.c
@@ -41,7 +41,7 @@ struct composite_context *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
struct composite_context *result;
struct xids2sids_state *state;
- DEBUG(0, ("wb_xids2sids_send called\n"));
+ DEBUG(5, ("wb_xids2sids_send called\n"));
result = composite_create(mem_ctx, service->task->event_ctx);
if (!result) return NULL;
@@ -68,7 +68,7 @@ NTSTATUS wb_xids2sids_recv(struct composite_context *ctx,
{
NTSTATUS status = composite_wait(ctx);
- DEBUG(0, ("wb_xids2sids_recv called.\n"));
+ DEBUG(5, ("wb_xids2sids_recv called.\n"));
if (NT_STATUS_IS_OK(status)) {
struct xids2sids_state *state =