diff options
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl.c | 100 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl_nfs4.c | 106 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 6 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 3 |
4 files changed, 166 insertions, 49 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 5070f6852d..2393a2e7a3 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -126,6 +126,8 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, NTSTATUS status; struct security_ace ace; mode_t mode; + struct id_mapping *ids; + struct composite_context *ctx; *psd = security_descriptor_initialise(req); if (*psd == NULL) { @@ -133,15 +135,33 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } sd = *psd; - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids = talloc_array(sd, struct id_mapping, 2); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = wbc_xids_to_sids_recv(ctx, &ids); + NT_STATUS_NOT_OK_RETURN(status); + + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); + + talloc_free(ids); sd->type |= SEC_DESC_DACL_PRESENT; mode = name->st.st_mode; @@ -248,6 +268,8 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, gid_t old_gid = -1; uid_t new_uid = -1; gid_t new_gid = -1; + struct id_mapping *ids; + struct composite_context *ctx; if (pvfs->acl_ops != NULL) { status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd); @@ -259,6 +281,12 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return status; } + ids = talloc(req, struct id_mapping); + NT_STATUS_HAVE_NO_MEMORY(ids); + ids->unixid = NULL; + ids->sid = NULL; + ids->status = NT_STATUS_NONE_MAPPED; + new_sd = info->set_secdesc.in.sd; orig_sd = *sd; @@ -271,8 +299,16 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) { - status = sidmap_sid_to_unixuid(pvfs->sidmap, new_sd->owner_sid, &new_uid); + ids->sid = new_sd->owner_sid; + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_sids_to_xids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + + if (ids->unixid->type == ID_TYPE_BOTH || + ids->unixid->type == ID_TYPE_UID) { + new_uid = ids->unixid->id; + } } sd->owner_sid = new_sd->owner_sid; } @@ -281,8 +317,17 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) { - status = sidmap_sid_to_unixgid(pvfs->sidmap, new_sd->group_sid, &new_gid); + ids->sid = new_sd->group_sid; + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_sids_to_xids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + + if (ids->unixid->type == ID_TYPE_BOTH || + ids->unixid->type == ID_TYPE_GID) { + new_gid = ids->unixid->id; + } + } sd->group_sid = new_sd->group_sid; } @@ -664,6 +709,8 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, struct pvfs_filename *parent; struct security_descriptor *parent_sd, *sd; bool container; + struct id_mapping *ids; + struct composite_context *ctx; /* form the parents path */ status = pvfs_resolve_parent(pvfs, req, name, &parent); @@ -705,14 +752,31 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids = talloc_array(sd, struct id_mapping, 2); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[0].status = NT_STATUS_NONE_MAPPED; + + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + ids[1].status = NT_STATUS_NONE_MAPPED; + + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = wbc_xids_to_sids_recv(ctx, &ids); + NT_STATUS_NOT_OK_RETURN(status); + + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); sd->type |= SEC_DESC_DACL_PRESENT; diff --git a/source4/ntvfs/posix/pvfs_acl_nfs4.c b/source4/ntvfs/posix/pvfs_acl_nfs4.c index 2abb1482a4..fa855555b2 100644 --- a/source4/ntvfs/posix/pvfs_acl_nfs4.c +++ b/source4/ntvfs/posix/pvfs_acl_nfs4.c @@ -38,7 +38,9 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename NTSTATUS status; struct nfs4acl *acl; struct security_descriptor *sd; - int i; + int i, num_ids; + struct id_mapping *ids; + struct composite_context *ctx; acl = talloc_zero(mem_ctx, struct nfs4acl); NT_STATUS_HAVE_NO_MEMORY(acl); @@ -57,25 +59,57 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename sd = *psd; sd->type |= acl->a_flags; - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - NT_STATUS_NOT_OK_RETURN(status); - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); + + /* the number of ids to map is the acl count plus uid and gid */ + num_ids = acl->a_count +2; + ids = talloc_array(sd, struct id_mapping, num_ids); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[0].status = NT_STATUS_NONE_MAPPED; + + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + ids[1].status = NT_STATUS_NONE_MAPPED; + + for (i=0;i<acl->a_count;i++) { + struct nfs4ace *a = &acl->ace[i]; + ids[i+2].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[i+2].unixid); + ids[i+2].unixid->id = a->e_id; + if (a->e_flags & ACE4_IDENTIFIER_GROUP) { + ids[i+2].unixid->type = ID_TYPE_GID; + } else { + ids[i+2].unixid->type = ID_TYPE_UID; + } + ids[i+2].sid = NULL; + ids[i+2].status = NT_STATUS_NONE_MAPPED; + } + + /* Allocate memory for the sids from the security descriptor to be on + * the safe side. */ + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, sd, num_ids, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_xids_to_sids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); + for (i=0;i<acl->a_count;i++) { struct nfs4ace *a = &acl->ace[i]; struct security_ace ace; - struct dom_sid *sid; ace.type = a->e_type; ace.flags = a->e_flags; ace.access_mask = a->e_mask; - if (a->e_flags & ACE4_IDENTIFIER_GROUP) { - status = sidmap_gid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); - } else { - status = sidmap_uid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); - } - NT_STATUS_NOT_OK_RETURN(status); - ace.trustee = *sid; + ace.trustee = *ids[i+2].sid; security_descriptor_dacl_add(sd, &ace); } @@ -93,6 +127,8 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename struct nfs4acl acl; int i; TALLOC_CTX *tmp_ctx; + struct id_mapping *ids; + struct composite_context *ctx; tmp_ctx = talloc_new(pvfs); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); @@ -110,30 +146,44 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename return NT_STATUS_NO_MEMORY; } + ids = talloc_array(tmp_ctx, struct id_mapping, acl.a_count); + if (ids == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<acl.a_count;i++) { + struct security_ace *ace = &sd->dacl->aces[i]; + ids[i].unixid = NULL; + ids[i].sid = dom_sid_dup(ids, &ace->trustee); + if (ids[i].sid == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + ids[i].status = NT_STATUS_NONE_MAPPED; + } + + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx,ids, acl.a_count, ids); + if (ctx == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = wbc_sids_to_xids_recv(ctx, &ids); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + for (i=0;i<acl.a_count;i++) { struct nfs4ace *a = &acl.ace[i]; struct security_ace *ace = &sd->dacl->aces[i]; a->e_type = ace->type; a->e_flags = ace->flags; a->e_mask = ace->access_mask; - if (sidmap_sid_is_group(pvfs->sidmap, &ace->trustee)) { - gid_t gid; + if (ids[i].unixid->type != ID_TYPE_UID) { a->e_flags |= ACE4_IDENTIFIER_GROUP; - status = sidmap_sid_to_unixgid(pvfs->sidmap, &ace->trustee, &gid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - a->e_id = gid; - } else { - uid_t uid; - status = sidmap_sid_to_unixuid(pvfs->sidmap, &ace->trustee, &uid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - a->e_id = uid; } + a->e_id = ids[i].unixid->id; a->e_who = ""; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ca874d1db1..ebc2d88e70 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -222,8 +222,10 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, event_context_find(pvfs), pvfs->ntvfs->ctx->config); - pvfs->sidmap = sidmap_open(pvfs, pvfs->ntvfs->ctx->lp_ctx); - if (pvfs->sidmap == NULL) { + pvfs->wbc_ctx = wbc_init(pvfs, + pvfs->ntvfs->ctx->msg_ctx, + pvfs->ntvfs->ctx->event_ctx); + if (pvfs->wbc_ctx == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4d22a91714..441424142f 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,6 +26,7 @@ #include "system/filesys.h" #include "ntvfs/ntvfs.h" #include "ntvfs/common/ntvfs_common.h" +#include "libcli/wbclient/wbclient.h" #include "dsdb/samdb/samdb.h" struct pvfs_wait; @@ -46,7 +47,7 @@ struct pvfs_state { struct brl_context *brl_context; struct odb_context *odb_context; struct notify_context *notify_context; - struct sidmap_context *sidmap; + struct wbc_context *wbc_ctx; /* a list of pending async requests. Needed to support ntcancel */ |