1/* 2 * Copyright (c) 2006, 2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#import <err.h> 37#import <stdio.h> 38#import <arpa/inet.h> 39#import <netdb.h> 40#import <sys/param.h> 41#import <sys/socket.h> 42 43#import <Foundation/Foundation.h> 44#import <SystemConfiguration/SystemConfiguration.h> 45#import <Heimdal/HeimdalSystemConfiguration.h> 46#import <Heimdal/krb5.h> 47#import <Heimdal/config_plugin.h> 48 49/** 50 * Configuration plugin uses configuration in SC for Kerberos 51 */ 52 53struct config_ctx { 54 SCDynamicStoreRef store; 55}; 56 57 58static krb5_error_code 59get_default_realm(krb5_context context, void *ptr, void *userctx, 60 void (*add_realms)(krb5_context, void *, krb5_const_realm)) 61{ 62 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE; 63 struct config_ctx *ctx = ptr; 64 NSAutoreleasePool *pool; 65 NSArray *vals = NULL; 66 67 @try { 68 pool = [[NSAutoreleasePool alloc] init]; 69 70 vals = (NSArray *)SCDynamicStoreCopyValue(ctx->store, HEIMDAL_SC_DEFAULT_REALM); 71 if (vals == NULL) 72 goto out; 73 74 for (NSString *a in vals) 75 add_realms(context, userctx, [a UTF8String]); 76 77 ret = 0; 78 out: 79 do { } while(0); 80 } 81 @catch (NSException * __unused exception) { } 82 @finally { 83 84 if (vals) 85 CFRelease((CFTypeRef)vals); 86 [pool drain]; 87 } 88 89 return ret; 90} 91 92static krb5_error_code 93get_host_domain(krb5_context context, const char *hostname, void *ptr, void *userptr, 94 void (*add_realms)(krb5_context, void *, krb5_const_realm)) 95{ 96 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE; 97 struct config_ctx *ctx = ptr; 98 NSAutoreleasePool *pool; 99 NSArray *vals = NULL; 100 101 @try { 102 pool = [[NSAutoreleasePool alloc] init]; 103 NSMutableArray *res = [NSMutableArray arrayWithCapacity:0]; 104 NSString *host = [NSString stringWithUTF8String:hostname]; 105 106 vals = (NSArray *)SCDynamicStoreCopyValue(ctx->store, HEIMDAL_SC_DOMAIN_REALM_MAPPING); 107 if (vals == NULL) 108 goto out; 109 110 /* search dict for matches, all matches from first domain that matches */ 111 for (NSDictionary *a in vals) { 112 for (NSString *domain in a) 113 if ([host hasSuffix:domain]) 114 [res addObject:[a valueForKey:domain]]; 115 116 if ([res count]) 117 break; 118 } 119 if ([res count] == 0) 120 goto out; 121 122 for (NSString *realm in res) 123 add_realms(context, userptr, [realm UTF8String]); 124 125 ret = 0; 126 out: 127 do { } while(0); 128 } 129 @catch (NSException * __unused exception) { } 130 @finally { 131 132 if (vals) 133 CFRelease((CFTypeRef)vals); 134 [pool drain]; 135 } 136 137 return ret; 138} 139 140static krb5_error_code 141config_init(krb5_context context, void **ptr) 142{ 143 struct config_ctx *ctx = calloc(1, sizeof(*ctx)); 144 145 if (ctx == NULL) 146 return ENOMEM; 147 148 ctx->store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCKerberosConfig"), NULL, NULL); 149 if (ctx->store == NULL) { 150 free(ctx); 151 return ENOMEM; 152 } 153 154 *ptr = ctx; 155 return 0; 156} 157 158static void 159config_fini(void *ptr) 160{ 161 struct config_ctx *ctx = ptr; 162 163 CFRelease(ctx->store); 164 free(ctx); 165} 166 167 168krb5plugin_config_ftable krb5_configuration = { 169 KRB5_PLUGIN_CONFIGURATION_VERSION_1, 170 config_init, 171 config_fini, 172 get_default_realm, 173 get_host_domain 174}; 175