Example #1
0
static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type)
{
	struct gpfs_acl *acl;
	size_t len = 200;
	int ret;
	TALLOC_CTX *mem_ctx = talloc_tos();

	acl = (struct gpfs_acl *)TALLOC_SIZE(mem_ctx, len);
	if (acl == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	acl->acl_len = len;
	acl->acl_level = 0;
	acl->acl_version = 0;
	acl->acl_type = type;

	ret = smbd_gpfs_getacl((char *)fname, GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA, acl);
	if ((ret != 0) && (errno == ENOSPC)) {
		struct gpfs_acl *new_acl = (struct gpfs_acl *)TALLOC_SIZE(
			mem_ctx, acl->acl_len + sizeof(struct gpfs_acl));
		if (new_acl == NULL) {
			errno = ENOMEM;
			return NULL;
		}

		new_acl->acl_len = acl->acl_len;
		new_acl->acl_level = acl->acl_level;
		new_acl->acl_version = acl->acl_version;
		new_acl->acl_type = acl->acl_type;
		acl = new_acl;

		ret = smbd_gpfs_getacl((char *)fname, GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA, acl);
	}
	if (ret != 0)
	{
		DEBUG(8, ("smbd_gpfs_getacl failed with %s\n",strerror(errno)));
		return NULL;
	}

	return acl;
}
Example #2
0
static AIXJFS2_ACL_T *aixjfs2_getacl_alloc(const char *fname, acl_type_t *type)
{
	AIXJFS2_ACL_T *acl;
	size_t len = 200;
	mode_t mode;
	int ret;
	uint64_t ctl_flag=0;
	TALLOC_CTX	*mem_ctx;

	mem_ctx = talloc_tos();
	acl = (AIXJFS2_ACL_T *)TALLOC_SIZE(mem_ctx, len);
	if (acl == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	if(type->u64 == ACL_ANY) {
		ctl_flag = ctl_flag | GET_ACLINFO_ONLY;
	}

	ret = aclx_get((char *)fname, ctl_flag, type, acl, &len, &mode);
	if ((ret != 0) && (errno == ENOSPC)) {
		len = aixacl2_getlen(acl, type) + sizeof(AIXJFS2_ACL_T);
		DEBUG(10,("aixjfs2_getacl_alloc - acl_len:%d\n",len));

		acl = (AIXJFS2_ACL_T *)TALLOC_SIZE(mem_ctx, len);
		if (acl == NULL) {
			errno = ENOMEM;
			return NULL;
		}

		ret = aclx_get((char *)fname, ctl_flag, type, acl, &len, &mode);
	}
	if (ret != 0) {
		DEBUG(8, ("aclx_get failed with %s\n", strerror(errno)));
		return NULL;
	}

	return acl;
}
Example #3
0
/*
  called when the kernel has some events for us
*/
static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde,
                            uint16_t flags, void *private_data)
{
    struct inotify_private *in = talloc_get_type(private_data,
                                 struct inotify_private);
    int bufsize = 0;
    struct inotify_event *e0, *e;
    uint32_t prev_cookie=0;
    NTSTATUS status;

    /*
      we must use FIONREAD as we cannot predict the length of the
      filenames, and thus can't know how much to allocate
      otherwise
    */
    if (ioctl(in->fd, FIONREAD, &bufsize) != 0 ||
            bufsize == 0) {
        DEBUG(0,("No data on inotify fd?!\n"));
        TALLOC_FREE(fde);
        return;
    }

    e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize + 1);
    if (e == NULL) return;
    ((uint8_t *)e)[bufsize] = '\0';

    status = read_data(in->fd, (char *)e0, bufsize);
    if (!NT_STATUS_IS_OK(status)) {
        DEBUG(0,("Failed to read all inotify data - %s\n",
                 nt_errstr(status)));
        talloc_free(e0);
        /* the inotify fd will now be out of sync,
         * can't keep reading data off it */
        TALLOC_FREE(fde);
        return;
    }

    /* we can get more than one event in the buffer */
    while (e && (bufsize >= sizeof(*e))) {
        struct inotify_event *e2 = NULL;
        bufsize -= e->len + sizeof(*e);
        if (bufsize >= sizeof(*e)) {
            e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e);
        }
        inotify_dispatch(in, e, prev_cookie, e2);
        prev_cookie = e->cookie;
        e = e2;
    }

    talloc_free(e0);
}
Example #4
0
/*
  called when the kernel has some events for us
*/
static void inotify_handler(struct event_context *ev, struct fd_event *fde,
			    uint16_t flags, void *private_data)
{
	struct inotify_private *in = talloc_get_type(private_data,
						     struct inotify_private);
	int bufsize = 0;
	struct inotify_event *e0, *e;
	uint32_t prev_cookie=0;

	/*
	  we must use FIONREAD as we cannot predict the length of the
	  filenames, and thus can't know how much to allocate
	  otherwise
	*/

	if ((ioctl(in->fd, FIONREAD, &bufsize) != 0) && (errno == EACCES)) {
		/*
		 * Workaround for broken SELinux policies on Fedora
		 */
		TALLOC_FREE(fde);
		in->broken_inotify = True;
		return;
	}
	if (bufsize == 0) {
		DEBUG(0,("No data on inotify fd?!\n"));
		return;
	}

	e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize);
	if (e == NULL) return;

	if (read(in->fd, e0, bufsize) != bufsize) {
		DEBUG(0,("Failed to read all inotify data\n"));
		talloc_free(e0);
		return;
	}

	/* we can get more than one event in the buffer */
	while (bufsize >= sizeof(*e)) {
		struct inotify_event *e2 = NULL;
		bufsize -= e->len + sizeof(*e);
		if (bufsize >= sizeof(*e)) {
			e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e);
		}
		inotify_dispatch(in, e, prev_cookie, e2);
		prev_cookie = e->cookie;
		e = e2;
	}

	talloc_free(e0);
}
Example #5
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;
}
Example #6
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;
}