Exemple #1
0
static struct SMB4ACL_T *nfs4acls_defaultacl(TALLOC_CTX *mem_ctx)
{
	struct SMB4ACL_T *pacl = NULL;
	struct SMB4ACE_T *pace;
	SMB_ACE4PROP_T ace = {
		.flags = SMB_ACE4_ID_SPECIAL,
		.who = {
			.id = SMB_ACE4_WHO_EVERYONE,
		},
		.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
		.aceFlags = 0,
		.aceMask = SMB_ACE4_ALL_MASKS,
	};

	DEBUG(10, ("Building default full access acl\n"));

	pacl = smb_create_smb4acl(mem_ctx);
	if (pacl == NULL) {
		DEBUG(0, ("talloc failed\n"));
		errno = ENOMEM;
		return NULL;
	}

	pace = smb_add_ace4(pacl, &ace);
	if (pace == NULL) {
		DEBUG(0, ("talloc failed\n"));
		TALLOC_FREE(pacl);
		errno = ENOMEM;
		return NULL;
	}

	return pacl;
}
Exemple #2
0
static bool aixjfs2_get_nfs4_acl(const char *name,
	SMB4ACL_T **ppacl, bool *pretryPosix)
{
	int32_t i;
	
	AIXJFS2_ACL_T *pacl = NULL;
	nfs4_acl_int_t *jfs2_acl = NULL;
	nfs4_ace_int_t *jfs2_ace = NULL;
	acl_type_t type;

	DEBUG(10,("jfs2 get_nt_acl invoked for %s\n", name));

	memset(&type, 0, sizeof(acl_type_t));
	type.u64 = ACL_NFS4;

	pacl = aixjfs2_getacl_alloc(name, &type);
        if (pacl == NULL) {
		DEBUG(9, ("aixjfs2_getacl_alloc failed for %s with %s\n",
				name, strerror(errno)));
		if (errno==ENOSYS)
			*pretryPosix = True;
		return False;
	}

	jfs2_acl = &pacl->jfs2_acl[0];
	DEBUG(10, ("len: %d, version: %d, nace: %d, type: 0x%x\n",
			jfs2_acl->aclLength, jfs2_acl->aclVersion, jfs2_acl->aclEntryN, type.u64));

	*ppacl = smb_create_smb4acl();
	if (*ppacl==NULL)
		return False;

	jfs2_ace = &jfs2_acl->aclEntry[0];
	for (i=0; i<jfs2_acl->aclEntryN; i++) {
		SMB_ACE4PROP_T aceprop;

		DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, "
				"who: %d, aclLen: %d\n", jfs2_ace->aceType, jfs2_ace->flags,
				jfs2_ace->aceFlags, jfs2_ace->aceMask, jfs2_ace->aceWho.id, jfs2_ace->entryLen));

		aceprop.aceType = jfs2_ace->aceType;
		aceprop.aceFlags = jfs2_ace->aceFlags;
		aceprop.aceMask = jfs2_ace->aceMask;
		aceprop.flags = (jfs2_ace->flags&ACE4_ID_SPECIAL) ? SMB_ACE4_ID_SPECIAL : 0;

		/* don't care it's real content is only 16 or 32 bit */
		aceprop.who.id = jfs2_ace->aceWho.id;

		if (smb_add_ace4(*ppacl, &aceprop)==NULL)
			return False;

		/* iterate to the next jfs2 ace */
		jfs2_ace = (nfs4_ace_int_t *)(((char *)jfs2_ace) + jfs2_ace->entryLen);
        }

	DEBUG(10,("jfs2 get_nt_acl finished successfully\n"));

	return True;
}
Exemple #3
0
static SMB4ACL_T *smbacl4_win2nfs4(
    TALLOC_CTX *mem_ctx,
    const files_struct *fsp,
    const struct security_acl *dacl,
    smbacl4_vfs_params *pparams,
    uid_t ownerUID,
    gid_t ownerGID
)
{
    SMB4ACL_T *theacl;
    uint32	i;
    const char *filename = fsp->fsp_name->base_name;

    DEBUG(10, ("smbacl4_win2nfs4 invoked\n"));

    theacl = smb_create_smb4acl(mem_ctx);
    if (theacl==NULL)
        return NULL;

    for(i=0; i<dacl->num_aces; i++) {
        SMB_ACE4PROP_T	ace_v4;
        bool	addNewACE = true;

        if (!smbacl4_fill_ace4(fsp->fsp_name, pparams,
                               ownerUID, ownerGID,
                               dacl->aces + i, &ace_v4)) {
            DEBUG(3, ("Could not fill ace for file %s, SID %s\n",
                      filename,
                      sid_string_dbg(&((dacl->aces+i)->trustee))));
            continue;
        }

        if (pparams->acedup!=e_dontcare) {
            if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl,
                                          &ace_v4, &addNewACE, i))
                return NULL;
        }

        if (addNewACE)
            smb_add_ace4(theacl, &ace_v4);
    }

    if (pparams->mode==e_simple) {
        smbacl4_substitute_simple(theacl, ownerUID, ownerGID);
    }

    if (pparams->mode==e_special) {
        smbacl4_substitute_special(theacl, ownerUID, ownerGID);
    }

    return theacl;
}
Exemple #4
0
static NTSTATUS nfs4_get_nfs4_acl_common(TALLOC_CTX *mem_ctx,
					 DATA_BLOB *blob,
					 struct SMB4ACL_T **ppacl)
{
	int i;
	struct nfs4acl *nfs4acl = NULL;
	struct SMB4ACL_T *pacl = NULL;
	TALLOC_CTX *frame = talloc_stackframe();
	nfs4acl = nfs4acl_blob2acl(blob, frame);

	/* create SMB4ACL data */
	if((pacl = smb_create_smb4acl(mem_ctx)) == NULL) {
		TALLOC_FREE(frame);
		return NT_STATUS_NO_MEMORY;
	}
	for(i=0; i<nfs4acl->a_count; i++) {
		SMB_ACE4PROP_T aceprop;

		aceprop.aceType  = (uint32_t) nfs4acl->ace[i].e_type;
		aceprop.aceFlags = (uint32_t) nfs4acl->ace[i].e_flags;
		aceprop.aceMask  = (uint32_t) nfs4acl->ace[i].e_mask;
		aceprop.who.id   = (uint32_t) nfs4acl->ace[i].e_id;
		if (!strcmp(nfs4acl->ace[i].e_who,
			    NFS4ACL_XATTR_OWNER_WHO)) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_OWNER;
		} else if (!strcmp(nfs4acl->ace[i].e_who,
				   NFS4ACL_XATTR_GROUP_WHO)) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_GROUP;
		} else if (!strcmp(nfs4acl->ace[i].e_who,
				   NFS4ACL_XATTR_EVERYONE_WHO)) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_EVERYONE;
		} else {
			aceprop.flags = 0;
		}
		if(smb_add_ace4(pacl, &aceprop) == NULL) {
			TALLOC_FREE(frame);
			return NT_STATUS_NO_MEMORY;
		}
	}

	*ppacl = pacl;
	TALLOC_FREE(frame);
	return NT_STATUS_OK;
}
Exemple #5
0
/*
 * Because there is no good way to guarantee that a new xattr will be
 * created on file creation there might be no acl xattr on a file when
 * trying to read the acl. In this case the acl xattr will get
 * constructed at that time from the parent acl.
 * If the parent ACL doesn't have an xattr either the call will
 * recurse to the next parent directory until the share root is
 * reached. If the share root doesn't contain an ACL xattr either a
 * default ACL will be used.
 * Also a default ACL will be set if a non inheriting ACL is encountered.
 *
 * Basic algorithm:
 *   read acl xattr blob
 *   if acl xattr blob doesn't exist
 *     stat current directory to know if it's a file or directory
 *     read acl xattr blob from parent dir
 *     acl xattr blob to smb nfs4 acl
 *     calculate inherited smb nfs4 acl
 *     without inheritance use default smb nfs4 acl
 *     smb nfs4 acl to acl xattr blob
 *     set acl xattr blob
 *     return smb nfs4 acl
 *   else
 *     acl xattr blob to smb nfs4 acl
 *
 * Todo: Really use mem_ctx after fixing interface of nfs4_acls
 */
static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
	const char *path,
	TALLOC_CTX *mem_ctx)
{
	char *parent_dir = NULL;
	struct SMB4ACL_T *pparentacl = NULL;
	struct SMB4ACL_T *pchildacl = NULL;
	struct SMB4ACE_T *pace;
	SMB_ACE4PROP_T ace;
	bool isdir;
	struct smb_filename *smb_fname = NULL;
	NTSTATUS status;
	int ret;
	TALLOC_CTX *frame = talloc_stackframe();

	DEBUG(10, ("nfs4acls_inheritacl invoked for %s\n", path));
	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL);
	if (smb_fname == NULL) {
		TALLOC_FREE(frame);
		errno = ENOMEM;
		return NULL;
	}

	ret = SMB_VFS_STAT(handle->conn, smb_fname);
	if (ret == -1) {
		DEBUG(0,("nfs4acls_inheritacl: failed to stat "
			 "directory %s. Error was %s\n",
			 smb_fname_str_dbg(smb_fname),
			 strerror(errno)));
		TALLOC_FREE(frame);
		return NULL;
	}
	isdir = S_ISDIR(smb_fname->st.st_ex_mode);

	if (!parent_dirname(talloc_tos(),
			    path,
			    &parent_dir,
			    NULL)) {
		TALLOC_FREE(frame);
		errno = ENOMEM;
		return NULL;
	}

	status = nfs4_get_nfs4_acl(handle, frame, parent_dir, &pparentacl);
	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)
	    && strncmp(parent_dir, ".", 2) != 0) {
		pparentacl = nfs4acls_inheritacl(handle, parent_dir,
						 frame);
	}
	else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
		pparentacl = nfs4acls_defaultacl(frame);

	}
	else if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(frame);
		return NULL;
	}

	pchildacl = smb_create_smb4acl(mem_ctx);
	if (pchildacl == NULL) {
		DEBUG(0, ("talloc failed\n"));
		TALLOC_FREE(frame);
		errno = ENOMEM;
		return NULL;
	}

	for (pace = smb_first_ace4(pparentacl); pace != NULL;
	     pace = smb_next_ace4(pace)) {
		struct SMB4ACE_T *pchildace;
		ace = *smb_get_ace4(pace);
		if ((isdir && !(ace.aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) ||
		    (!isdir && !(ace.aceFlags & SMB_ACE4_FILE_INHERIT_ACE))) {
			DEBUG(10, ("non inheriting ace type: %d, iflags: %x, "
				   "flags: %x, mask: %x, who: %d\n",
				   ace.aceType, ace.flags, ace.aceFlags,
				   ace.aceMask, ace.who.id));
			continue;
		}
		DEBUG(10, ("inheriting ace type: %d, iflags: %x, "
			   "flags: %x, mask: %x, who: %d\n",
			   ace.aceType, ace.flags, ace.aceFlags,
			   ace.aceMask, ace.who.id));
		ace.aceFlags |= SMB_ACE4_INHERITED_ACE;
		if (ace.aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) {
			ace.aceFlags &= ~SMB_ACE4_INHERIT_ONLY_ACE;
		}
		if (ace.aceFlags & SMB_ACE4_NO_PROPAGATE_INHERIT_ACE) {
			ace.aceFlags &= ~SMB_ACE4_FILE_INHERIT_ACE;
			ace.aceFlags &= ~SMB_ACE4_DIRECTORY_INHERIT_ACE;
			ace.aceFlags &= ~SMB_ACE4_NO_PROPAGATE_INHERIT_ACE;
		}
		pchildace = smb_add_ace4(pchildacl, &ace);
		if (pchildace == NULL) {
			DEBUG(0, ("talloc failed\n"));
			TALLOC_FREE(frame);
			errno = ENOMEM;
			return NULL;
		}
	}

	/* Set a default ACL if we didn't inherit anything. */
	if (smb_first_ace4(pchildacl) == NULL) {
		TALLOC_FREE(pchildacl);
		pchildacl = nfs4acls_defaultacl(mem_ctx);
	}

	/* store the returned ACL to get it directly in the
	   future and avoid dynamic inheritance behavior. */
	nfs4acl_xattr_set_smb4acl(handle, path, pchildacl);

	TALLOC_FREE(frame);
	return pchildacl;
}
Exemple #6
0
/* zfs_get_nt_acl()
 * read the local file's acls and return it in NT form
 * using the NFSv4 format conversion
 */
static NTSTATUS zfs_get_nt_acl_common(const char *name,
				      uint32 security_info,
				      SMB4ACL_T **ppacl)
{
	int naces, i;
	ace_t *acebuf;
	SMB4ACL_T *pacl;
	TALLOC_CTX	*mem_ctx;

	/* read the number of file aces */
	if((naces = acl(name, ACE_GETACLCNT, 0, NULL)) == -1) {
		if(errno == ENOSYS) {
			DEBUG(9, ("acl(ACE_GETACLCNT, %s): Operation is not "
				  "supported on the filesystem where the file "
				  "reside", name));
		} else {
			DEBUG(9, ("acl(ACE_GETACLCNT, %s): %s ", name,
					strerror(errno)));
		}
		return map_nt_error_from_unix(errno);
	}
	/* allocate the field of ZFS aces */
	mem_ctx = talloc_tos();
	acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*naces);
	if(acebuf == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	/* read the aces into the field */
	if(acl(name, ACE_GETACL, naces, acebuf) < 0) {
		DEBUG(9, ("acl(ACE_GETACL, %s): %s ", name,
				strerror(errno)));
		return map_nt_error_from_unix(errno);
	}
	/* create SMB4ACL data */
	if((pacl = smb_create_smb4acl()) == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	for(i=0; i<naces; i++) {
		SMB_ACE4PROP_T aceprop;

		aceprop.aceType  = (uint32) acebuf[i].a_type;
		aceprop.aceFlags = (uint32) acebuf[i].a_flags;
		aceprop.aceMask  = (uint32) acebuf[i].a_access_mask;
		aceprop.who.id   = (uint32) acebuf[i].a_who;

		if(aceprop.aceFlags & ACE_OWNER) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_OWNER;
		} else if(aceprop.aceFlags & ACE_GROUP) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_GROUP;
		} else if(aceprop.aceFlags & ACE_EVERYONE) {
			aceprop.flags = SMB_ACE4_ID_SPECIAL;
			aceprop.who.special_id = SMB_ACE4_WHO_EVERYONE;
		} else {
			aceprop.flags	= 0;
		}
		if(smb_add_ace4(pacl, &aceprop) == NULL)
			return NT_STATUS_NO_MEMORY;
	}

	*ppacl = pacl;
	return NT_STATUS_OK;
}
Exemple #7
0
/* Tries to get nfs4 acls and returns SMB ACL allocated.
 * On failure returns 1 if it got non-NFSv4 ACL to prompt 
 * retry with POSIX ACL checks.
 * On failure returns -1 if there is system (GPFS) error, check errno.
 * Returns 0 on success
 */
static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
{
	int i;
	struct gpfs_acl *gacl = NULL;
	DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname));

	/* First get the real acl length */
	gacl = gpfs_getacl_alloc(fname, 0);
	if (gacl == NULL) {
		DEBUG(9, ("gpfs_getacl failed for %s with %s\n",
			   fname, strerror(errno)));
		return -1;
	}

	if (gacl->acl_type != GPFS_ACL_TYPE_NFS4) {
		DEBUG(10, ("Got non-nfsv4 acl\n"));
		/* Retry with POSIX ACLs check */
		return 1;
	}

	*ppacl = smb_create_smb4acl();

	DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d\n",
		   gacl->acl_len, gacl->acl_level, gacl->acl_version,
		   gacl->acl_nace));

	for (i=0; i<gacl->acl_nace; i++) {
		struct gpfs_ace_v4 *gace = &gacl->ace_v4[i];
		SMB_ACE4PROP_T smbace;
		DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, "
			   "who: %d\n", gace->aceType, gace->aceIFlags,
			   gace->aceFlags, gace->aceMask, gace->aceWho));

		ZERO_STRUCT(smbace);
		if (gace->aceIFlags & ACE4_IFLAG_SPECIAL_ID) {
			smbace.flags |= SMB_ACE4_ID_SPECIAL;
			switch (gace->aceWho) {
			case ACE4_SPECIAL_OWNER:
				smbace.who.special_id = SMB_ACE4_WHO_OWNER;
				break;
			case ACE4_SPECIAL_GROUP:
				smbace.who.special_id = SMB_ACE4_WHO_GROUP;
				break;
			case ACE4_SPECIAL_EVERYONE:
				smbace.who.special_id = SMB_ACE4_WHO_EVERYONE;
				break;
			default:
				DEBUG(8, ("invalid special gpfs id %d "
					  "ignored\n", gace->aceWho));
				continue; /* don't add it */
			}
		} else {
			if (gace->aceFlags & ACE4_FLAG_GROUP_ID)
				smbace.who.gid = gace->aceWho;
			else
				smbace.who.uid = gace->aceWho;
		}

		/* remove redundent deny entries */
		if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) {
			struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1];
			if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE &&
			    prev->aceFlags == gace->aceFlags &&
			    prev->aceIFlags == gace->aceIFlags &&
			    (gace->aceMask & prev->aceMask) == 0 &&
			    gace->aceWho == prev->aceWho) {
				/* its redundent - skip it */
				continue;
			}                                                
		}

		smbace.aceType = gace->aceType;
		smbace.aceFlags = gace->aceFlags;
		smbace.aceMask = gace->aceMask;
		smb_add_ace4(*ppacl, &smbace);
	}

	return 0;
}