1/* 2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#include <sys/types.h> 24#include <sys/acl.h> 25#include <errno.h> 26#include <unistd.h> 27#include <fcntl.h> 28#include <string.h> 29 30enum {OPENX, MKFIFOX, MKDIRX}; 31 32extern int __open_extended(const char *, int, uid_t, gid_t, int, struct kauth_filesec *); 33extern int __mkfifo_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *); 34extern int __mkdir_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *); 35 36static int 37_mkfilex_np(int opcode, const char *path, int flags, filesec_t fsec) 38{ 39 uid_t owner = KAUTH_UID_NONE; 40 gid_t group = KAUTH_GID_NONE; 41 mode_t mode = 0; 42 size_t size = 0; 43 int fsacl_used = 0; 44 struct kauth_filesec *fsacl = NULL; 45 struct kauth_filesec static_filesec; 46 47 /* handle extended security data */ 48 if (fsec != NULL) { 49 /* fetch basic parameters */ 50 if ((filesec_get_property(fsec, FILESEC_OWNER, &owner) != 0) && (errno != ENOENT)) 51 return(-1); 52 if ((filesec_get_property(fsec, FILESEC_GROUP, &group) != 0) && (errno != ENOENT)) 53 return(-1); 54 if ((filesec_get_property(fsec, FILESEC_MODE, &mode) != 0) && (errno != ENOENT)) 55 return(-1); 56 57 /* try to fetch the ACL */ 58 if (((filesec_get_property(fsec, FILESEC_ACL_RAW, &fsacl) != 0) || 59 (filesec_get_property(fsec, FILESEC_ACL_ALLOCSIZE, &size) != 0)) && 60 (errno != ENOENT)) 61 return(-1); 62 63 /* only valid for chmod */ 64 if (fsacl == _FILESEC_REMOVE_ACL) { 65 errno = EINVAL; 66 return(-1); 67 } 68 69 /* no ACL, use local filesec */ 70 if (fsacl == NULL) { 71 bzero(&static_filesec, sizeof(static_filesec)); 72 fsacl = &static_filesec; 73 fsacl->fsec_magic = KAUTH_FILESEC_MAGIC; 74 fsacl->fsec_entrycount = KAUTH_FILESEC_NOACL; 75 } else { 76 fsacl_used = 1; 77 } 78 79 /* grab the owner and group UUID if present */ 80 if (filesec_get_property(fsec, FILESEC_UUID, &fsacl->fsec_owner) != 0) { 81 if (errno != ENOENT) 82 return(-1); 83 bzero(&fsacl->fsec_owner, sizeof(fsacl->fsec_owner)); 84 } else { 85 fsacl_used = 1; 86 } 87 if (filesec_get_property(fsec, FILESEC_GRPUUID, &fsacl->fsec_group) != 0) { 88 if (errno != ENOENT) 89 return(-1); 90 bzero(&fsacl->fsec_group, sizeof(fsacl->fsec_group)); 91 } else { 92 fsacl_used = 1; 93 } 94 95 /* after all this, if we didn't find anything that needs it, don't pass it in */ 96 if (!fsacl_used) 97 fsacl = NULL; 98 } 99 100 switch (opcode) { 101 case OPENX: 102 return(__open_extended(path, flags, owner, group, mode, fsacl)); 103 case MKFIFOX: 104 return(__mkfifo_extended(path, owner, group, mode, fsacl)); 105 case MKDIRX: 106 return(__mkdir_extended(path, owner, group, mode, fsacl)); 107 } 108 /* should never get here */ 109 errno = EINVAL; 110 return(-1); 111} 112 113int 114openx_np(const char *path, int flags, filesec_t fsec) 115{ 116 /* optimise for the simple case */ 117 if (!(flags & O_CREAT) || (fsec == NULL)) 118 return(open(path, flags)); 119 return(_mkfilex_np(OPENX, path, flags, fsec)); 120} 121 122int 123mkfifox_np(const char *path, filesec_t fsec) 124{ 125 return(_mkfilex_np(MKFIFOX, path, 0, fsec)); 126} 127 128int 129mkdirx_np(const char *path, filesec_t fsec) 130{ 131 return(_mkfilex_np(MKDIRX, path, 0, fsec)); 132} 133