Esempio n. 1
0
static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
        smbacl4_vfs_params *params,
        uint32 security_info,
        TALLOC_CTX *mem_ctx,
        struct security_descriptor **ppdesc,
        SMB4ACL_T *theacl)
{
    int good_aces = 0;
    struct dom_sid sid_owner, sid_group;
    size_t sd_size = 0;
    struct security_ace *nt_ace_list = NULL;
    struct security_acl *psa = NULL;
    TALLOC_CTX *frame = talloc_stackframe();

    if (theacl==NULL || smb_get_naces(theacl)==0) {
        TALLOC_FREE(frame);
        return NT_STATUS_ACCESS_DENIED; /* special because we
						 * shouldn't alloc 0 for
						 * win */
    }

    uid_to_sid(&sid_owner, sbuf->st_ex_uid);
    gid_to_sid(&sid_group, sbuf->st_ex_gid);

    if (smbacl4_nfs42win(mem_ctx, params, theacl, &sid_owner, &sid_group,
                         S_ISDIR(sbuf->st_ex_mode),
                         &nt_ace_list, &good_aces)==false) {
        DEBUG(8,("smbacl4_nfs42win failed\n"));
        TALLOC_FREE(frame);
        return map_nt_error_from_unix(errno);
    }

    psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list);
    if (psa == NULL) {
        DEBUG(2,("make_sec_acl failed\n"));
        TALLOC_FREE(frame);
        return NT_STATUS_NO_MEMORY;
    }

    DEBUG(10,("after make sec_acl\n"));
    *ppdesc = make_sec_desc(
                  mem_ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
                  (security_info & SECINFO_OWNER) ? &sid_owner : NULL,
                  (security_info & SECINFO_GROUP) ? &sid_group : NULL,
                  NULL, psa, &sd_size);
    if (*ppdesc==NULL) {
        DEBUG(2,("make_sec_desc failed\n"));
        TALLOC_FREE(frame);
        return NT_STATUS_NO_MEMORY;
    }

    DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with "
               "sd_size %d\n",
               (int)ndr_size_security_descriptor(*ppdesc, 0)));

    TALLOC_FREE(frame);
    return NT_STATUS_OK;
}
Esempio n. 2
0
static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
{
	SMB4ACE_T	*smbace;
	TALLOC_CTX	*mem_ctx;
	nfs4_acl_int_t	*jfs2acl;
	int32_t	entryLen;
	uint32	aclLen, naces;
	int	rc;
	acl_type_t	acltype;

	DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp)));

	/* no need to be freed which is alloced with mem_ctx */
	mem_ctx = talloc_tos();

	entryLen = sizeof(nfs4_ace_int_t);
	if (entryLen & 0x03)
		entryLen = entryLen + 4 - (entryLen%4);

	naces = smb_get_naces(smbacl);
	aclLen = ACL_V4_SIZ + naces * entryLen;
	jfs2acl = (nfs4_acl_int_t *)TALLOC_SIZE(mem_ctx, aclLen);
	if (jfs2acl==NULL) {
		DEBUG(0, ("TALLOC_SIZE failed\n"));
		errno = ENOMEM;
		return False;
	}

	jfs2acl->aclLength = ACL_V4_SIZ;
	jfs2acl->aclVersion = NFS4_ACL_INT_STRUCT_VERSION;
	jfs2acl->aclEntryN = 0;

	for(smbace = smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace))
	{
		SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);
		nfs4_ace_int_t *jfs2_ace = (nfs4_ace_int_t *)(((char *)jfs2acl) + jfs2acl->aclLength);

		memset(jfs2_ace, 0, entryLen);
		jfs2_ace->entryLen = entryLen; /* won't store textual "who" */
		jfs2_ace->aceType = aceprop->aceType; /* only ACCES|DENY supported by jfs2 */
		jfs2_ace->aceFlags = aceprop->aceFlags;
		jfs2_ace->aceMask = aceprop->aceMask;
		jfs2_ace->flags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_ID_SPECIAL : 0;

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

		/* iterate to the next jfs2 ace */
		jfs2acl->aclLength += jfs2_ace->entryLen;
		jfs2acl->aclEntryN++;
	}
	SMB_ASSERT(jfs2acl->aclEntryN==naces);

	/* Don't query it (again) */
	memset(&acltype, 0, sizeof(acl_type_t));
	acltype.u64 = ACL_NFS4;

	/* won't set S_ISUID - the only one JFS2/NFS4 accepts */
	rc = aclx_put(
		fsp->fsp_name->base_name,
		SET_ACL, /* set only the ACL, not mode bits */
		acltype, /* not a pointer !!! */
		jfs2acl,
		jfs2acl->aclLength,
		0 /* don't set here mode bits */
	);
	if (rc) {
		DEBUG(8, ("aclx_put failed with %s\n", strerror(errno)));
		return False;
	}

	DEBUG(10, ("jfs2_process_smbacl succeeded.\n"));
	return True;
}
Esempio n. 3
0
/* call-back function processing the NT acl -> ZFS acl using NFSv4 conv. */
static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
{
	int naces = smb_get_naces(smbacl), i;
	ace_t *acebuf;
	SMB4ACE_T *smbace;
	TALLOC_CTX	*mem_ctx;
	bool have_special_id = false;

	/* allocate the field of ZFS aces */
	mem_ctx = talloc_tos();
	acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*naces);
	if(acebuf == NULL) {
		errno = ENOMEM;
		return False;
	}
	/* handle all aces */
	for(smbace = smb_first_ace4(smbacl), i = 0;
			smbace!=NULL;
			smbace = smb_next_ace4(smbace), i++) {
		SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);

		acebuf[i].a_type        = aceprop->aceType;
		acebuf[i].a_flags       = aceprop->aceFlags;
		acebuf[i].a_access_mask = aceprop->aceMask;
		acebuf[i].a_who         = aceprop->who.id;
		if(aceprop->flags & SMB_ACE4_ID_SPECIAL) {
			switch(aceprop->who.special_id) {
			case SMB_ACE4_WHO_EVERYONE:
				acebuf[i].a_flags |= ACE_EVERYONE;
				break;
			case SMB_ACE4_WHO_OWNER:
				acebuf[i].a_flags |= ACE_OWNER;
				break;
			case SMB_ACE4_WHO_GROUP:
				acebuf[i].a_flags |= ACE_GROUP;
				break;
			default:
				DEBUG(8, ("unsupported special_id %d\n", \
					aceprop->who.special_id));
				continue; /* don't add it !!! */
			}
			have_special_id = true;
		}
	}

	if (!have_special_id
	    && lp_parm_bool(fsp->conn->params->service, "zfsacl",
			    "denymissingspecial", false)) {
		errno = EACCES;
		return false;
	}

	SMB_ASSERT(i == naces);

	/* store acl */
	if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
		if(errno == ENOSYS) {
			DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
				  "supported on the filesystem where the file "
				  "reside", fsp_str_dbg(fsp)));
		} else {
			DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp),
				  strerror(errno)));
		}
		return 0;
	}

	return True;
}
Esempio n. 4
0
static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
				    struct SMB4ACL_T *smbacl,
				    struct nfs4acl **pnfs4acl,
				    bool denymissingspecial)
{
	struct nfs4acl *nfs4acl;
	struct SMB4ACE_T *smbace;
	bool have_special_id = false;
	int i;

	/* allocate the field of NFS4 aces */
	nfs4acl = talloc_zero(mem_ctx, struct nfs4acl);
	if(nfs4acl == NULL) {
		errno = ENOMEM;
		return false;
	}

	nfs4acl->a_count = smb_get_naces(smbacl);

	nfs4acl->ace = talloc_zero_array(nfs4acl, struct nfs4ace,
					 nfs4acl->a_count);
	if(nfs4acl->ace == NULL) {
		TALLOC_FREE(nfs4acl);
		errno = ENOMEM;
		return false;
	}

	/* handle all aces */
	for(smbace = smb_first_ace4(smbacl), i = 0;
			smbace!=NULL;
			smbace = smb_next_ace4(smbace), i++) {
		SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);

		nfs4acl->ace[i].e_type        = aceprop->aceType;
		nfs4acl->ace[i].e_flags       = aceprop->aceFlags;
		nfs4acl->ace[i].e_mask        = aceprop->aceMask;
		nfs4acl->ace[i].e_id          = aceprop->who.id;
		if(aceprop->flags & SMB_ACE4_ID_SPECIAL) {
			switch(aceprop->who.special_id) {
			case SMB_ACE4_WHO_EVERYONE:
				nfs4acl->ace[i].e_who =
					NFS4ACL_XATTR_EVERYONE_WHO;
				break;
			case SMB_ACE4_WHO_OWNER:
				nfs4acl->ace[i].e_who =
					NFS4ACL_XATTR_OWNER_WHO;
				break;
			case SMB_ACE4_WHO_GROUP:
				nfs4acl->ace[i].e_who =
					NFS4ACL_XATTR_GROUP_WHO;
				break;
			default:
				DEBUG(8, ("unsupported special_id %d\n", \
					aceprop->who.special_id));
				continue; /* don't add it !!! */
			}
			have_special_id = true;
		} else {
			nfs4acl->ace[i].e_who = "";
		}
	}

	if (!have_special_id && denymissingspecial) {
		TALLOC_FREE(nfs4acl);
		errno = EACCES;
		return false;
	}

	SMB_ASSERT(i == nfs4acl->a_count);

	*pnfs4acl = nfs4acl;
	return true;
}
Esempio n. 5
0
static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
{
	int ret;
	gpfs_aclLen_t gacl_len;
	SMB4ACE_T	*smbace;
	struct gpfs_acl *gacl;
	TALLOC_CTX *mem_ctx  = talloc_tos();

	gacl_len = sizeof(struct gpfs_acl) +
		(smb_get_naces(smbacl)-1)*sizeof(gpfs_ace_v4_t);

	gacl = (struct gpfs_acl *)TALLOC_SIZE(mem_ctx, gacl_len);
	if (gacl == NULL) {
		DEBUG(0, ("talloc failed\n"));
		errno = ENOMEM;
		return False;
	}

	gacl->acl_len = gacl_len;
	gacl->acl_level = 0;
	gacl->acl_version = GPFS_ACL_VERSION_NFS4;
	gacl->acl_type = GPFS_ACL_TYPE_NFS4;
	gacl->acl_nace = 0; /* change later... */

	for (smbace=smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) {
		struct gpfs_ace_v4 *gace = &gacl->ace_v4[gacl->acl_nace];
		SMB_ACE4PROP_T	*aceprop = smb_get_ace4(smbace);

		gace->aceType = aceprop->aceType;
		gace->aceFlags = aceprop->aceFlags;
		gace->aceMask = aceprop->aceMask;

		/*
		 * GPFS can't distinguish between WRITE and APPEND on
		 * files, so one being set without the other is an
		 * error. Sorry for the many ()'s :-)
		 */

		if (!fsp->is_directory
		    &&
		    ((((gace->aceMask & ACE4_MASK_WRITE) == 0)
		      && ((gace->aceMask & ACE4_MASK_APPEND) != 0))
		     ||
		     (((gace->aceMask & ACE4_MASK_WRITE) != 0)
		      && ((gace->aceMask & ACE4_MASK_APPEND) == 0)))
		    &&
		    lp_parm_bool(fsp->conn->params->service, "gpfs",
				 "merge_writeappend", True)) {
			DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
				  "WRITE^APPEND, setting WRITE|APPEND\n",
				  fsp->fsp_name));
			gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
		}

		gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0;

		if (aceprop->flags&SMB_ACE4_ID_SPECIAL)
		{
			switch(aceprop->who.special_id)
			{
			case SMB_ACE4_WHO_EVERYONE:
				gace->aceWho = ACE4_SPECIAL_EVERYONE;
				break;
			case SMB_ACE4_WHO_OWNER:
				gace->aceWho = ACE4_SPECIAL_OWNER;
				break;
			case SMB_ACE4_WHO_GROUP:
				gace->aceWho = ACE4_SPECIAL_GROUP;
				break;
			default:
				DEBUG(8, ("unsupported special_id %d\n", aceprop->who.special_id));
				continue; /* don't add it !!! */
			}
		} else {
			/* just only for the type safety... */
			if (aceprop->aceFlags&SMB_ACE4_IDENTIFIER_GROUP)
				gace->aceWho = aceprop->who.gid;
			else
				gace->aceWho = aceprop->who.uid;
		}

		gacl->acl_nace++;
	}

	ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
	if (ret != 0) {
		DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno)));
		gpfs_dumpacl(8, gacl);
		return False;
	}

	DEBUG(10, ("gpfs_putacl succeeded\n"));
	return True;
}