#include <sys/types.h>
#include <sys/acl.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
enum {OPENX, MKFIFOX, MKDIRX};
extern int __open_extended(const char *, int, uid_t, gid_t, int, struct kauth_filesec *);
extern int __mkfifo_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *);
extern int __mkdir_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *);
static int
_mkfilex_np(int opcode, const char *path, int flags, filesec_t fsec)
{
uid_t owner = KAUTH_UID_NONE;
gid_t group = KAUTH_GID_NONE;
mode_t mode = 0;
size_t size = 0;
int fsacl_used = 0;
struct kauth_filesec *fsacl = NULL;
struct kauth_filesec static_filesec;
if (fsec != NULL) {
if ((filesec_get_property(fsec, FILESEC_OWNER, &owner) != 0) && (errno != ENOENT))
return(-1);
if ((filesec_get_property(fsec, FILESEC_GROUP, &group) != 0) && (errno != ENOENT))
return(-1);
if ((filesec_get_property(fsec, FILESEC_MODE, &mode) != 0) && (errno != ENOENT))
return(-1);
if (((filesec_get_property(fsec, FILESEC_ACL_RAW, &fsacl) != 0) ||
(filesec_get_property(fsec, FILESEC_ACL_ALLOCSIZE, &size) != 0)) &&
(errno != ENOENT))
return(-1);
if (fsacl == _FILESEC_REMOVE_ACL) {
errno = EINVAL;
return(-1);
}
if (fsacl == NULL) {
bzero(&static_filesec, sizeof(static_filesec));
fsacl = &static_filesec;
fsacl->fsec_magic = KAUTH_FILESEC_MAGIC;
fsacl->fsec_entrycount = KAUTH_FILESEC_NOACL;
} else {
fsacl_used = 1;
}
if (filesec_get_property(fsec, FILESEC_UUID, &fsacl->fsec_owner) != 0) {
if (errno != ENOENT)
return(-1);
bzero(&fsacl->fsec_owner, sizeof(fsacl->fsec_owner));
} else {
fsacl_used = 1;
}
if (filesec_get_property(fsec, FILESEC_GRPUUID, &fsacl->fsec_group) != 0) {
if (errno != ENOENT)
return(-1);
bzero(&fsacl->fsec_group, sizeof(fsacl->fsec_group));
} else {
fsacl_used = 1;
}
if (!fsacl_used)
fsacl = NULL;
}
switch (opcode) {
case OPENX:
return(__open_extended(path, flags, owner, group, mode, fsacl));
case MKFIFOX:
return(__mkfifo_extended(path, owner, group, mode, fsacl));
case MKDIRX:
return(__mkdir_extended(path, owner, group, mode, fsacl));
}
errno = EINVAL;
return(-1);
}
int
openx_np(const char *path, int flags, filesec_t fsec)
{
if (!(flags & O_CREAT) || (fsec == NULL))
return(open(path, flags));
return(_mkfilex_np(OPENX, path, flags, fsec));
}
int
mkfifox_np(const char *path, filesec_t fsec)
{
return(_mkfilex_np(MKFIFOX, path, 0, fsec));
}
int
mkdirx_np(const char *path, filesec_t fsec)
{
return(_mkfilex_np(MKDIRX, path, 0, fsec));
}