/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright (c) Likewise Software. All rights Reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the license, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy
* of the GNU Lesser General Public License along with this program. If
* not, see .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewise.com
*/
/*
* Copyright (C) Likewise Software. All rights reserved.
*
* Module Name:
*
* dscache.c
*
* Abstract:
*
* Likewise Base Library (LwBase)
*
* Directory Service Cache Exception API
* For services that can call into lookup functions like gethostbtname, gethostbyaddr, getpwnam
* on Macintosh systems running 10.5+, the DirectoryService can cause complications when lookups
* re-enter the DirectoryService /Search plugin. There is a mutex used to serialize access to the
* /Search plugin, which can block operations that require the above functions to complete a query
* about an object such as a user or group (which needs to fetch data from a remote host). A mechanism
* to bypass the /Search plugin is possible by having a given process notify the /Cache plugin (accessed
* prior to the /Search plugin) of it's process pid. The /Cache plugin checks the list of exception pids
* for the given query to process, and will call directly to the /Local or/or /BSD plugins, thus skipping
* past the /Search plugin and avoiding the mutex deadlock potential.
*
* These are helper functions used by daemon startup/shutdown operations to add or remove the process pid
* of the daemon to the /Cache DS plugin. The notificatin is done by calling Mac DirectoryService
* dsDoPluginCustomCall() with the operation code 10000 (to add) or 100001 (to remove) a pid exception.
*
* Authors: Glenn Curtis (glennc@likewise.com)
*
*/
#include "includes.h"
#if defined(__LWI_DARWIN__)
#include
#include
#include
typedef struct _dsCacheExceptionRqst {
AuthorizationExternalForm auth;
int32_t pid;
} DsCacheExceptionRqst;
// Local helper function to do the request
LW_NTSTATUS SendDSCustomCall(int command, int32_t pid);
#endif
LW_NTSTATUS
LwAddPidExceptionToDSCache(
int32_t pid
)
{
#if defined(__LWI_DARWIN__)
return SendDSCustomCall(10000, pid);
#else
return LW_STATUS_SUCCESS;
#endif
}
LW_NTSTATUS
LwRemovePidExceptionFromDSCache(
int32_t pid
)
{
#if defined(__LWI_DARWIN__)
return SendDSCustomCall(10001, pid);
#else
return LW_STATUS_SUCCESS;
#endif
}
#if defined(__LWI_DARWIN__)
LW_NTSTATUS
SendDSCustomCall(
int command,
int32_t pid
)
{
LW_NTSTATUS ntstatus = LW_STATUS_SUCCESS;
tDirReference hDirRef = 0;
tDirNodeReference hNodeRef = 0;
tDirStatus status = eDSNoErr;
const char nodeName[] = "/Cache";
tDataListPtr dirNodeName = NULL;
tDataBufferPtr pPidRequest = NULL;
tDataBufferPtr pPidResponse = NULL;
DsCacheExceptionRqst * pRequest = NULL;
status = dsOpenDirService(&hDirRef);
if(status != eDSNoErr)
{
ntstatus = LW_STATUS_UNSUCCESSFUL;
goto errorexit;
}
pPidRequest = dsDataBufferAllocate(hDirRef, sizeof(DsCacheExceptionRqst));
if (pPidRequest == NULL)
{
ntstatus = LW_STATUS_UNSUCCESSFUL;
goto errorexit;
}
pPidResponse = dsDataBufferAllocate(hDirRef, sizeof(int32_t));
if (pPidResponse == NULL)
{
ntstatus = LW_STATUS_UNSUCCESSFUL;
goto errorexit;
}
pRequest = (DsCacheExceptionRqst*)pPidRequest->fBufferData;
memset(&pRequest->auth, 0, sizeof(pRequest->auth));
pRequest->pid = pid;
pPidRequest->fBufferLength = sizeof(DsCacheExceptionRqst);
dirNodeName = dsBuildFromPath(hDirRef, nodeName, "/");
if (dirNodeName == NULL)
{
ntstatus = LW_STATUS_UNSUCCESSFUL;
goto errorexit;
}
status = dsOpenDirNode(hDirRef, dirNodeName, &hNodeRef);
if (status != eDSNoErr)
{
// This can happen on older Tiger Mac OS X 10.4 systems, as there is no /Cache plugin.
// It is okay to return successful in this scenario.
goto errorexit;
}
status = dsDoPlugInCustomCall(hNodeRef, command, pPidRequest, pPidResponse);
if (status != eDSNoErr)
{
ntstatus = LW_STATUS_UNSUCCESSFUL;
goto errorexit;
}
errorexit:
if (dirNodeName)
dsDataListDeallocate(hDirRef, dirNodeName);
if (hNodeRef)
dsCloseDirNode(hNodeRef);
if (pPidRequest)
dsDataBufferDeAllocate(hDirRef, pPidRequest);
if (pPidResponse)
dsDataBufferDeAllocate(hDirRef, pPidResponse);
if (hDirRef)
dsCloseDirService(hDirRef);
return ntstatus;
}
#endif
/*
local variables:
mode: c
c-basic-offset: 4
indent-tabs-mode: nil
tab-width: 4
end:
*/