#include <stdio.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <membership.h>
#include <membershipPriv.h>
#include <CoreFoundation/CoreFoundation.h>
#include <DirectoryService/DirServices.h>
#include <DirectoryService/DirServicesUtils.h>
#include <DirectoryService/DirServicesConst.h>
#include <CoreFoundation/CFString.h>
#include <SystemConfiguration/SystemConfiguration.h>
#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(u_char* user_name, int len);
int start(CFBundleRef ref)
{
bundle = ref;
CFRetain(bundle);
acl_hook = dsaccess_authorize_user;
info("Directory Services Authorization plugin initialized\n");
return 0;
}
static int dsaccess_authorize_user(u_char* name, int len)
{
tDirReference dirRef;
tDirStatus dsResult = eDSNoErr;
int authorized = 0;
tDirNodeReference searchNodeRef;
tAttributeValueEntryPtr gUID;
UInt32 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) {
if ((dsResult = dsauth_get_search_node_ref(dirRef, 1, &searchNodeRef, &searchNodeCount)) == eDSNoErr) {
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)) {
result = mbr_check_service_membership(userid, VPN_SERVICE_NAME, &ismember);
if (result == ENOENT || (result == 0 && ismember != 0))
authorized = 1;
}
dsDeallocAttributeValueEntry(dirRef, gUID);
}
}
dsCloseDirNode(searchNodeRef); }
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;
}