|
|
/* ----------------------------------------------------------------------
Module: ULS.DLL (Service Provider) File: spils.cpp Content: This file contains the ILS specifics. History: 12/10/96 Chu, Lon-Chan [lonchanc] Created.
Copyright (c) Microsoft Corporation 1996-1997
---------------------------------------------------------------------- */
#include "ulsp.h"
#include "spinc.h"
#include "winsock.h"
#include "ping.h"
// Constant string for ISBU's special modify-operation attribute
//
const TCHAR c_szModOp[] = { TEXT ('s'), TEXT ('m'), TEXT ('o'), TEXT ('d'), TEXT ('o'), TEXT ('p'), TEXT ('\0'), TEXT ('0'), TEXT ('\0')}; //TEXT ("smodop\0000");
ULONG g_cbUserPrefix = sizeof (c_szModOp); TCHAR *g_pszUserPrefix = NULL; ULONG g_cbMtgPrefix = sizeof (c_szModOp); TCHAR *g_pszMtgPrefix = NULL;
CPing *g_pPing = NULL;
HRESULT IlsInitialize ( VOID ) { // Allocate the ping object
//
g_pPing = new CPing; if (g_pPing == NULL) return ILS_E_MEMORY;
// Allocate user prefix
//
g_pszUserPrefix = (TCHAR *) MemAlloc (g_cbUserPrefix); if (g_pszUserPrefix == NULL) return ILS_E_MEMORY;
// Fill in user prefix string
//
TCHAR *psz = g_pszUserPrefix; lstrcpy (psz, &c_szModOp[0]); psz += lstrlen (psz) + 1; lstrcpy (psz, TEXT ("0"));
// Allocate mtg prefix
//
g_pszMtgPrefix = (TCHAR *) MemAlloc (g_cbMtgPrefix); if (g_pszMtgPrefix == NULL) { MemFree (g_pszUserPrefix); g_pszUserPrefix = NULL; return ILS_E_MEMORY; }
// Fill in mtg prefix string
//
psz = g_pszMtgPrefix; lstrcpy (psz, &c_szModOp[0]); psz += lstrlen (psz) + 1; lstrcpy (psz, TEXT ("0"));
return S_OK; }
HRESULT IlsCleanup ( VOID ) { // Free the ping object
//
if (g_pPing != NULL) { delete g_pPing; g_pPing = NULL; }
// Free user prefix string
//
MemFree (g_pszUserPrefix); g_pszUserPrefix = NULL;
// Free mtg prefix string
//
MemFree (g_pszMtgPrefix); g_pszMtgPrefix = NULL;
return S_OK; }
ULONG IlsCalcModifyListSize ( ULONG cAttrs ) { ULONG cbSize;
// array itself
cbSize = (cAttrs + 1) * sizeof (LDAPMod *);
// array elements
cbSize += cAttrs * sizeof (LDAPMod);
// single valued attribute requires two pointers
cbSize += cAttrs * 2 * sizeof (TCHAR *);
return cbSize; }
LDAPMod * IlsGetModifyListMod ( LDAPMod ***pppMod, ULONG cAttrs, LONG AttrIdx ) { return (LDAPMod *) (((BYTE *) *pppMod) + (cAttrs + 1) * sizeof (LDAPMod *) + AttrIdx * (sizeof (LDAPMod) + 2 * sizeof (TCHAR *))); }
VOID IlsFillModifyListItem ( LDAPMod *pMod, TCHAR *pszAttrName, TCHAR *pszAttrValue ) { MyAssert (pMod != NULL); MyAssert (pszAttrName != NULL);
// Set attribute name
//
pMod->mod_type = pszAttrName;
// Set single valued attribute value
//
TCHAR **ppsz = (TCHAR **) (pMod + 1); pMod->mod_values = ppsz; *ppsz++ = (pszAttrValue != NULL) ? pszAttrValue : STR_EMPTY;
// Set null string to terminate this array of values
//
*ppsz = NULL; }
VOID IlsFillModifyListForAnyAttrs ( LDAPMod *apMod[], ULONG *puIndex, ANY_ATTRS *pAnyAttrs ) { LDAPMod *pMod; TCHAR *pszName, *pszValue; ULONG i = *puIndex, j;
// Put in extended attributes to add
//
pszName = pAnyAttrs->pszAttrsToAdd; for (j = 0; j < pAnyAttrs->cAttrsToAdd; j++) { pMod = apMod[i++]; pMod->mod_op = LDAP_MOD_ADD; pszValue = pszName + lstrlen (pszName) + 1; IlsFillModifyListItem (pMod, pszName, pszValue); pszName = pszValue + lstrlen (pszValue) + 1; }
// Put in extended attributes to modify
//
pszName = pAnyAttrs->pszAttrsToModify; for (j = 0; j < pAnyAttrs->cAttrsToModify; j++) { pMod = apMod[i++]; pMod->mod_op = LDAP_MOD_REPLACE; pszValue = pszName + lstrlen (pszName) + 1; IlsFillModifyListItem (pMod, pszName, pszValue); pszName = pszValue + lstrlen (pszValue) + 1; }
// Put in extended attributes to remove
//
pszName = pAnyAttrs->pszAttrsToRemove; for (j = 0; j < pAnyAttrs->cAttrsToRemove; j++) { pMod = apMod[i++]; pMod->mod_op = LDAP_MOD_DELETE; IlsFillModifyListItem (pMod, pszName, NULL); pszName = pszName + lstrlen (pszName) + 1; }
// Return the running index
//
*puIndex = i; }
TCHAR c_szModOp_AddApp[] = TEXT ("0"); TCHAR c_szModOp_DeleteApp[] = TEXT ("1"); TCHAR c_szModOp_ModifyUser[] = TEXT ("2"); TCHAR c_szModOp_ModifyApp[] = TEXT ("3");
VOID IlsFixUpModOp ( LDAPMod *pMod, LONG LdapModOp, LONG IsbuModOp ) { MyAssert (pMod != NULL);
pMod->mod_op = LdapModOp; // pMod->mod_op = LDAP_MOD_ADD; // lonchanc: MUST MUST MUST
pMod->mod_type = (TCHAR *) &c_szModOp[0]; pMod->mod_values = (TCHAR **) (pMod + 1);
switch (IsbuModOp) { case ISBU_MODOP_ADD_APP: *(pMod->mod_values) = &c_szModOp_AddApp[0]; break; case ISBU_MODOP_DELETE_APP: *(pMod->mod_values) = &c_szModOp_DeleteApp[0]; break; case ISBU_MODOP_MODIFY_USER: *(pMod->mod_values) = &c_szModOp_ModifyUser[0]; break; case ISBU_MODOP_MODIFY_APP: *(pMod->mod_values) = &c_szModOp_ModifyApp[0]; break; default: MyAssert (FALSE); break; } }
HRESULT IlsParseRefreshPeriod ( LDAP *ld, LDAPMessage *pLdapMsg, const TCHAR *pszTtlAttrName, ULONG *puTTL ) { MyAssert (ld != NULL); MyAssert (pLdapMsg != NULL); MyAssert (pszTtlAttrName != NULL); MyAssert (puTTL != NULL);
HRESULT hr; ULONG uRefreshPeriod; ULONG tcRefreshPeriod;
// Get the first entry
//
LDAPMessage *pEntry = ldap_first_entry (ld, pLdapMsg); if (pEntry == NULL) { MyAssert (FALSE); hr = ILS_E_MEMORY; goto MyExit; }
// Get the sTTL attribute
//
TCHAR **ppszAttrVal; ppszAttrVal = my_ldap_get_values (ld, pEntry, (TCHAR *) pszTtlAttrName); if (ppszAttrVal == NULL || *ppszAttrVal == NULL) { MyAssert (FALSE); hr = ILS_E_MEMORY; goto MyExit; }
// Convert string to long
//
uRefreshPeriod = ::GetStringLong (*ppszAttrVal);
// Reserve two-minute overhead
//
if (uRefreshPeriod > ILS_DEF_REFRESH_MARGIN_MINUTE) uRefreshPeriod -= ILS_DEF_REFRESH_MARGIN_MINUTE;
// Make sure we have a safe, reasonable refresh period at least
//
if (uRefreshPeriod < ILS_DEF_REFRESH_MARGIN_MINUTE) uRefreshPeriod = ILS_DEF_REFRESH_MARGIN_MINUTE;
// Convert min to ms
//
tcRefreshPeriod = Minute2TickCount (uRefreshPeriod);
// Free the attribute value
//
ldap_value_free (ppszAttrVal);
// Update ttl
//
*puTTL = uRefreshPeriod; // in unit of minute
hr = S_OK;
MyExit:
if (hr != S_OK) { MyAssert (FALSE); }
return hr; }
HRESULT IlsUpdateOneAttr ( SERVER_INFO *pServerInfo, TCHAR *pszDN, TCHAR *pszAttrName, TCHAR *pszAttrValue, LONG nModifyMagic, ULONG cPrefix, TCHAR *pszPrefix, SP_CSession **ppSession, // output
ULONG *puMsgID ) // output
{ MyAssert (pServerInfo != NULL); MyAssert (pszDN != NULL); MyAssert (pszAttrName != NULL); MyAssert (pszAttrValue != NULL); MyAssert ( nModifyMagic == ISBU_MODOP_MODIFY_USER || nModifyMagic == ISBU_MODOP_MODIFY_APP); MyAssert (ppSession != NULL); MyAssert (puMsgID != NULL);
// Build modify array for ldap_modify()
//
LDAP *ld; LDAPMod **ppMod = NULL; ULONG cTotal = 0; HRESULT hr = IlsFillDefStdAttrsModArr (&ppMod, 1, // one attribute (i.e. IP addr)
1, // max? there is only one attr, come on
&cTotal, nModifyMagic, cPrefix, pszPrefix); if (hr != S_OK) goto MyExit;
// Fill in modify list
//
MyAssert (ppMod != NULL); LDAPMod *pMod; pMod = ppMod[cPrefix]; MyAssert (pMod != NULL); pMod->mod_type = pszAttrName;
// Put in ip address
//
pMod->mod_values = (TCHAR **) (pMod + 1); *(pMod->mod_values) = pszAttrValue;
// Get the session object
//
hr = g_pSessionContainer->GetSession (ppSession, pServerInfo, FALSE); if (hr != S_OK) goto MyExit; MyAssert (*ppSession != NULL);
// Get the ldap session
//
ld = (*ppSession)->GetLd (); MyAssert (ld != NULL);
// Send the data over the wire
//
*puMsgID = ldap_modify (ld, pszDN, ppMod); if (*puMsgID == -1) { hr = ::LdapError2Hresult (ld->ld_errno); (*ppSession)->Disconnect (); goto MyExit; }
// Success
//
hr = S_OK; MyExit:
MemFree (ppMod); return hr; }
HRESULT IlsUpdateIPAddress ( SERVER_INFO *pServerInfo, TCHAR *pszDN, TCHAR *pszIPAddrName, TCHAR *pszIPAddrValue, LONG nModifyMagic, ULONG cPrefix, TCHAR *pszPrefix ) { SP_CSession *pSession = NULL; LDAP *ld; ULONG uMsgID;
// Update the ip address attribute on the server
//
HRESULT hr = IlsUpdateOneAttr ( pServerInfo, pszDN, pszIPAddrName, pszIPAddrValue, nModifyMagic, cPrefix, pszPrefix, &pSession, &uMsgID); if (hr != S_OK) return hr;
// Get the ldap session
//
MyAssert (pSession != NULL); ld = pSession->GetLd (); MyAssert (ld != NULL);
// Let's wait for the result
//
LDAP_TIMEVAL TimeVal; TimeVal.tv_usec = 0; TimeVal.tv_sec = pSession->GetServerTimeoutInSecond ();
// We don't care the result.
// Should it fails, nothing we can do.
// We can try it again in next keep alive time.
//
LDAPMessage *pLdapMsg; pLdapMsg = NULL; ldap_result (ld, uMsgID, LDAP_MSG_ALL, &TimeVal, &pLdapMsg);
// Free message
//
if (pLdapMsg != NULL) ldap_msgfree (pLdapMsg);
// Free up the session
//
if (pSession != NULL) pSession->Disconnect ();
return S_OK; }
HRESULT IlsSendRefreshMsg ( SERVER_INFO *pServerInfo, TCHAR *pszBaseDN, TCHAR *pszTTL, TCHAR *pszRefreshFilter, ULONG *puTTL ) { MyAssert (pServerInfo != NULL); MyAssert (MyIsGoodString (pszBaseDN)); MyAssert (MyIsGoodString (pszTTL)); MyAssert (MyIsGoodString (pszRefreshFilter)); MyAssert (puTTL != NULL);
// Let's check to see if we need to use Ping...
//
if (g_pPing != NULL && g_pPing->IsAutodialEnabled ()) { LPTSTR pszServerName = My_strdup(pServerInfo->pszServerName); if (NULL == pszServerName) { return E_OUTOFMEMORY; } LPTSTR pszSeparator = My_strchr(pszServerName, _T(':')); if (NULL != pszSeparator) { *pszSeparator = _T('\0'); } DWORD dwIPAddr = inet_addr (pszServerName); MemFree(pszServerName); if (dwIPAddr != INADDR_NONE) { if (g_pPing->Ping (dwIPAddr, 10 * 1000, 9) == S_FALSE) { MyDebugMsg ((ZONE_KA, "KA: ping failed, network down\r\n"));
// The "ping" operation failed, but other operations failed
//
return ILS_E_NETWORK_DOWN; } } }
// Get the connection object
//
SP_CSession *pSession = NULL; HRESULT hr = g_pSessionContainer->GetSession (&pSession, pServerInfo, FALSE); if (hr != S_OK) { MyDebugMsg ((ZONE_KA, "KA: network down, hr=0x%lX\r\n", hr));
// Report error
//
return ILS_E_NETWORK_DOWN; } MyAssert (pSession != NULL);
// Get the ldap session
//
LDAP *ld = pSession->GetLd (); MyAssert (ld != NULL);
// Set attributes to return
//
TCHAR *apszAttrNames[2]; apszAttrNames[0] = pszTTL; apszAttrNames[1] = NULL;
// Update options in ld
//
ld->ld_sizelimit = 0; // no limit in the num of entries to return
ld->ld_timelimit = 0; // no limit on the time to spend on the search
ld->ld_deref = LDAP_DEREF_ALWAYS;
// Send search query
//
MyDebugMsg ((ZONE_KA, "KA: calling ldap_search()...\r\n")); ULONG uMsgID = ::ldap_search ( ld, pszBaseDN, // base DN
LDAP_SCOPE_BASE, // scope
pszRefreshFilter, // filter
&apszAttrNames[0], // attrs[]
0); // both type and value
if (uMsgID == -1) { MyDebugMsg ((ZONE_KA, "KA: ldap_search() failed\r\n")); hr = ::LdapError2Hresult (ld->ld_errno); pSession->Disconnect (); return hr; }
// Let's wait for the result
//
LDAP_TIMEVAL TimeVal; TimeVal.tv_usec = 0; TimeVal.tv_sec = pSession->GetServerTimeoutInSecond ();
// Wait and get the result back
//
LDAPMessage *pLdapMsg = NULL; INT ResultType = ::ldap_result (ld, uMsgID, LDAP_MSG_ALL, &TimeVal, &pLdapMsg); if (ResultType == LDAP_RES_SEARCH_ENTRY || ResultType == LDAP_RES_SEARCH_RESULT) { if (pLdapMsg != NULL) { switch (pLdapMsg->lm_returncode) { case LDAP_NO_SUCH_OBJECT: MyDebugMsg ((ZONE_KA, "KA: no such object!\r\n"));
// Report error
//
hr = ILS_E_NEED_RELOGON; break;
case LDAP_SUCCESS: // Get the new refresh period
//
hr = ::IlsParseRefreshPeriod (ld, pLdapMsg, pszTTL, puTTL); break;
default: MyDebugMsg ((ZONE_KA, "KA: unknown lm_returncode=%ld\r\n", pLdapMsg->lm_returncode)); MyAssert (FALSE); hr = ::LdapError2Hresult (ld->ld_errno); break; } // Free this message
//
ldap_msgfree (pLdapMsg); } // if (pLdapMsg != NULL)
else { hr = ILS_E_FAIL; } } // not timeout
else { // Timeout
//
hr = ILS_E_TIMEOUT; }
// Free up the session
//
pSession->Disconnect (); return hr; }
HRESULT IlsFillDefStdAttrsModArr ( LDAPMod ***pppMod, DWORD dwFlags, ULONG cMaxAttrs, ULONG *pcTotal, // in/out parameter!!!
LONG IsbuModOp, ULONG cPrefix, TCHAR *pszPrefix ) {
MyAssert (pppMod != NULL); MyAssert (pcTotal != NULL); MyAssert ( (cPrefix == 0 && pszPrefix == NULL) || (cPrefix != 0 && pszPrefix != NULL));
// Figure out the num of attributes
//
ULONG cAttrs = 0; for (ULONG i = 0; i < cMaxAttrs; i++) { if (dwFlags & 0x01) cAttrs++; dwFlags >>= 1; }
// Allocate modify list
//
ULONG cTotal = *pcTotal + cPrefix + cAttrs; ULONG cbMod = IlsCalcModifyListSize (cTotal); *pppMod = (LDAPMod **) MemAlloc (cbMod); if (*pppMod == NULL) return ILS_E_MEMORY;
// Fill in the modify list
//
LDAPMod *pMod; for (i = 0; i < cTotal; i++) { pMod = IlsGetModifyListMod (pppMod, cTotal, i); (*pppMod)[i] = pMod; pMod->mod_values = (TCHAR **) (pMod + 1);
if (i < cPrefix) { pMod->mod_op = LDAP_MOD_REPLACE; pMod->mod_type = pszPrefix; pszPrefix += lstrlen (pszPrefix) + 1; *(pMod->mod_values) = pszPrefix; pszPrefix += lstrlen (pszPrefix) + 1; } }
// Fix up the first and the last ones
//
IlsFixUpModOp ((*pppMod)[0], LDAP_MOD_REPLACE, IsbuModOp); (*pppMod)[cTotal] = NULL;
// Return the total number of entries
//
*pcTotal = cTotal;
return S_OK; }
const TCHAR c_szAnyAttrPrefix[] = TEXT ("ILSA"); #define SIZE_ANY_ATTR_PREFIX (sizeof (c_szAnyAttrPrefix) / sizeof (TCHAR))
const TCHAR * UlsLdap_GetExtAttrNamePrefix ( VOID ) { return &c_szAnyAttrPrefix[0]; }
const TCHAR * IlsSkipAnyAttrNamePrefix ( const TCHAR *pszAttrName ) { MyAssert (pszAttrName != NULL);
const TCHAR *psz = IlsIsAnyAttrName (pszAttrName); if (psz == NULL) { MyAssert (FALSE); psz = pszAttrName; }
return psz; }
const TCHAR * IlsIsAnyAttrName ( const TCHAR *pszAttrName ) { BOOL fRet = FALSE; TCHAR *psz = (TCHAR *) pszAttrName;
if (pszAttrName != NULL) { if (lstrlen (pszAttrName) > SIZE_ANY_ATTR_PREFIX) { TCHAR c = pszAttrName[SIZE_ANY_ATTR_PREFIX-1]; psz[SIZE_ANY_ATTR_PREFIX-1] = TEXT ('\0'); fRet = (My_lstrcmpi (pszAttrName, &c_szAnyAttrPrefix[0]) == 0); psz[SIZE_ANY_ATTR_PREFIX-1] = c; } }
return (fRet ? &pszAttrName[SIZE_ANY_ATTR_PREFIX-1] : NULL); }
TCHAR * IlsPrefixNameValueArray ( BOOL fPair, ULONG cAttrs, const TCHAR *pszAttrs ) { if (cAttrs == 0 || pszAttrs == NULL) { MyAssert (FALSE); return NULL; }
// compute the total size required
ULONG cbTotalSize = 0; ULONG cbThisSize; TCHAR *pszSrc = (TCHAR *) pszAttrs; for (ULONG i = 0; i < cAttrs; i++) { // get name size
cbThisSize = lstrlen (pszSrc) + 1; pszSrc += lstrlen (pszSrc) + 1;
// get value size as needed
if (fPair) { cbThisSize += lstrlen (pszSrc) + 1; pszSrc += lstrlen (pszSrc) + 1; }
// adjust the size
cbThisSize += SIZE_ANY_ATTR_PREFIX; cbThisSize *= sizeof (TCHAR);
// accumulate it
cbTotalSize += cbThisSize; }
// allocate the new buffer
TCHAR *pszPrefixAttrs = (TCHAR *) MemAlloc (cbTotalSize); if (pszPrefixAttrs == NULL) return NULL;
// copy the strings over to the new buffer
pszSrc = (TCHAR *) pszAttrs; TCHAR *pszDst = pszPrefixAttrs; for (i = 0; i < cAttrs; i++) { // copy prefix
lstrcpy (pszDst, &c_szAnyAttrPrefix[0]); pszDst += lstrlen (pszDst); // no plus 1
// copy name
lstrcpy (pszDst, pszSrc); pszDst += lstrlen (pszDst) + 1; pszSrc += lstrlen (pszSrc) + 1;
// copy value as needed
if (fPair) { lstrcpy (pszDst, pszSrc); pszDst += lstrlen (pszDst) + 1; pszSrc += lstrlen (pszSrc) + 1; } }
return pszPrefixAttrs; }
TCHAR * IlsBuildDN ( TCHAR *pszBaseDN, TCHAR *pszC, TCHAR *pszO, TCHAR *pszCN, TCHAR *pszObjectClass ) { MyAssert (MyIsGoodString (pszCN)); MyAssert (MyIsGoodString (pszObjectClass));
static TCHAR s_szC[] = TEXT ("c="); static TCHAR s_szO[] = TEXT ("o="); static TCHAR s_szCN[] = TEXT ("cn="); static TCHAR s_szObjectClass[] = TEXT ("objectClass="); static TCHAR s_szDelimiter[] = TEXT (", "); enum { C_LENGTH = 2 }; enum { O_LENGTH = 2 }; enum { CN_LENGTH = 3 }; enum { OBJECTCLASS_LENGTH = 12 }; enum { DELIMITER_LENGTH = 2 };
ULONG cchDN = 1; BOOL fInBaseDN;
ASSERT(MyIsGoodString(pszC));
cchDN += lstrlen (pszC) + DELIMITER_LENGTH + C_LENGTH;
if (MyIsGoodString (pszBaseDN)) { fInBaseDN = TRUE;
cchDN += lstrlen (pszBaseDN) + DELIMITER_LENGTH; } else { fInBaseDN = FALSE;
if (MyIsGoodString (pszO)) cchDN += lstrlen (pszO) + DELIMITER_LENGTH + O_LENGTH; }
if (MyIsGoodString (pszCN)) cchDN += lstrlen (pszCN) + CN_LENGTH;
if (MyIsGoodString (pszObjectClass)) cchDN += lstrlen (pszObjectClass) + DELIMITER_LENGTH + OBJECTCLASS_LENGTH;
TCHAR *pszDN = (TCHAR *) MemAlloc (cchDN * sizeof (TCHAR)); if (pszDN != NULL) { TCHAR *psz = pszDN; psz[0] = TEXT ('\0');
if (MyIsGoodString (pszC)) { lstrcpy (psz, &s_szC[0]); psz += lstrlen (psz); lstrcpy (psz, pszC); psz += lstrlen (psz); }
if (fInBaseDN) { if (psz != pszDN) { lstrcpy (psz, &s_szDelimiter[0]); psz += lstrlen (psz); }
lstrcpy (psz, pszBaseDN); psz += lstrlen (psz); } else { if (MyIsGoodString (pszO)) { if (psz != pszDN) { lstrcpy (psz, &s_szDelimiter[0]); psz += lstrlen (psz); }
lstrcpy (psz, &s_szO[0]); psz += lstrlen (psz); lstrcpy (psz, pszO); psz += lstrlen (psz); } }
if (MyIsGoodString (pszCN)) { if (psz != pszDN) { lstrcpy (psz, &s_szDelimiter[0]); psz += lstrlen (psz); }
lstrcpy (psz, &s_szCN[0]); psz += lstrlen (psz); lstrcpy (psz, pszCN); psz += lstrlen (psz); }
if (MyIsGoodString (pszObjectClass)) { if (psz != pszDN) { lstrcpy (psz, &s_szDelimiter[0]); psz += lstrlen (psz); }
lstrcpy (psz, &s_szObjectClass[0]); psz += lstrlen (psz); lstrcpy (psz, pszObjectClass); psz += lstrlen (psz); }
MyAssert (psz == pszDN + cchDN - 1); }
return pszDN; }
HRESULT IlsCreateAnyAttrsPrefix ( ANY_ATTRS *pAnyAttrs ) { if (pAnyAttrs->cAttrsToAdd != 0) { MyAssert (pAnyAttrs->pszAttrsToAdd != NULL); pAnyAttrs->pszAttrsToAdd = IlsPrefixNameValueArray ( TRUE, pAnyAttrs->cAttrsToAdd, (const TCHAR *) pAnyAttrs->pszAttrsToAdd); if (pAnyAttrs->pszAttrsToAdd == NULL) return ILS_E_MEMORY; }
if (pAnyAttrs->cAttrsToModify != 0) { MyAssert (pAnyAttrs->pszAttrsToModify != NULL); pAnyAttrs->pszAttrsToModify = IlsPrefixNameValueArray ( TRUE, pAnyAttrs->cAttrsToModify, (const TCHAR *) pAnyAttrs->pszAttrsToModify); if (pAnyAttrs->pszAttrsToModify == NULL) { MemFree (pAnyAttrs->pszAttrsToAdd); pAnyAttrs->pszAttrsToAdd = NULL; return ILS_E_MEMORY; } }
if (pAnyAttrs->cAttrsToRemove != 0) { MyAssert (pAnyAttrs->pszAttrsToRemove != NULL); pAnyAttrs->pszAttrsToRemove = IlsPrefixNameValueArray ( FALSE, pAnyAttrs->cAttrsToRemove, (const TCHAR *) pAnyAttrs->pszAttrsToRemove); if (pAnyAttrs->pszAttrsToRemove == NULL) { MemFree (pAnyAttrs->pszAttrsToAdd); MemFree (pAnyAttrs->pszAttrsToModify); pAnyAttrs->pszAttrsToAdd = NULL; pAnyAttrs->pszAttrsToModify = NULL; return ILS_E_MEMORY; } }
return S_OK; }
VOID IlsReleaseAnyAttrsPrefix ( ANY_ATTRS *pAnyAttrs ) { MemFree (pAnyAttrs->pszAttrsToAdd); MemFree (pAnyAttrs->pszAttrsToModify); MemFree (pAnyAttrs->pszAttrsToRemove); ZeroMemory (pAnyAttrs, sizeof (*pAnyAttrs)); }
TCHAR **my_ldap_get_values ( LDAP *ld, LDAPMessage *pEntry, TCHAR *pszRetAttrName ) { MyAssert (ld != NULL); MyAssert (pEntry != NULL); MyAssert (pszRetAttrName != NULL);
// Examine the first attribute
//
struct berelement *pContext = NULL; TCHAR *pszAttrName = ldap_first_attribute (ld, pEntry, &pContext); if (My_lstrcmpi (pszAttrName, pszRetAttrName) != 0) { // Examine the other attributes
//
while ((pszAttrName = ldap_next_attribute (ld, pEntry, pContext)) != NULL) { if (My_lstrcmpi (pszAttrName, pszRetAttrName) == 0) break; } }
// Get the attribute value if needed
//
TCHAR **ppszAttrValue = NULL; if (pszAttrName != NULL) ppszAttrValue = ldap_get_values (ld, pEntry, pszAttrName);
return ppszAttrValue; }
ULONG my_ldap_count_1st_entry_attributes ( LDAP *ld, LDAPMessage *pLdapMsg ) { MyAssert (ld != NULL); MyAssert (pLdapMsg != NULL);
ULONG cAttrs = 0;
// there should be only an entry
ULONG cEntries = ldap_count_entries (ld, pLdapMsg); if (cEntries > 0) { // there should be only one entry
MyAssert (cEntries == 1);
TCHAR *pszAttrName;
// get this entry
LDAPMessage *pEntry = ldap_first_entry (ld, pLdapMsg); if (pEntry == NULL) { MyAssert (FALSE); return cAttrs; }
// examine the first attribute
struct berelement *pContext = NULL; pszAttrName = ldap_first_attribute (ld, pEntry, &pContext); if (pszAttrName == NULL) { MyAssert (FALSE); return 0; } cAttrs = 1;
TCHAR **ppszAttrVal; ppszAttrVal = ldap_get_values (ld, pEntry, pszAttrName); if (ppszAttrVal != NULL) ldap_value_free (ppszAttrVal);
// step through the others
while ((pszAttrName = ldap_next_attribute (ld, pEntry, pContext)) != NULL) { cAttrs++;
ppszAttrVal = ldap_get_values (ld, pEntry, pszAttrName); if (ppszAttrVal != NULL) ldap_value_free (ppszAttrVal); } } // if cEntries > 0
return cAttrs; }
|