1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

ntvfs: Use wbclient for pvfs_acl and pvfs_acl_nfs4

This commit is contained in:
Kai Blin 2008-03-28 23:29:01 +01:00
parent 2908a77fa5
commit ac5e5fee1d
4 changed files with 166 additions and 49 deletions

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