static DWORD LsaAdBatchGatherSchemaModeGroup( IN OUT PLSA_AD_BATCH_ITEM pItem, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; DWORD dwValue = 0; dwError = LwLdapGetUInt32( hDirectory, pMessage, AD_LDAP_GID_TAG, &dwValue); if (LW_ERROR_INVALID_LDAP_ATTR_VALUE == dwError) { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED); dwError = LW_ERROR_SUCCESS; } BAIL_ON_LSA_ERROR(dwError); if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED)) { goto cleanup; } if (!dwValue) { LSA_LOG_DEBUG("gid must be non-zero for SID '%s'", pItem->pszSid); // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP); dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } pItem->GroupInfo.gid = (gid_t)dwValue; dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DISPLAY_NAME_TAG, &pItem->GroupInfo.pszAlias); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_PASSWD_TAG, &pItem->GroupInfo.pszPasswd); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
static DWORD LsaAdBatchGatherUnprovisionedModeUser( IN OUT PLSA_AD_BATCH_ITEM pItem, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; // Check for a machine account. Last character in name will be "$" // In the future, it would be safer to either add a new // LSA_AD_BATCH_OBJECT_TYPE_COMPUTER value or an additional // flag to distinguish a user from a computer. For current // AD releases however, this is a sufficient check if (pItem->pszSamAccountName[strlen(pItem->pszSamAccountName)-1] == '$') { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED); } #if 0 if (dwError != 0) { LSA_LOG_ERROR("Failed to get primary group ID for SID '%s'", pItem->pszSid); pItem->UserInfo.dwPrimaryGroupRid = WELLKNOWN_SID_DOMAIN_USER_GROUP_RID; dwError = 0; } #endif // Use display name for user gecos. dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DISPLAY_NAME_TAG, &pItem->UserInfo.pszGecos); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: 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 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 GetUserAttributes( HANDLE hDirectory, PSTR pszUserSID, PSTR pszDomainName, PGPUSER_AD_ATTRS * ppUserADAttrs ) { DWORD dwError = MAC_AD_ERROR_SUCCESS; PSTR pszDirectoryRoot = NULL; PSTR szAttributeList[] = {"*", NULL}; CHAR szQuery[1024]; LDAPMessage *pUserMessage = NULL; LDAPMessage *pDomainMessage = NULL; long lCount = 0; PGPUSER_AD_ATTRS pUserADAttrs = NULL; dwError = ADUConvertDomainToDN(pszDomainName, &pszDirectoryRoot); BAIL_ON_MAC_ERROR(dwError); sprintf(szQuery, "(objectsid=%s)", pszUserSID); dwError = LwLdapDirectorySearch( hDirectory, pszDirectoryRoot, LDAP_SCOPE_SUBTREE, szQuery, szAttributeList, &pUserMessage); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapCountEntries( hDirectory, pUserMessage, &lCount ); BAIL_ON_MAC_ERROR(dwError); if (lCount < 0) { dwError = MAC_AD_ERROR_INVALID_NAME; } else if (lCount == 0) { dwError = MAC_AD_ERROR_INVALID_NAME; } else if (lCount > 1) { dwError = MAC_AD_ERROR_INVALID_NAME; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapDirectorySearch( hDirectory, pszDirectoryRoot, LDAP_SCOPE_BASE, "(objectClass=*)", szAttributeList, &pDomainMessage); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapCountEntries( hDirectory, pDomainMessage, &lCount ); BAIL_ON_MAC_ERROR(dwError); if (lCount < 0) { dwError = MAC_AD_ERROR_INVALID_NAME; } else if (lCount == 0) { dwError = MAC_AD_ERROR_INVALID_NAME; } else if (lCount > 1) { dwError = MAC_AD_ERROR_INVALID_NAME; } BAIL_ON_MAC_ERROR(dwError); dwError = LwAllocateMemory(sizeof(GPUSER_AD_ATTRS), (PVOID *) &pUserADAttrs); BAIL_ON_MAC_ERROR(dwError); dwError = LwAllocateString(pszDomainName, &pUserADAttrs->pszADDomain); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "displayName", &pUserADAttrs->pszDisplayName); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "givenName", &pUserADAttrs->pszFirstName); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "sn", &pUserADAttrs->pszLastName); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "userPrincipalName", &pUserADAttrs->pszKerberosPrincipal); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "mail", &pUserADAttrs->pszEMailAddress); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "msExchHomeServerName", &pUserADAttrs->pszMSExchHomeServerName); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "homeMDB", &pUserADAttrs->pszMSExchHomeMDB); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "telephoneNumber", &pUserADAttrs->pszTelephoneNumber); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "facsimileTelephoneNumber", &pUserADAttrs->pszFaxTelephoneNumber); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "mobile", &pUserADAttrs->pszMobileTelephoneNumber); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "streetAddress", &pUserADAttrs->pszStreetAddress); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "postOfficeBox", &pUserADAttrs->pszPostOfficeBox); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "l", &pUserADAttrs->pszCity); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "st", &pUserADAttrs->pszState); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "postalCode", &pUserADAttrs->pszPostalCode); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "co", &pUserADAttrs->pszCountry); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "title", &pUserADAttrs->pszTitle); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "company", &pUserADAttrs->pszCompany); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "department", &pUserADAttrs->pszDepartment); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "homeDirectory", &pUserADAttrs->pszHomeDirectory); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "homeDrive", &pUserADAttrs->pszHomeDrive); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "pwdLastSet", &pUserADAttrs->pszPasswordLastSet); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pUserMessage, "userAccountControl", &pUserADAttrs->pszUserAccountControl); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); /* The settings below are found on the domain container for the user */ dwError = LwLdapGetString(hDirectory, pDomainMessage, "maxPwdAge", &pUserADAttrs->pszMaxMinutesUntilChangePassword); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pDomainMessage, "minPwdAge", &pUserADAttrs->pszMinMinutesUntilChangePassword); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pDomainMessage, "lockoutThreshhold", &pUserADAttrs->pszMaxFailedLoginAttempts); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pDomainMessage, "pwdHistoryLength", &pUserADAttrs->pszAllowedPasswordHistory); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pDomainMessage, "minPwdLength", &pUserADAttrs->pszMinCharsAllowedInPassword); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = MAC_AD_ERROR_SUCCESS; } BAIL_ON_MAC_ERROR(dwError); *ppUserADAttrs = pUserADAttrs; pUserADAttrs = NULL; error: FreeUserAttributes(pUserADAttrs); if (pszDirectoryRoot) { LwFreeString(pszDirectoryRoot); } if (pUserMessage) { ldap_msgfree(pUserMessage); } if (pDomainMessage) { ldap_msgfree(pDomainMessage); } return dwError; }
DWORD ADUGetPolicyInformation( HANDLE hDirectory, PCSTR pszPolicyDN, PGROUP_POLICY_OBJECT pGroupPolicyObject ) { DWORD dwError = MAC_AD_ERROR_SUCCESS; PSTR szAttributeList[] = {ADU_DISPLAY_NAME_ATTR, ADU_FLAGS_ATTR, ADU_FILESYS_PATH_ATTR, ADU_FUNCTIONALITY_VERSION_ATTR, ADU_MACHINE_EXTENSION_NAMES_ATTR, ADU_USER_EXTENSION_NAMES_ATTR, ADU_WQL_FILTER_ATTR, ADU_VERSION_NUMBER_ATTR, NULL }; LDAPMessage* pMessage = NULL; DWORD dwCount = 0; PSTR pszValue = NULL; DWORD dwValue = 0; dwError = LwLdapDirectorySearch( hDirectory, pszPolicyDN, LDAP_SCOPE_BASE, (PSTR)"(objectclass=*)", szAttributeList, &pMessage); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapCountEntries( hDirectory, pMessage, &dwCount ); BAIL_ON_MAC_ERROR(dwError); if (dwCount < 0) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } else if (dwCount == 0) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } else if (dwCount > 1) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pMessage, ADU_DISPLAY_NAME_ATTR, &pszValue); BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->pszDisplayName = pszValue; pszValue = NULL; dwError = LwLdapGetUInt32(hDirectory, pMessage, ADU_FLAGS_ATTR, &dwValue); BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->dwFlags = dwValue; dwError = LwLdapGetString(hDirectory, pMessage, ADU_FILESYS_PATH_ATTR, &pszValue); BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->pszgPCFileSysPath = pszValue; pszValue = NULL; dwError = LwLdapGetUInt32(hDirectory, pMessage, ADU_FUNCTIONALITY_VERSION_ATTR, &dwValue); BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->gPCFunctionalityVersion = dwValue; dwError = LwLdapGetString(hDirectory, pMessage, ADU_MACHINE_EXTENSION_NAMES_ATTR, &pszValue); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = 0; } BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->pszgPCMachineExtensionNames = pszValue; pszValue = NULL; dwError = LwLdapGetString(hDirectory, pMessage, ADU_USER_EXTENSION_NAMES_ATTR, &pszValue); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { dwError = 0; } BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->pszgPCUserExtensionNames = pszValue; pszValue = NULL; dwError = LwLdapGetUInt32(hDirectory, pMessage, ADU_VERSION_NUMBER_ATTR, &dwValue); BAIL_ON_MAC_ERROR(dwError); pGroupPolicyObject->dwVersion = dwValue; cleanup: LW_SAFE_FREE_STRING(pszValue); if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: LOG_ERROR("Failed to find policy or read GPO attributes for policy (%s)", pszPolicyDN); goto cleanup; }
DWORD ADUGetAllMCXPolicies( HANDLE hDirectory, PCSTR pszDN, PGROUP_POLICY_OBJECT * ppGroupPolicyObjects ) { DWORD dwError = MAC_AD_ERROR_SUCCESS; PSTR szAttributeList[] = { "distinguishedName", NULL }; PGROUP_POLICY_OBJECT pGPObjectList = NULL; PGROUP_POLICY_OBJECT pGPObject = NULL; LDAPMessage* pMessage = NULL; LDAPMessage* pLDAPMessage = NULL; DWORD dwCount = 0; PSTR pszValue = NULL; dwError = LwLdapDirectorySearch( hDirectory, pszDN, LDAP_SCOPE_ONELEVEL, (PSTR)"(&(objectclass=groupPolicyContainer)(|(gPCMachineExtensionNames=*{B9BF896E-F9EB-49B5-8E67-11E2EDAED06C}*)(gPCUserExtensionNames=*{07E500C4-20FD-4829-8F38-B5FF63FA0493}*)))", szAttributeList, &pMessage); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapCountEntries( hDirectory, pMessage, &dwCount ); BAIL_ON_MAC_ERROR(dwError); if (dwCount > 0) { pLDAPMessage = LwLdapFirstEntry(hDirectory, pMessage); } while(pLDAPMessage != NULL) { dwError = LwLdapGetString(hDirectory, pLDAPMessage, "distinguishedName", &pszValue); BAIL_ON_MAC_ERROR(dwError); dwError = LwAllocateMemory(sizeof(GROUP_POLICY_OBJECT), (PVOID*)&pGPObject); BAIL_ON_MAC_ERROR(dwError); pGPObject->pszPolicyDN = pszValue; pszValue = NULL; if (pGPObjectList != NULL) { pGPObject->pNext = pGPObjectList; pGPObjectList = pGPObject; } else { pGPObjectList = pGPObject; } pGPObject = NULL; pLDAPMessage = LwLdapNextEntry(hDirectory, pLDAPMessage); } if (*ppGroupPolicyObjects != NULL) { (*ppGroupPolicyObjects)->pNext = pGPObjectList; } else { *ppGroupPolicyObjects = pGPObjectList; } if (pMessage) { ldap_msgfree(pMessage); } if (pLDAPMessage) { ldap_msgfree(pLDAPMessage); } return dwError; cleanup: if (pMessage) { ldap_msgfree(pMessage); } if (pLDAPMessage) { ldap_msgfree(pLDAPMessage); } LW_SAFE_FREE_STRING(pszValue); ADU_SAFE_FREE_GPO_LIST (pGPObject); ADU_SAFE_FREE_GPO_LIST (pGPObjectList); return dwError; error: if (ppGroupPolicyObjects) *ppGroupPolicyObjects = NULL; goto cleanup; }
DWORD ADUGetMCXPolicy( HANDLE hDirectory, PCSTR pszDN, PCSTR pszGPOName, PGROUP_POLICY_OBJECT * ppGPO ) { DWORD dwError = MAC_AD_ERROR_SUCCESS; PSTR szAttributeList[] = { "distinguishedName", NULL }; char szQuery[512] = {0}; PGROUP_POLICY_OBJECT pGPObject = NULL; LDAPMessage* pMessage = NULL; DWORD dwCount = 0; PSTR pszValue = NULL; sprintf(szQuery, "(&(objectclass=groupPolicyContainer)(%s=%s))", ADU_DISPLAY_NAME_ATTR, pszGPOName); dwError = LwLdapDirectorySearch( hDirectory, pszDN, LDAP_SCOPE_ONELEVEL, szQuery, szAttributeList, &pMessage); BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapCountEntries( hDirectory, pMessage, &dwCount ); BAIL_ON_MAC_ERROR(dwError); if (dwCount < 0) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } else if (dwCount == 0) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } else if (dwCount > 1) { dwError = MAC_AD_ERROR_NO_SUCH_POLICY; } BAIL_ON_MAC_ERROR(dwError); dwError = LwLdapGetString(hDirectory, pMessage, "distinguishedName", &pszValue); BAIL_ON_MAC_ERROR(dwError); dwError = LwAllocateMemory(sizeof(GROUP_POLICY_OBJECT), (PVOID*)&pGPObject); BAIL_ON_MAC_ERROR(dwError); pGPObject->pszPolicyDN = pszValue; pszValue = NULL; *ppGPO = pGPObject; pGPObject = NULL; cleanup: if (pMessage) { ldap_msgfree(pMessage); } LW_SAFE_FREE_STRING(pszValue); ADU_SAFE_FREE_GPO_LIST (pGPObject); return dwError; error: if (ppGPO) *ppGPO = NULL; goto cleanup; }
DWORD LsaAdBatchGatherPseudoObject( IN PAD_PROVIDER_DATA pProviderData, IN OUT PLSA_AD_BATCH_ITEM pItem, IN LSA_AD_BATCH_OBJECT_TYPE ObjectType, IN BOOLEAN bIsSchemaMode, IN OPTIONAL DWORD dwKeywordValuesCount, IN OPTIONAL PSTR* ppszKeywordValues, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; PSTR pszComparePseudoDn = NULL; LSA_ASSERT(LSA_IS_XOR(LsaAdBatchIsDefaultSchemaMode(pProviderData), ppszKeywordValues)); SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_PSEUDO); dwError = LsaAdBatchGatherObjectType(pItem, ObjectType); BAIL_ON_LSA_ERROR(dwError); if (!pItem->pszSid) { dwError = LsaAdBatchGatherPseudoSid( &pItem->pszSid, pProviderData, dwKeywordValuesCount, ppszKeywordValues, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); } if (!pItem->pszPseudoDn) { dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DN_TAG, &pItem->pszPseudoDn); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pItem->pszPseudoDn)) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } } pItem->FoundPseudoCount++; if (pItem->FoundPseudoCount > 1) { dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DN_TAG, &pszComparePseudoDn); BAIL_ON_LSA_ERROR(dwError); LSA_LOG_WARNING("Found pseudo object %s that conflicts with pseudo object %s for SID %s", LSA_SAFE_LOG_STRING(pItem->pszPseudoDn), LSA_SAFE_LOG_STRING(pszComparePseudoDn), LSA_SAFE_LOG_STRING(pItem->pszSid)); dwError = LW_ERROR_DUPLICATE_USER_OR_GROUP; BAIL_ON_LSA_ERROR(dwError); } if (bIsSchemaMode) { dwError = LsaAdBatchGatherSchemaMode( pItem, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); // In default Schema mode, originally the following portion of code tries to gather real use information // using 'pMessage' obtained during pseudo objects lookup // However, a GC search is used on pseudo objects lookup, // Some of the attributes, such as user-specific attributes, i.e. 'accountExpires' etc. // are not available in GC. We still need to look up real objects in that particular domain for those missing attributes // Hence, we do not gather real object information until we actually do a real object lookup later on. #if 0 if (LsaAdBatchIsDefaultSchemaMode() && !IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_REAL)) { dwError = LsaAdBatchGatherRealObject( pItem, ObjectType, NULL, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); } #endif } else { dwError = LsaAdBatchGatherNonSchemaMode( pItem, dwKeywordValuesCount, ppszKeywordValues); BAIL_ON_LSA_ERROR(dwError); } cleanup: LW_SAFE_FREE_STRING(pszComparePseudoDn); return dwError; error: SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ERROR); goto cleanup; }
DWORD LsaAdBatchGatherRealObjectInternal( IN PAD_PROVIDER_DATA pProviderData, IN OUT PLSA_AD_BATCH_ITEM pItem, IN OPTIONAL PDWORD pdwDirectoryMode, IN OPTIONAL ADConfigurationMode* pAdMode, IN LSA_AD_BATCH_OBJECT_TYPE ObjectType, IN OUT OPTIONAL PSTR* ppszSid, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; DWORD dwDirectoryMode = pdwDirectoryMode == NULL ? pProviderData->dwDirectoryMode : *pdwDirectoryMode; ADConfigurationMode adMode = pAdMode == NULL ? pProviderData->adConfigurationMode : *pAdMode; SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_REAL); dwError = LsaAdBatchGatherObjectType(pItem, ObjectType); BAIL_ON_LSA_ERROR(dwError); if (!pItem->pszSid) { if (ppszSid) { LSA_XFER_STRING(*ppszSid, pItem->pszSid); } else { dwError = ADLdap_GetObjectSid(hDirectory, pMessage, &pItem->pszSid); BAIL_ON_LSA_ERROR(dwError); } } if (LW_IS_NULL_OR_EMPTY_STR(pItem->pszSid)) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } LSA_ASSERT(!pItem->pszSamAccountName); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_SAM_NAME_TAG, &pItem->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pItem->pszSamAccountName)) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } LSA_ASSERT(!pItem->pszDn); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DN_TAG, &pItem->pszDn); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pItem->pszDn)) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } // Handle cases where real contains pseudo. if (DEFAULT_MODE == dwDirectoryMode && SchemaMode == adMode) { // But only if we are not being called by a pseudo // lookup for default schema mode. if (!IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_PSEUDO)) { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_PSEUDO); dwError = LsaAdBatchGatherSchemaMode( pItem, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); } } else if (UNPROVISIONED_MODE == dwDirectoryMode) { dwError = LsaAdBatchGatherUnprovisionedMode( pItem, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); } // User object has some AD-specific fields. if (LSA_AD_BATCH_OBJECT_TYPE_USER == pItem->ObjectType) { dwError = LsaAdBatchGatherRealUser( pItem, hDirectory, pMessage); BAIL_ON_LSA_ERROR(dwError); } cleanup: return dwError; error: SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ERROR); goto cleanup; }
static DWORD LsaAdBatchGatherRealUser( IN OUT PLSA_AD_BATCH_ITEM pItem, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; dwError = LwLdapGetUInt32( hDirectory, pMessage, AD_LDAP_PRIMEGID_TAG, &pItem->UserInfo.dwPrimaryGroupRid); BAIL_ON_LSA_ERROR(dwError); LSA_ASSERT(!pItem->UserInfo.pszUserPrincipalName); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_UPN_TAG, &pItem->UserInfo.pszUserPrincipalName); BAIL_ON_LSA_ERROR(dwError); if (pItem->UserInfo.pszUserPrincipalName) { // Do not touch the non-realm part, just the realm part // to make sure the realm conforms to spec. LsaPrincipalRealmToUpper(pItem->UserInfo.pszUserPrincipalName); } dwError = LwLdapGetUInt32( hDirectory, pMessage, AD_LDAP_USER_CTRL_TAG, &pItem->UserInfo.UserAccountControl); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { LSA_LOG_VERBOSE( "User %s has an invalid value for the userAccountControl" " attribute. Please check that it is set and that the " "machine account has permission to read it. Assuming 0x%x", pItem->pszSid, LSA_AD_UF_DEFAULT); pItem->UserInfo.UserAccountControl = LSA_AD_UF_DEFAULT; dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetUInt64( hDirectory, pMessage, AD_LDAP_ACCOUT_EXP_TAG, &pItem->UserInfo.AccountExpires); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { LSA_LOG_VERBOSE( "User %s has an invalid value for the accountExpires" " attribute. Please check that it is set and that the " "machine account has permission to read it.", pItem->pszSid); pItem->UserInfo.AccountExpires = 0; dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetUInt64( hDirectory, pMessage, AD_LDAP_PWD_LASTSET_TAG, &pItem->UserInfo.PasswordLastSet); if (dwError == LW_ERROR_INVALID_LDAP_ATTR_VALUE) { LSA_LOG_VERBOSE( "User %s has an invalid value for the passwordLastSet" " attribute. Please check that it is set and that the " "machine account has permission to read it.", pItem->pszSid); dwError = ADGetCurrentNtTime(&pItem->UserInfo.PasswordLastSet); } BAIL_ON_LSA_ERROR(dwError); LSA_ASSERT(!pItem->UserInfo.pszDisplayName); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DISPLAY_NAME_TAG, &pItem->UserInfo.pszDisplayName); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_WINDOWSHOMEFOLDER_TAG, &pItem->UserInfo.pszWindowsHomeFolder); BAIL_ON_LSA_ERROR(dwError); SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ACCOUNT_INFO_KNOWN); cleanup: return dwError; error: goto cleanup; }
static DWORD LsaAdBatchGatherSchemaModeUser( IN OUT PLSA_AD_BATCH_ITEM pItem, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; DWORD dwValue = 0; dwError = LwLdapGetUInt32( hDirectory, pMessage, AD_LDAP_UID_TAG, &dwValue); if (LW_ERROR_INVALID_LDAP_ATTR_VALUE == dwError) { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED); dwError = LW_ERROR_SUCCESS; } BAIL_ON_LSA_ERROR(dwError); if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED)) { goto cleanup; } if (!dwValue) { LSA_LOG_DEBUG("uid must be non-zero for SID '%s'", pItem->pszSid); // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP); dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } pItem->UserInfo.uid = (uid_t)dwValue; dwError = LwLdapGetUInt32( hDirectory, pMessage, AD_LDAP_GID_TAG, &dwValue); if (LW_ERROR_INVALID_LDAP_ATTR_VALUE == dwError) { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED); dwError = LW_ERROR_SUCCESS; } BAIL_ON_LSA_ERROR(dwError); if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED)) { goto cleanup; } if (!dwValue) { LSA_LOG_DEBUG("gid must be non-zero for SID '%s'", pItem->pszSid); // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP); dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } pItem->UserInfo.gid = (gid_t)dwValue; dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_ALIAS_TAG, &pItem->UserInfo.pszAlias); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_PASSWD_TAG, &pItem->UserInfo.pszPasswd); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_GECOS_TAG, &pItem->UserInfo.pszGecos); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_HOMEDIR_TAG, &pItem->UserInfo.pszHomeDirectory); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_SHELL_TAG, &pItem->UserInfo.pszShell); BAIL_ON_LSA_ERROR(dwError); #if 0 dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_LOCALWINDOWSHOMEFOLDER_TAG, &pItem->UserInfo.pszLocalWindowsHomeFolder); BAIL_ON_LSA_ERROR(dwError); #endif cleanup: return dwError; error: goto cleanup; }