DWORD LwGetCurrentDirectoryPath( PSTR* ppszPath ) { DWORD dwError = 0; CHAR szBuf[PATH_MAX+1]; PSTR pszPath = NULL; if (getcwd(szBuf, PATH_MAX) == NULL) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } dwError = LwAllocateString(szBuf, &pszPath); BAIL_ON_LW_ERROR(dwError); *ppszPath = pszPath; return dwError; error: if (pszPath) { LwFreeString(pszPath); } return dwError; }
DWORD LwLdapBindDirectory( HANDLE hDirectory, PCSTR pszServerName, BOOLEAN bSeal ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; PSTR pszTargetPrinciaplName = NULL; BOOLEAN bNeedCredentials = FALSE; // Leave the realm empty so that kerberos referrals are turned on. dwError = LwAllocateStringPrintf(&pszTargetPrinciaplName, "ldap/%s@", pszServerName); BAIL_ON_LW_ERROR(dwError); dwError = LwKrb5CheckInitiatorCreds(pszTargetPrinciaplName, &bNeedCredentials); BAIL_ON_LW_ERROR(dwError); if (bNeedCredentials) { dwError = SEC_E_NO_CREDENTIALS; BAIL_ON_LW_ERROR(dwError); } dwError = LwLdapBindDirectorySasl(pDirectory->ld, pszServerName, bSeal); BAIL_ON_LW_ERROR(dwError); error: LW_SAFE_FREE_STRING(pszTargetPrinciaplName); return dwError; }
DWORD LwStrndup( PCSTR pszInputString, size_t size, PSTR * ppszOutputString ) { DWORD dwError = 0; size_t copylen = 0; PSTR pszOutputString = NULL; if (!pszInputString || !ppszOutputString){ dwError = EINVAL; BAIL_ON_LW_ERROR(dwError); } for (copylen = 0; copylen < size && pszInputString[copylen]; copylen++); dwError = LwAllocateMemory(copylen+1, OUT_PPVOID(&pszOutputString)); BAIL_ON_LW_ERROR(dwError); memcpy(pszOutputString, pszInputString, copylen); pszOutputString[copylen] = 0; *ppszOutputString = pszOutputString; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszOutputString); goto cleanup; }
DWORD LwKrb5InitializeCredentials( IN PCSTR pszUserPrincipalName, IN PCSTR pszPassword, IN PCSTR pszCachePath, OUT OPTIONAL PDWORD pdwGoodUntilTime ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwGoodUntilTime = 0; PSTR pszTempCachePath = NULL; if (!pszCachePath) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LW_ERROR(dwError); } if (!strncmp(pszCachePath, "FILE:", sizeof("FILE:") - 1)) { dwError = LwAllocateStringPrintf(&pszTempCachePath, "%s.new", pszCachePath); BAIL_ON_LW_ERROR(dwError); } dwError = LwKrb5GetTgt( pszUserPrincipalName, pszPassword, pszTempCachePath ? pszTempCachePath : pszCachePath, &dwGoodUntilTime); BAIL_ON_LW_ERROR(dwError); if (pszTempCachePath) { dwError = LwMoveFile(pszTempCachePath + sizeof("FILE:") - 1, pszCachePath + sizeof("FILE:") - 1); BAIL_ON_LW_ERROR(dwError); } error: if (dwError) { dwGoodUntilTime = 0; } LW_SAFE_FREE_STRING(pszTempCachePath); if (pdwGoodUntilTime) { *pdwGoodUntilTime = dwGoodUntilTime; } return dwError; }
DWORD LwKrb5GetUserCachePath( uid_t uid, Krb5CacheType cacheType, PSTR* ppszCachePath ) { DWORD dwError = 0; PSTR pszCachePath = NULL; switch (cacheType) { case KRB5_InMemory_Cache: dwError = LwAllocateStringPrintf( &pszCachePath, "MEMORY:krb5cc_%ld", (long)uid); BAIL_ON_LW_ERROR(dwError); break; case KRB5_File_Cache: dwError = LwAllocateStringPrintf( &pszCachePath, "FILE:/tmp/krb5cc_%ld", (long)uid); BAIL_ON_LW_ERROR(dwError); break; default: dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LW_ERROR(dwError); break; } *ppszCachePath = pszCachePath; cleanup: return dwError; error: *ppszCachePath = NULL; goto cleanup; }
DWORD LwDuplicateStringArray( PSTR** pppNewStringArray, PDWORD pdwNewCount, PSTR* ppStringArray, DWORD dwCount ) { DWORD dwError = 0; PSTR* ppNewStringArray = NULL; DWORD dwNewCount = 0; if (dwCount) { DWORD i = 0; dwError = LwAllocateMemory( dwCount * sizeof(*ppNewStringArray), OUT_PPVOID(&ppNewStringArray)); BAIL_ON_LW_ERROR(dwError); dwNewCount = dwCount; for (i = 0; i < dwCount; i++) { dwError = LwAllocateString( ppStringArray[i], &ppNewStringArray[i]); BAIL_ON_LW_ERROR(dwError); } } cleanup: *pppNewStringArray = ppNewStringArray; if (pdwNewCount) { *pdwNewCount = dwNewCount; } return dwError; error: LwFreeStringArray(ppNewStringArray, dwNewCount); ppNewStringArray = NULL; dwNewCount = 0; goto cleanup; }
DWORD LwLdapGetString( HANDLE hDirectory, LDAPMessage* pMessage, PCSTR pszFieldName, PSTR* ppszValue ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; PSTR *ppszValues = NULL; PSTR pszValue = NULL; pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; ppszValues = (PSTR*)ldap_get_values(pDirectory->ld, pMessage, pszFieldName); if (ppszValues && ppszValues[0]) { dwError = LwAllocateString(ppszValues[0], &pszValue); BAIL_ON_LW_ERROR(dwError); } *ppszValue = pszValue; cleanup: if (ppszValues) { ldap_value_free(ppszValues); } return dwError; error: *ppszValue = NULL; LW_SAFE_FREE_STRING(pszValue); goto cleanup; }
DWORD LwByteArrayToHexStr( IN UCHAR* pucByteArray, IN DWORD dwByteArrayLength, OUT PSTR* ppszHexString ) { DWORD dwError = 0; DWORD i = 0; PSTR pszHexString = NULL; dwError = LwAllocateMemory( (dwByteArrayLength*2 + 1) * sizeof(CHAR), OUT_PPVOID(&pszHexString)); BAIL_ON_LW_ERROR(dwError); for (i = 0; i < dwByteArrayLength; i++) { sprintf(pszHexString+(2*i), "%.2X", pucByteArray[i]); } *ppszHexString = pszHexString; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszHexString); *ppszHexString = NULL; goto cleanup; }
DWORD LwChangeOwner( PCSTR pszPath, uid_t uid, gid_t gid ) { DWORD dwError = 0; while (1) { if (lchown(pszPath, uid, gid) < 0) { if (errno == EINTR) { continue; } dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } else { break; } } error: return dwError; }
DWORD LwGetOwnerAndPermissions( PCSTR pszSrcPath, uid_t * uid, gid_t * gid, mode_t * mode ) { DWORD dwError = 0; struct stat statbuf; memset(&statbuf, 0, sizeof(struct stat)); if (stat(pszSrcPath, &statbuf) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } *uid = statbuf.st_uid; *gid = statbuf.st_gid; *mode = statbuf.st_mode; error: return dwError; }
DWORD LwKrb5SetProcessDefaultCachePath( PCSTR pszCachePath ) { DWORD dwError = 0; PSTR pszEnvironmentEntry = NULL; static volatile PSTR pszSavedEnvironmentEntry = NULL; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; BOOLEAN bLocked = FALSE; dwError = pthread_mutex_lock(&lock); if (dwError) { dwError = LwMapErrnoToLwError(dwError); BAIL_ON_LW_ERROR(dwError); } bLocked = TRUE; dwError = LwAllocateStringPrintf(&pszEnvironmentEntry, "KRB5CCNAME=%s", pszCachePath); BAIL_ON_LW_ERROR(dwError); /* * putenv requires that the buffer not be free'd. */ if (putenv(pszEnvironmentEntry) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } LW_SAFE_FREE_STRING(pszSavedEnvironmentEntry); pszSavedEnvironmentEntry = pszEnvironmentEntry; pszEnvironmentEntry = NULL; error: LW_SAFE_FREE_STRING(pszEnvironmentEntry); if (bLocked) { pthread_mutex_unlock(&lock); } return dwError; }
DWORD LwCLdapOpenDirectory( IN PCSTR pszServerName, OUT PHANDLE phDirectory ) { DWORD dwError = LW_ERROR_SUCCESS; LDAP * ld = NULL; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; int rc = LDAP_VERSION3; PSTR pszURL = NULL; LW_BAIL_ON_INVALID_STRING(pszServerName); dwError = LwAllocateStringPrintf(&pszURL, "cldap://%s", pszServerName); BAIL_ON_LW_ERROR(dwError); dwError = ldap_initialize(&ld, pszURL); BAIL_ON_LDAP_ERROR(dwError); dwError = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &rc); BAIL_ON_LDAP_ERROR(dwError); dwError = ldap_set_option(ld, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF); BAIL_ON_LDAP_ERROR(dwError); dwError = LwAllocateMemory(sizeof(*pDirectory), OUT_PPVOID(&pDirectory)); BAIL_ON_LW_ERROR(dwError); pDirectory->ld = ld; error: LW_SAFE_FREE_STRING(pszURL); if (dwError) { if (pDirectory) { LwLdapCloseDirectory(pDirectory); pDirectory = NULL; } } *phDirectory = (HANDLE)pDirectory; return dwError; }
DWORD LwURLEncodeString( PCSTR pIn, PSTR *ppOut ) { DWORD dwError = 0; const char *pRequireEscape = "$&+,/:;=?@ \"'<>#%{}|\\^~[]`"; size_t outputPos = 0; size_t i = 0; PSTR pOut = NULL; for (i = 0; pIn[i]; i++) { if (pIn[i] < 0x20 || pIn[i] >= 0x7F || strchr(pRequireEscape, pIn[i]) != NULL) { outputPos+=3; } else { outputPos++; } } // Space for the NULL outputPos++; dwError = LwAllocateMemory( outputPos, OUT_PPVOID(&pOut)); BAIL_ON_LW_ERROR(dwError); for (outputPos = 0, i = 0; pIn[i]; i++) { if (pIn[i] < 0x20 || pIn[i] >= 0x7F || strchr(pRequireEscape, pIn[i]) != NULL) { sprintf(pOut + outputPos, "%%%.2X", (BYTE)pIn[i]); outputPos+=3; } else { pOut[outputPos] = pIn[i]; outputPos++; } } *ppOut = pOut; cleanup: return dwError; error: *ppOut = NULL; LW_SAFE_FREE_STRING(pOut); goto cleanup; }
DWORD LwLdapGetInt64( IN HANDLE hDirectory, IN LDAPMessage* pMessage, IN PCSTR pszFieldName, OUT int64_t * pqwValue ) { DWORD dwError = 0; PSTR pszValue = NULL; PSTR pszEndPtr = NULL; dwError = LwLdapGetString(hDirectory, pMessage, pszFieldName, &pszValue); BAIL_ON_LW_ERROR(dwError); if (pszValue) { #if SIZEOF_LONG == 8 *pqwValue = strtol(pszValue, &pszEndPtr, 10); #else *pqwValue = strtoll(pszValue, &pszEndPtr, 10); #endif if (pszEndPtr == NULL || pszEndPtr == pszValue || *pszEndPtr != '\0') { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LW_ERROR(dwError); } } else { dwError = LW_ERROR_INVALID_LDAP_ATTR_VALUE; // This error occurs very frequently (every time an unenabled user // or group is queried in default schema mode). So in order to avoid // log noise, BAIL_ON_LW_ERROR is not used here. goto error; } cleanup: LW_SAFE_FREE_STRING(pszValue); return dwError; error: *pqwValue = 0; goto cleanup; }
DWORD LwKrb5MoveCCacheToUserPath( krb5_context ctx, PCSTR pszNewCacheName, uid_t uid, gid_t gid ) { DWORD dwError = LW_ERROR_SUCCESS; PSTR pszCachePath = NULL; PCSTR pszCachePathReal = NULL; dwError = LwKrb5GetUserCachePath( uid, KRB5_File_Cache, &pszCachePath); BAIL_ON_LW_ERROR(dwError); if (strncasecmp(pszCachePath, "FILE:", sizeof("FILE:")-1)) { dwError = LW_ERROR_INTERNAL; BAIL_ON_LW_ERROR(dwError); } else { pszCachePathReal = pszCachePath + sizeof("FILE:") - 1; } dwError = LwMoveFile(pszNewCacheName, pszCachePathReal); BAIL_ON_LW_ERROR(dwError); /* Let the user read and write to their cache file (before this, only * root was allowed to read and write the file). */ dwError = LwChangeOwner(pszCachePathReal, uid, gid); BAIL_ON_LW_ERROR(dwError); cleanup: LW_SAFE_FREE_STRING(pszCachePath); return dwError; error: goto cleanup; }
DWORD LwKrb5GetDefaultRealm( PSTR* ppszRealm ) { DWORD dwError = 0; krb5_context ctx = NULL; PSTR pszKrb5Realm = NULL; PSTR pszRealm = NULL; krb5_init_context(&ctx); krb5_get_default_realm(ctx, &pszKrb5Realm); if (LW_IS_NULL_OR_EMPTY_STR(pszKrb5Realm)) { dwError = LW_ERROR_NO_DEFAULT_REALM; BAIL_ON_LW_ERROR(dwError); } dwError = LwAllocateString(pszKrb5Realm, &pszRealm); BAIL_ON_LW_ERROR(dwError); *ppszRealm = pszRealm; cleanup: if (pszKrb5Realm) { krb5_free_default_realm(ctx, pszKrb5Realm); } krb5_free_context(ctx); return(dwError); error: *ppszRealm = NULL; LW_SAFE_FREE_STRING(pszRealm); goto cleanup; }
DWORD LwChangeOwnerAndPermissions( PCSTR pszPath, uid_t uid, gid_t gid, mode_t dwFileMode ) { DWORD dwError = 0; dwError = LwChangeOwner(pszPath, uid, gid); BAIL_ON_LW_ERROR(dwError); dwError = LwChangePermissions(pszPath, dwFileMode); BAIL_ON_LW_ERROR(dwError); error: return dwError; }
DWORD LwGssGetErrorMessage( OUT PSTR* ppszErrorMessage, IN OPTIONAL PCSTR pszGssFunction, IN OM_uint32 MajorStatus, IN OM_uint32 MinorStatus ) { DWORD dwError = 0; PSTR pszErrorMessage = NULL; PSTR pszMajorMessage = NULL; PSTR pszMinorMessage = NULL; dwError = LwGssGetSingleErrorMessage(&pszMajorMessage, MajorStatus, TRUE); BAIL_ON_LW_ERROR(dwError); dwError = LwGssGetSingleErrorMessage(&pszMinorMessage, MinorStatus, FALSE); BAIL_ON_LW_ERROR(dwError); dwError = LwAllocateStringPrintf(&pszErrorMessage, "GSS API error calling %s(): " "majorStatus = 0x%08x (%s), " "minorStatus = 0x%08x (%s)", pszGssFunction, MajorStatus, pszMajorMessage, MinorStatus, pszMinorMessage); BAIL_ON_LW_ERROR(dwError); error: if (dwError) { LW_SAFE_FREE_STRING(pszErrorMessage); } LW_SAFE_FREE_STRING(pszMajorMessage); LW_SAFE_FREE_STRING(pszMinorMessage); *ppszErrorMessage = pszErrorMessage; return dwError; }
DWORD LwLdapGetDN( HANDLE hDirectory, LDAPMessage* pMessage, PSTR* ppszValue ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; PSTR pszLdapValue = NULL; PSTR pszValue = NULL; pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; pszLdapValue = ldap_get_dn(pDirectory->ld, pMessage); if (LW_IS_NULL_OR_EMPTY_STR(pszLdapValue)) { dwError = LW_ERROR_INVALID_LDAP_ATTR_VALUE; BAIL_ON_LW_ERROR(dwError); } dwError = LwAllocateString(pszLdapValue, &pszValue); BAIL_ON_LW_ERROR(dwError); *ppszValue = pszValue; cleanup: if (pszLdapValue) { ldap_memfree(pszLdapValue); } return dwError; error: *ppszValue = NULL; LW_SAFE_FREE_STRING(pszValue); goto cleanup; }
DWORD LwAllocateString( PCSTR pszInputString, PSTR* ppszOutputString ) { DWORD dwError = 0; DWORD dwLen = 0; PSTR pszOutputString = NULL; if (!pszInputString) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LW_ERROR(dwError); } dwLen = strlen(pszInputString); dwError = LwAllocateMemory(dwLen+1, OUT_PPVOID(&pszOutputString)); BAIL_ON_LW_ERROR(dwError); if (dwLen) { memcpy(pszOutputString, pszInputString, dwLen); } *ppszOutputString = pszOutputString; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszOutputString); *ppszOutputString = NULL; goto cleanup; }
DWORD LwLdapGetBytes( HANDLE hDirectory, LDAPMessage* pMessage, PSTR pszFieldName, PBYTE* ppszByteValue, PDWORD pszByteLen ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; struct berval **ppszValues = NULL; PBYTE pszByteValue = NULL; DWORD szByteLen = 0; pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; ppszValues = ldap_get_values_len(pDirectory->ld, pMessage, pszFieldName); if (ppszValues && ppszValues[0]){ if (ppszValues[0]->bv_len != 0){ dwError = LwAllocateMemory( sizeof(BYTE) * ppszValues[0]->bv_len, OUT_PPVOID(&pszByteValue)); BAIL_ON_LW_ERROR(dwError); memcpy (pszByteValue, ppszValues[0]->bv_val, ppszValues[0]->bv_len * sizeof (BYTE)); szByteLen = ppszValues[0]->bv_len; } } *ppszByteValue = pszByteValue; *pszByteLen = szByteLen; cleanup: if (ppszValues) { ldap_value_free_len(ppszValues); } return dwError; error: *ppszByteValue = NULL; *pszByteLen = 0; LW_SAFE_FREE_MEMORY(pszByteValue); goto cleanup; }
DWORD LwLdapIsValidADEntry( HANDLE hDirectory, LDAPMessage* pMessage, PBOOLEAN pbValidADEntry ) { DWORD dwError = LW_ERROR_SUCCESS; PSTR pszValue = NULL; dwError = LwLdapGetDN( hDirectory, pMessage, &pszValue); BAIL_ON_LW_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszValue)) { dwError = LW_ERROR_INVALID_LDAP_ATTR_VALUE; BAIL_ON_LW_ERROR(dwError); } *pbValidADEntry = TRUE; cleanup: LW_SAFE_FREE_STRING(pszValue); return dwError; error: *pbValidADEntry = FALSE; goto cleanup; }
DWORD LwLdapGetParentDN( PCSTR pszObjectDN, PSTR* ppszParentDN ) { DWORD dwError = LW_ERROR_SUCCESS; PSTR pszParentDN = NULL; PSTR pComma = NULL; if (!pszObjectDN || !*pszObjectDN) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LW_ERROR(dwError); } pComma = strchr(pszObjectDN,','); if (!pComma) { dwError = LW_ERROR_LDAP_NO_PARENT_DN; BAIL_ON_LW_ERROR(dwError); } pComma++; dwError= LwAllocateString(pComma, &pszParentDN); BAIL_ON_LW_ERROR(dwError); *ppszParentDN = pszParentDN; return(dwError); error: *ppszParentDN = NULL; return(dwError); }
DWORD LwRemoveFile( PCSTR pszPath ) { DWORD dwError = 0; // POSIX says it will not return EINTR if (unlink(pszPath) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } error: return dwError; }
DWORD LwChangePermissions( PCSTR pszPath, mode_t dwFileMode ) { DWORD dwError = 0; // POSIX says it will not return EINTR if (chmod(pszPath, dwFileMode) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } error: return dwError; }
DWORD LwKrb5SetThreadDefaultCachePath( IN PCSTR pszCachePath, OUT PSTR* ppszPreviousCachePath ) { DWORD dwError = 0; DWORD dwMajorStatus = 0; DWORD dwMinorStatus = 0; PSTR pszOrigCachePath = NULL; // Set the default for gss dwMajorStatus = gss_krb5_ccache_name( (OM_uint32 *)&dwMinorStatus, pszCachePath, (ppszPreviousCachePath) ? (const char**)&pszOrigCachePath : NULL); BAIL_ON_GSS_ERROR(dwError, dwMajorStatus, dwMinorStatus); LW_LOG_DEBUG("Switched gss krb5 credentials path from %s to %s", LW_SAFE_LOG_STRING(pszOrigCachePath), LW_SAFE_LOG_STRING(pszCachePath)); if (ppszPreviousCachePath) { if (!LW_IS_NULL_OR_EMPTY_STR(pszOrigCachePath)) { dwError = LwAllocateString(pszOrigCachePath, ppszPreviousCachePath); BAIL_ON_LW_ERROR(dwError); } else { *ppszPreviousCachePath = NULL; } } cleanup: return dwError; error: if (ppszPreviousCachePath) { *ppszPreviousCachePath = NULL; } goto cleanup; }
DWORD LwHexCharToByte( CHAR cHexChar, UCHAR* pucByte ) { DWORD dwError = 0; UCHAR ucByte = 0; if (cHexChar >= '0' && cHexChar <= '9') { ucByte = (UCHAR)(cHexChar - '0'); } else if (cHexChar >= 'a' && cHexChar <= 'f') { ucByte = 10 + (UCHAR)(cHexChar - 'a'); } else if (cHexChar >= 'A' && cHexChar <= 'F') { ucByte = 10 + (UCHAR)(cHexChar - 'A'); } else { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LW_ERROR(dwError); } *pucByte = ucByte; cleanup: return dwError; error: *pucByte = 0; goto cleanup; }
DWORD LwKrb5GetDefaultCachePath( OUT PSTR* ppszCachePath ) { DWORD dwError = 0; PSTR pszCachePath = NULL; krb5_context ctx = NULL; const char *pszKrbDefault = NULL; krb5_error_code ret = 0; ret = krb5_init_context(&ctx); BAIL_ON_KRB_ERROR(ctx, ret); pszKrbDefault = krb5_cc_default_name(ctx); dwError = LwAllocateString( pszKrbDefault, &pszCachePath); BAIL_ON_LW_ERROR(dwError); *ppszCachePath = pszCachePath; cleanup: if (ctx) { krb5_free_context(ctx); } return dwError; error: *ppszCachePath = NULL; goto cleanup; }
DWORD LwLdapGetUInt32( HANDLE hDirectory, LDAPMessage* pMessage, PCSTR pszFieldName, PDWORD pdwValue ) { DWORD dwError = 0; PSTR pszValue = NULL; dwError = LwLdapGetString(hDirectory, pMessage, pszFieldName, &pszValue); BAIL_ON_LW_ERROR(dwError); if (pszValue) { *pdwValue = atoi(pszValue); } else { dwError = LW_ERROR_INVALID_LDAP_ATTR_VALUE; // This error occurs very frequently (every time an unenabled user // or group is queried in default schema mode). So in order to avoid // log noise, BAIL_ON_LW_ERROR is not used here. goto error; } cleanup: LW_SAFE_FREE_STRING(pszValue); return dwError; error: *pdwValue = 0; goto cleanup; }
DWORD LwRemoveDuplicateInodes( IN OUT PDWORD pdwFoundCount, IN OUT PSTR* ppszFoundPaths ) { DWORD dwError = 0; DWORD foundCount = *pdwFoundCount; DWORD outputIndex = 0; struct stat *pStats = NULL; DWORD index = 0; DWORD index2 = 0; dwError = LwAllocateMemory( foundCount * sizeof(pStats[0]), OUT_PPVOID(&pStats)); BAIL_ON_LW_ERROR(dwError); for (index = 0; index < foundCount; index++) { if (stat(ppszFoundPaths[index], &pStats[index]) < 0) { switch (errno) { case ELOOP: case ENOENT: case ENOTDIR: // These errors indicate a bad symlink. Treat the path as // unique from all others. pStats[index].st_dev = (dev_t)-1; pStats[index].st_ino = (ino_t)-1; break; default: dwError = LwMapErrnoToLwError(errno); BAIL_ON_LW_ERROR(dwError); } } } if (foundCount > 0) { // Even if the first index is a duplicate, we take that value over // another. outputIndex = 1; } for (index = 1; index < foundCount; index++) { // See if ppszFoundPaths[index] is a duplicate of any paths with a // lower index. if (pStats[index].st_ino != (ino_t)-1) { for (index2 = 0; index2 < index; index2++) { if (pStats[index].st_dev == pStats[index2].st_dev && pStats[index].st_ino == pStats[index2].st_ino) { LW_SAFE_FREE_STRING(ppszFoundPaths[index]); break; } } } if (ppszFoundPaths[index] != NULL) { ppszFoundPaths[outputIndex] = ppszFoundPaths[index]; outputIndex++; } } *pdwFoundCount = outputIndex; cleanup: LW_SAFE_FREE_MEMORY(pStats); return dwError; error: goto cleanup; }