mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into openchange
Conflicts:
source/headermap.txt
(This used to be commit 1b084e85c1
)
This commit is contained in:
commit
30ccc36b8d
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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 \
|
||||
|
6
source4/libcli/wbclient/config.mk
Normal file
6
source4/libcli/wbclient/config.mk
Normal file
@ -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
|
210
source4/libcli/wbclient/wbclient.c
Normal file
210
source4/libcli/wbclient/wbclient.c
Normal file
@ -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;
|
||||
}
|
||||
|
50
source4/libcli/wbclient/wbclient.h
Normal file
50
source4/libcli/wbclient/wbclient.h
Normal file
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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[]
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 = "";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
9
source4/pidl/config.m4
Normal file
9
source4/pidl/config.m4
Normal file
@ -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)
|
@ -82,7 +82,8 @@ PRIVATE_DEPENDENCIES = \
|
||||
DCERPC_COMMON \
|
||||
SAMDB \
|
||||
NDR_UNIXINFO \
|
||||
NSS_WRAPPER
|
||||
NSS_WRAPPER \
|
||||
LIBWBCLIENT
|
||||
# End MODULE dcerpc_unixinfo
|
||||
################################################
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"));
|
||||
|
||||
status = sidmap_sid_to_unixuid(sidmap, &r->in.sid, &uid);
|
||||
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.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;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
|
73
source4/scripting/python/samba/idmap.py
Normal file
73
source4/scripting/python/samba/idmap.py
Normal file
@ -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])
|
||||
|
||||
|
@ -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")
|
||||
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")
|
||||
|
||||
# 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)
|
||||
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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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"));
|
||||
DEBUG(6, ("xid not found in idmap db, create S-1-22- 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;
|
||||
}
|
||||
|
||||
/* 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,39 +308,6 @@ 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;
|
||||
}
|
||||
|
||||
*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;
|
||||
|
||||
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)) {
|
||||
uint32_t rid;
|
||||
DEBUG(6, ("This is a local unix uid, just calculate that.\n"));
|
||||
@ -370,7 +319,7 @@ 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)->id = rid;
|
||||
(*unixid)->type = ID_TYPE_UID;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
@ -388,13 +337,61 @@ 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)->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 (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 = 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) {
|
||||
status = NT_STATUS_NONE_MAPPED;
|
||||
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 =
|
||||
|
Loading…
Reference in New Issue
Block a user