/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* ----------------------------------------------------------------------------- * * Theory of operation : * * plugin to add support for authentication through Directory Services. * ----------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include "../../Helpers/pppd/pppd.h" #include "../../Helpers/pppd/pppd.h" #include "../DSAuthentication/DSUser.h" #define VPN_SERVICE_NAME "vpn" static CFBundleRef bundle = 0; static int dsaccess_authorize_user(char* user_name, int len); /* ----------------------------------------------------------------------------- plugin entry point, called by pppd ----------------------------------------------------------------------------- */ int start(CFBundleRef ref) { bundle = ref; CFRetain(bundle); // setup hooks acl_hook = dsaccess_authorize_user; info("Directory Services Authorization plugin initialized\n"); return 0; } //---------------------------------------------------------------------- // dsaccess_authorize_user //---------------------------------------------------------------------- static int dsaccess_authorize_user(char* name, int len) { tDirReference dirRef; tDirStatus dsResult = eDSNoErr; int authorized = 0; tDirNodeReference searchNodeRef; tAttributeValueEntryPtr gUID; unsigned long searchNodeCount; char* user_name; uuid_t userid; int result; int ismember; if (len < 1) { error("DSAccessControl plugin: invalid user name has zero length\n"); return 0; } if ((user_name = (char*)malloc(len + 1)) == 0) { error("DSAccessControl plugin: unable to allocate memory for user name\n"); return 0; } bcopy(name, user_name, len); *(user_name + len) = 0; if ((dsResult = dsOpenDirService(&dirRef)) == eDSNoErr) { // get the search node ref if ((dsResult = dsauth_get_search_node_ref(dirRef, 1, &searchNodeRef, &searchNodeCount)) == eDSNoErr) { // get the user's generated user Id if ((dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDS1AttrGeneratedUID, &gUID)) == eDSNoErr) { if (gUID != 0) { if (!mbr_string_to_uuid(gUID->fAttributeValueData.fBufferData, userid)) { // check if user is member authorized result = mbr_check_service_membership(userid, VPN_SERVICE_NAME, &ismember); if (result == ENOENT || (result == 0 && ismember != 0)) authorized = 1; } dsDeallocAttributeValueEntry(dirRef, gUID); } } dsCloseDirNode(searchNodeRef); // close the search node } dsCloseDirService(dirRef); } if (authorized) notice("DSAccessControl plugin: User '%s' authorized for access\n", user_name); else notice("DSAccessControl plugin: User '%s' not authorized for access\n", user_name); free(user_name); return authorized; }