예제 #1
0
파일: unix_token.c 프로젝트: srimalik/samba
/*
  form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
				      struct wbc_context *wbc_ctx,
				      struct security_token *token,
				      struct security_unix_token **sec)
{
	uint32_t s, g;
	NTSTATUS status;
	struct id_map *ids;
	struct composite_context *ctx;

	/* we can't do unix security without a user and group */
	if (token->num_sids < 2) {
		return NT_STATUS_ACCESS_DENIED;
	}

	*sec = talloc_zero(mem_ctx, struct security_unix_token);
	if (*sec == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	ids = talloc_zero_array(mem_ctx, struct id_map, token->num_sids);
	NT_STATUS_HAVE_NO_MEMORY(ids);

	for (s=0; s < token->num_sids; s++) {
		ids[s].sid = &token->sids[s];
		ids[s].status = ID_UNKNOWN;
	}

	ctx = wbc_sids_to_xids_send(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);

	g = token->num_sids;
	if (ids[0].xid.type != ID_TYPE_BOTH) {
		g--;
	}
	(*sec)->ngroups = g;
	(*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups);
	NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);

	g=0;
	if (ids[0].xid.type == ID_TYPE_BOTH) {
		(*sec)->uid = ids[0].xid.id;
		(*sec)->groups[g] = ids[0].xid.id;
		g++;
	} else if (ids[0].xid.type == ID_TYPE_UID) {
		(*sec)->uid = ids[0].xid.id;
	} else {
		char *sid_str = dom_sid_string(mem_ctx, ids[0].sid);
		DEBUG(0, ("Unable to convert first SID (%s) in user token to a UID.  Conversion was returned as type %d, full token:\n",
			  sid_str, (int)ids[0].xid.type));
		security_token_debug(0, 0, token);
		talloc_free(sid_str);
		return NT_STATUS_INVALID_SID;
	}

	if (ids[1].xid.type == ID_TYPE_BOTH ||
	    ids[1].xid.type == ID_TYPE_GID) {
		(*sec)->gid = ids[1].xid.id;
		(*sec)->groups[g] = ids[1].xid.id;
		g++;
	} else {
		char *sid_str = dom_sid_string(mem_ctx, ids[1].sid);
		DEBUG(0, ("Unable to convert second SID (%s) in user token to a GID.  Conversion was returned as type %d, full token:\n",
			  sid_str, (int)ids[1].xid.type));
		security_token_debug(0, 0, token);
		talloc_free(sid_str);
		return NT_STATUS_INVALID_SID;
	}

	for (s=2; s < token->num_sids; s++) {
		if (ids[s].xid.type == ID_TYPE_BOTH ||
		    ids[s].xid.type == ID_TYPE_GID) {
			(*sec)->groups[g] = ids[s].xid.id;
			g++;
		} else {
			char *sid_str = dom_sid_string(mem_ctx, ids[s].sid);
			DEBUG(0, ("Unable to convert SID (%s) at index %u in user token to a GID.  Conversion was returned as type %d, full token:\n",
				  sid_str, (unsigned int)s, (int)ids[s].xid.type));
			security_token_debug(0, 0, token);
			talloc_free(sid_str);
			return NT_STATUS_INVALID_SID;
		}
	}

	DEBUG(5, ("Successfully converted security token to a unix token:"));
	security_token_debug(0, 5, token);
	TALLOC_FREE(ids);

	return NT_STATUS_OK;
}
예제 #2
0
/*
  save the acl for a file into system.nfs4acl
*/
static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
				   struct security_descriptor *sd)
{
	NTSTATUS status;
	void *privs;
	struct nfs4acl acl;
	int i;
	TALLOC_CTX *tmp_ctx;
	struct id_map *ids;
	struct composite_context *ctx;

	tmp_ctx = talloc_new(pvfs);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	acl.a_version = 0;
	acl.a_flags   = sd->type;
	acl.a_count   = sd->dacl?sd->dacl->num_aces:0;
	acl.a_owner_mask = 0;
	acl.a_group_mask = 0;
	acl.a_other_mask = 0;

	acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count);
	if (!acl.ace) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	ids = talloc_array(tmp_ctx, struct id_map, 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];
		ZERO_STRUCT(ids[i].xid);
		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 = ID_UNKNOWN;
	}

	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 (ids[i].xid.type != ID_TYPE_UID) {
			a->e_flags |= ACE4_IDENTIFIER_GROUP;
		}
		a->e_id = ids[i].xid.id;
		a->e_who   = "";
	}

	privs = root_privileges();
	status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
				     NFS4ACL_XATTR_NAME, 
				     &acl, (void *) ndr_push_nfs4acl);
	talloc_free(privs);

	talloc_free(tmp_ctx);
	return status;
}
예제 #3
0
파일: unix_token.c 프로젝트: rti7743/samba
/*
  form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
				      struct wbc_context *wbc_ctx,
				      struct security_token *token,
				      struct security_unix_token **sec)
{
	int i;
	NTSTATUS status;
	struct id_map *ids;
	struct composite_context *ctx;
	*sec = talloc(mem_ctx, struct security_unix_token);

	/* we can't do unix security without a user and group */
	if (token->num_sids < 2) {
		return NT_STATUS_ACCESS_DENIED;
	}

	ids = talloc_array(mem_ctx, struct id_map, token->num_sids);
	NT_STATUS_HAVE_NO_MEMORY(ids);

	(*sec)->ngroups = token->num_sids - 2;
	(*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups);
	NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);

	for (i=0;i<token->num_sids;i++) {
		ZERO_STRUCT(ids[i].xid);
		ids[i].sid = &token->sids[i];
		ids[i].status = ID_UNKNOWN;
	}

	ctx = wbc_sids_to_xids_send(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].xid.type == ID_TYPE_BOTH ||
	    ids[0].xid.type == ID_TYPE_UID) {
		(*sec)->uid = ids[0].xid.id;
	} else {
		return NT_STATUS_INVALID_SID;
	}

	if (ids[1].xid.type == ID_TYPE_BOTH ||
	    ids[1].xid.type == ID_TYPE_GID) {
		(*sec)->gid = ids[1].xid.id;
	} else {
		return NT_STATUS_INVALID_SID;
	}

	for (i=0;i<(*sec)->ngroups;i++) {
		if (ids[i+2].xid.type == ID_TYPE_BOTH ||
		    ids[i+2].xid.type == ID_TYPE_GID) {
			(*sec)->groups[i] = ids[i+2].xid.id;
		} else {
			return NT_STATUS_INVALID_SID;
		}
	}

	TALLOC_FREE(ids);

	return NT_STATUS_OK;
}