1178825Sdfr/* 2178825Sdfr * Copyright (c) 2005, PADL Software Pty Ltd. 3178825Sdfr * All rights reserved. 4178825Sdfr * 5233294Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 6233294Sstas * 7178825Sdfr * Redistribution and use in source and binary forms, with or without 8178825Sdfr * modification, are permitted provided that the following conditions 9178825Sdfr * are met: 10178825Sdfr * 11178825Sdfr * 1. Redistributions of source code must retain the above copyright 12178825Sdfr * notice, this list of conditions and the following disclaimer. 13178825Sdfr * 14178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 15178825Sdfr * notice, this list of conditions and the following disclaimer in the 16178825Sdfr * documentation and/or other materials provided with the distribution. 17178825Sdfr * 18178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors 19178825Sdfr * may be used to endorse or promote products derived from this software 20178825Sdfr * without specific prior written permission. 21178825Sdfr * 22178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 23178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 26178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32178825Sdfr * SUCH DAMAGE. 33178825Sdfr */ 34178825Sdfr 35178825Sdfr#include "kcm_locl.h" 36178825Sdfr 37178825Sdfrkrb5_error_code 38178825Sdfrkcm_access(krb5_context context, 39178825Sdfr kcm_client *client, 40178825Sdfr kcm_operation opcode, 41178825Sdfr kcm_ccache ccache) 42178825Sdfr{ 43178825Sdfr int read_p = 0; 44178825Sdfr int write_p = 0; 45178825Sdfr uint16_t mask; 46178825Sdfr krb5_error_code ret; 47178825Sdfr 48178825Sdfr KCM_ASSERT_VALID(ccache); 49178825Sdfr 50178825Sdfr switch (opcode) { 51178825Sdfr case KCM_OP_INITIALIZE: 52178825Sdfr case KCM_OP_DESTROY: 53178825Sdfr case KCM_OP_STORE: 54178825Sdfr case KCM_OP_REMOVE_CRED: 55178825Sdfr case KCM_OP_SET_FLAGS: 56178825Sdfr case KCM_OP_CHOWN: 57178825Sdfr case KCM_OP_CHMOD: 58178825Sdfr case KCM_OP_GET_INITIAL_TICKET: 59178825Sdfr case KCM_OP_GET_TICKET: 60233294Sstas case KCM_OP_MOVE_CACHE: 61233294Sstas case KCM_OP_SET_DEFAULT_CACHE: 62233294Sstas case KCM_OP_SET_KDC_OFFSET: 63178825Sdfr write_p = 1; 64178825Sdfr read_p = 0; 65178825Sdfr break; 66178825Sdfr case KCM_OP_NOOP: 67178825Sdfr case KCM_OP_GET_NAME: 68178825Sdfr case KCM_OP_RESOLVE: 69178825Sdfr case KCM_OP_GEN_NEW: 70178825Sdfr case KCM_OP_RETRIEVE: 71178825Sdfr case KCM_OP_GET_PRINCIPAL: 72233294Sstas case KCM_OP_GET_CRED_UUID_LIST: 73233294Sstas case KCM_OP_GET_CRED_BY_UUID: 74233294Sstas case KCM_OP_GET_CACHE_UUID_LIST: 75233294Sstas case KCM_OP_GET_CACHE_BY_UUID: 76233294Sstas case KCM_OP_GET_DEFAULT_CACHE: 77233294Sstas case KCM_OP_GET_KDC_OFFSET: 78178825Sdfr write_p = 0; 79178825Sdfr read_p = 1; 80178825Sdfr break; 81233294Sstas default: 82233294Sstas ret = KRB5_FCC_PERM; 83233294Sstas goto out; 84178825Sdfr } 85178825Sdfr 86178825Sdfr if (ccache->flags & KCM_FLAGS_OWNER_IS_SYSTEM) { 87178825Sdfr /* System caches cannot be reinitialized or destroyed by users */ 88178825Sdfr if (opcode == KCM_OP_INITIALIZE || 89178825Sdfr opcode == KCM_OP_DESTROY || 90233294Sstas opcode == KCM_OP_REMOVE_CRED || 91233294Sstas opcode == KCM_OP_MOVE_CACHE) { 92178825Sdfr ret = KRB5_FCC_PERM; 93178825Sdfr goto out; 94178825Sdfr } 95178825Sdfr 96178825Sdfr /* Let root always read system caches */ 97233294Sstas if (CLIENT_IS_ROOT(client)) { 98178825Sdfr ret = 0; 99178825Sdfr goto out; 100178825Sdfr } 101178825Sdfr } 102178825Sdfr 103233294Sstas /* start out with "other" mask */ 104233294Sstas mask = S_IROTH|S_IWOTH; 105178825Sdfr 106233294Sstas /* root can do anything */ 107233294Sstas if (CLIENT_IS_ROOT(client)) { 108178825Sdfr if (read_p) 109233294Sstas mask |= S_IRUSR|S_IRGRP|S_IROTH; 110233294Sstas if (write_p) 111233294Sstas mask |= S_IWUSR|S_IWGRP|S_IWOTH; 112233294Sstas } 113233294Sstas /* same session same as owner */ 114233294Sstas if (kcm_is_same_session(client, ccache->uid, ccache->session)) { 115233294Sstas if (read_p) 116233294Sstas mask |= S_IROTH; 117233294Sstas if (write_p) 118233294Sstas mask |= S_IWOTH; 119233294Sstas } 120233294Sstas /* owner */ 121233294Sstas if (client->uid == ccache->uid) { 122233294Sstas if (read_p) 123178825Sdfr mask |= S_IRUSR; 124178825Sdfr if (write_p) 125178825Sdfr mask |= S_IWUSR; 126233294Sstas } 127233294Sstas /* group */ 128233294Sstas if (client->gid == ccache->gid) { 129178825Sdfr if (read_p) 130178825Sdfr mask |= S_IRGRP; 131178825Sdfr if (write_p) 132178825Sdfr mask |= S_IWGRP; 133178825Sdfr } 134178825Sdfr 135233294Sstas ret = (ccache->mode & mask) ? 0 : KRB5_FCC_PERM; 136178825Sdfr 137178825Sdfrout: 138178825Sdfr if (ret) { 139178825Sdfr kcm_log(2, "Process %d is not permitted to call %s on cache %s", 140178825Sdfr client->pid, kcm_op2string(opcode), ccache->name); 141178825Sdfr } 142178825Sdfr 143178825Sdfr return ret; 144178825Sdfr} 145178825Sdfr 146178825Sdfrkrb5_error_code 147178825Sdfrkcm_chmod(krb5_context context, 148178825Sdfr kcm_client *client, 149178825Sdfr kcm_ccache ccache, 150178825Sdfr uint16_t mode) 151178825Sdfr{ 152178825Sdfr KCM_ASSERT_VALID(ccache); 153178825Sdfr 154178825Sdfr /* System cache mode can only be set at startup */ 155178825Sdfr if (ccache->flags & KCM_FLAGS_OWNER_IS_SYSTEM) 156178825Sdfr return KRB5_FCC_PERM; 157178825Sdfr 158178825Sdfr if (ccache->uid != client->uid) 159178825Sdfr return KRB5_FCC_PERM; 160178825Sdfr 161178825Sdfr if (ccache->gid != client->gid) 162178825Sdfr return KRB5_FCC_PERM; 163178825Sdfr 164178825Sdfr HEIMDAL_MUTEX_lock(&ccache->mutex); 165178825Sdfr 166178825Sdfr ccache->mode = mode; 167178825Sdfr 168178825Sdfr HEIMDAL_MUTEX_unlock(&ccache->mutex); 169178825Sdfr 170178825Sdfr return 0; 171178825Sdfr} 172178825Sdfr 173178825Sdfrkrb5_error_code 174178825Sdfrkcm_chown(krb5_context context, 175178825Sdfr kcm_client *client, 176178825Sdfr kcm_ccache ccache, 177178825Sdfr uid_t uid, 178178825Sdfr gid_t gid) 179178825Sdfr{ 180178825Sdfr KCM_ASSERT_VALID(ccache); 181178825Sdfr 182178825Sdfr /* System cache owner can only be set at startup */ 183178825Sdfr if (ccache->flags & KCM_FLAGS_OWNER_IS_SYSTEM) 184178825Sdfr return KRB5_FCC_PERM; 185178825Sdfr 186178825Sdfr if (ccache->uid != client->uid) 187178825Sdfr return KRB5_FCC_PERM; 188178825Sdfr 189178825Sdfr if (ccache->gid != client->gid) 190178825Sdfr return KRB5_FCC_PERM; 191178825Sdfr 192178825Sdfr HEIMDAL_MUTEX_lock(&ccache->mutex); 193178825Sdfr 194178825Sdfr ccache->uid = uid; 195178825Sdfr ccache->gid = gid; 196178825Sdfr 197178825Sdfr HEIMDAL_MUTEX_unlock(&ccache->mutex); 198178825Sdfr 199178825Sdfr return 0; 200178825Sdfr} 201178825Sdfr 202