1
0
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:
Jelmer Vernooij 2008-04-04 16:02:17 +02:00
commit 30ccc36b8d
29 changed files with 943 additions and 287 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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 \

View 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

View 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;
}

View 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);

View File

@ -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 */

View File

@ -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[]
);
}

View File

@ -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;

View File

@ -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 = "";
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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
View 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)

View File

@ -82,7 +82,8 @@ PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SAMDB \
NDR_UNIXINFO \
NSS_WRAPPER
NSS_WRAPPER \
LIBWBCLIENT
# End MODULE dcerpc_unixinfo
################################################

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View 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])

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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 =