1/* 2 * Copyright (c) 2000 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 24/* ----------------------------------------------------------------------------- 25 * 26 * Theory of operation : 27 * 28 * plugin to add support for authentication through Directory Services. 29 * 30----------------------------------------------------------------------------- */ 31 32 33#include <stdio.h> 34 35#include <syslog.h> 36#include <sys/types.h> 37#include <sys/time.h> 38#include <string.h> 39#include <membership.h> 40#include <membershipPriv.h> 41#include <CoreFoundation/CoreFoundation.h> 42 43#include <DirectoryService/DirServices.h> 44#include <DirectoryService/DirServicesUtils.h> 45#include <DirectoryService/DirServicesConst.h> 46#include <CoreFoundation/CFString.h> 47#include <SystemConfiguration/SystemConfiguration.h> 48#include "../../Helpers/pppd/pppd.h" 49#include "../../Helpers/pppd/pppd.h" 50#include "../DSAuthentication/DSUser.h" 51 52#define VPN_SERVICE_NAME "vpn" 53 54static CFBundleRef bundle = 0; 55 56static int dsaccess_authorize_user(u_char* user_name, int len); 57 58/* ----------------------------------------------------------------------------- 59plugin entry point, called by pppd 60----------------------------------------------------------------------------- */ 61 62int start(CFBundleRef ref) 63{ 64 65 bundle = ref; 66 67 CFRetain(bundle); 68 69 // setup hooks 70 acl_hook = dsaccess_authorize_user; 71 72 info("Directory Services Authorization plugin initialized\n"); 73 74 return 0; 75} 76 77 78//---------------------------------------------------------------------- 79// dsaccess_authorize_user 80//---------------------------------------------------------------------- 81static int dsaccess_authorize_user(u_char* name, int len) 82{ 83 84 tDirReference dirRef; 85 tDirStatus dsResult = eDSNoErr; 86 int authorized = 0; 87 tDirNodeReference searchNodeRef; 88 tAttributeValueEntryPtr gUID; 89 UInt32 searchNodeCount; 90 char* user_name; 91 uuid_t userid; 92 int result; 93 int ismember; 94 95 if (len < 1) { 96 error("DSAccessControl plugin: invalid user name has zero length\n"); 97 return 0; 98 } 99 if ((user_name = (char*)malloc(len + 1)) == 0) { 100 error("DSAccessControl plugin: unable to allocate memory for user name\n"); 101 return 0; 102 } 103 bcopy(name, user_name, len); 104 *(user_name + len) = 0; 105 106 if ((dsResult = dsOpenDirService(&dirRef)) == eDSNoErr) { 107 // get the search node ref 108 if ((dsResult = dsauth_get_search_node_ref(dirRef, 1, &searchNodeRef, &searchNodeCount)) == eDSNoErr) { 109 // get the user's generated user Id 110 if ((dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDS1AttrGeneratedUID, &gUID)) == eDSNoErr) { 111 if (gUID != 0) { 112 if (!mbr_string_to_uuid(gUID->fAttributeValueData.fBufferData, userid)) { 113 // check if user is member authorized 114 result = mbr_check_service_membership(userid, VPN_SERVICE_NAME, &ismember); 115 if (result == ENOENT || (result == 0 && ismember != 0)) 116 authorized = 1; 117 } 118 dsDeallocAttributeValueEntry(dirRef, gUID); 119 } 120 } 121 dsCloseDirNode(searchNodeRef); // close the search node 122 } 123 dsCloseDirService(dirRef); 124 } 125 126 if (authorized) 127 notice("DSAccessControl plugin: User '%s' authorized for access\n", user_name); 128 else 129 notice("DSAccessControl plugin: User '%s' not authorized for access\n", user_name); 130 free(user_name); 131 return authorized; 132} 133 134