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; }
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; }
/* 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); }
/* 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); }
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; }
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; }