DWORD LocalFindObjectByName( HANDLE hProvider, PCSTR pszName, PCSTR pszDomainName, PDWORD pdwObjectClass, PWSTR* ppwszObjectDN ) { DWORD dwError = 0; PLOCAL_PROVIDER_CONTEXT pContext = (PLOCAL_PROVIDER_CONTEXT)hProvider; wchar16_t wszAttrNameObjectClass[] = LOCAL_DIR_ATTR_OBJECT_CLASS; wchar16_t wszAttrNameDN[] = LOCAL_DIR_ATTR_DISTINGUISHED_NAME; PWSTR wszAttrs[] = { &wszAttrNameObjectClass[0], &wszAttrNameDN[0], NULL }; DWORD dwNumAttrs = (sizeof(wszAttrs)/sizeof(wszAttrs[0])) - 1; PDIRECTORY_ENTRY pEntries = NULL; PDIRECTORY_ENTRY pEntry = NULL; DWORD dwNumEntries = 0; PCSTR pszFilterTemplate = LOCAL_DB_DIR_ATTR_SAM_ACCOUNT_NAME " = %Q" \ " AND " LOCAL_DB_DIR_ATTR_DOMAIN " = %Q"; PWSTR pwszFilter = NULL; PWSTR pwszObjectDN = NULL; DWORD dwObjectClass = LOCAL_OBJECT_CLASS_UNKNOWN; dwError = DirectoryAllocateWC16StringFilterPrintf( &pwszFilter, pszFilterTemplate, pszName, pszDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = DirectorySearch( pContext->hDirectory, NULL, 0, pwszFilter, wszAttrs, FALSE, &pEntries, &dwNumEntries); BAIL_ON_LSA_ERROR(dwError); if (dwNumEntries == 0) { dwError = LW_ERROR_NO_SUCH_OBJECT; } else if (dwNumEntries != 1) { dwError = LW_ERROR_DATA_ERROR; } BAIL_ON_LSA_ERROR(dwError); pEntry = &pEntries[0]; if (pEntry->ulNumAttributes != dwNumAttrs) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } dwError = LocalMarshalAttrToInteger( pEntry, &wszAttrNameObjectClass[0], &dwObjectClass); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToUnicodeString( pEntry, &wszAttrNameDN[0], &pwszObjectDN); BAIL_ON_LSA_ERROR(dwError); *pdwObjectClass = dwObjectClass; *ppwszObjectDN = pwszObjectDN; cleanup: LW_SAFE_FREE_MEMORY(pwszFilter); if (pEntries) { DirectoryFreeEntries(pEntries, dwNumEntries); } return dwError; error: *pdwObjectClass = LOCAL_OBJECT_CLASS_UNKNOWN; *ppwszObjectDN = NULL; LW_SAFE_FREE_MEMORY(pwszObjectDN); goto cleanup; }
DWORD LocalMarshalEntryToSecurityObject( PDIRECTORY_ENTRY pEntry, PLSA_SECURITY_OBJECT* ppObject ) { DWORD dwError = 0; static WCHAR wszAttrNameObjectClass[] = LOCAL_DIR_ATTR_OBJECT_CLASS; static WCHAR wszAttrNameUID[] = LOCAL_DIR_ATTR_UID; static WCHAR wszAttrNameGID[] = LOCAL_DIR_ATTR_GID; static WCHAR wszAttrNamePrimaryGroup[] = LOCAL_DIR_ATTR_PRIMARY_GROUP; static WCHAR wszAttrNameSamAccountName[] = LOCAL_DIR_ATTR_SAM_ACCOUNT_NAME; static WCHAR wszAttrNamePassword[] = LOCAL_DIR_ATTR_PASSWORD; static WCHAR wszAttrNameNTHash[] = LOCAL_DIR_ATTR_NT_HASH; static WCHAR wszAttrNameLMHash[] = LOCAL_DIR_ATTR_LM_HASH; static WCHAR wszAttrNameGecos[] = LOCAL_DIR_ATTR_GECOS; static WCHAR wszAttrNameShell[] = LOCAL_DIR_ATTR_SHELL; static WCHAR wszAttrNameHomedir[] = LOCAL_DIR_ATTR_HOME_DIR; static WCHAR wszAttrNameUPN[] = LOCAL_DIR_ATTR_USER_PRINCIPAL_NAME; static WCHAR wszAttrNameObjectSID[] = LOCAL_DIR_ATTR_OBJECT_SID; static WCHAR wszAttrNameAccountFlags[] = LOCAL_DIR_ATTR_ACCOUNT_FLAGS; static WCHAR wszAttrNameAccountExpiry[] = LOCAL_DIR_ATTR_ACCOUNT_EXPIRY; static WCHAR wszAttrNamePasswdLastSet[] = LOCAL_DIR_ATTR_PASSWORD_LAST_SET; static WCHAR wszAttrNameDN[] = LOCAL_DIR_ATTR_DISTINGUISHED_NAME; static WCHAR wszAttrNameNetBIOSDomain[] = LOCAL_DIR_ATTR_NETBIOS_NAME; PLSA_SECURITY_OBJECT pObject = NULL; DWORD dwObjectClass = 0; DWORD dwAccountFlags = 0; LONG64 llAccountExpiry = 0; LONG64 llPasswordLastSet = 0; DWORD dwUid = 0; DWORD dwGid = 0; BOOLEAN enableUnixIds = TRUE; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameObjectClass, &dwObjectClass); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory( sizeof(*pObject), OUT_PPVOID(&pObject)); BAIL_ON_LSA_ERROR(dwError); pObject->bIsLocal = TRUE; dwError = LocalCfgGetEnableUnixIds(&enableUnixIds); BAIL_ON_LSA_ERROR(dwError); pObject->enabled = enableUnixIds; switch (dwObjectClass) { case LOCAL_OBJECT_CLASS_USER: pObject->type = LSA_OBJECT_TYPE_USER; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameUID, &dwUid); BAIL_ON_LSA_ERROR(dwError); pObject->userInfo.uid = (uid_t) dwUid; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNamePrimaryGroup, &dwGid); BAIL_ON_LSA_ERROR(dwError); pObject->userInfo.gid = (gid_t) dwGid; dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameSamAccountName, &pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNamePassword, &pObject->userInfo.pszPasswd); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameGecos, &pObject->userInfo.pszGecos); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameShell, &pObject->userInfo.pszShell); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameHomedir, &pObject->userInfo.pszHomedir); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameObjectSID, &pObject->pszObjectSid); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameUPN, &pObject->userInfo.pszUPN); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameDN, &pObject->pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameNetBIOSDomain, &pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameAccountFlags, &dwAccountFlags); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToLargeInteger( pEntry, wszAttrNameAccountExpiry, &llAccountExpiry); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToLargeInteger( pEntry, wszAttrNamePasswdLastSet, &llPasswordLastSet); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAccountFlagsToSecurityObject( pObject, dwAccountFlags, llPasswordLastSet, llAccountExpiry); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pObject->userInfo.pszUnixName, "%s%c%s", pObject->pszNetbiosDomainName, LsaSrvDomainSeparator(), pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pObject->userInfo.pszUPN)) { dwError = LwAllocateStringPrintf( &pObject->userInfo.pszUPN, "%s@%s", pObject->pszSamAccountName, pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pObject->userInfo.pszUPN + strlen(pObject->pszSamAccountName) + 1); pObject->userInfo.bIsGeneratedUPN = TRUE; } dwError = LocalMarshalAttrToOctetStream( pEntry, wszAttrNameNTHash, &pObject->userInfo.pNtHash, &pObject->userInfo.dwNtHashLen); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToOctetStream( pEntry, wszAttrNameLMHash, &pObject->userInfo.pLmHash, &pObject->userInfo.dwLmHashLen); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); break; case LOCAL_OBJECT_CLASS_GROUP: pObject->type = LSA_OBJECT_TYPE_GROUP; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameGID, &dwGid); BAIL_ON_LSA_ERROR(dwError); pObject->groupInfo.gid = dwGid; dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameSamAccountName, &pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameDN, &pObject->pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameObjectSID, &pObject->pszObjectSid); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameNetBIOSDomain, &pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pObject->groupInfo.pszUnixName, "%s%c%s", pObject->pszNetbiosDomainName, LsaSrvDomainSeparator(), pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_LSA_ERROR(dwError); } *ppObject = pObject; cleanup: return dwError; error: *ppObject = NULL; if (pObject) { LsaUtilFreeSecurityObject(pObject); } goto cleanup; }