NTSTATUS SamrSrvLookupDomain( /* [in] */ handle_t hBinding, /* [in] */ CONNECT_HANDLE hConn, /* [in] */ UNICODE_STRING *domain_name, /* [out] */ SID **ppSid ) { CHAR szDnToken[] = "DC"; wchar_t wszFilter[] = L"%ws=%u AND %ws=\'%ws\'"; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PCONNECT_CONTEXT pConnCtx = NULL; PWSTR pwszBase = NULL; WCHAR wszAttrObjectClass[] = DS_ATTR_OBJECT_CLASS; WCHAR wszAttrDomain[] = DS_ATTR_DOMAIN; WCHAR wszAttrObjectSID[] = DS_ATTR_OBJECT_SID; DWORD dwObjectClass = DS_OBJECT_CLASS_DOMAIN; WCHAR wszBuiltinDomainName[] = SAMR_BUILTIN_DOMAIN_NAME; PWSTR pwszDomainName = NULL; DWORD dwBaseLen = 0; DWORD dwScope = 0; PWSTR pwszFilter = NULL; DWORD dwFilterLen = 0; PWSTR wszAttributes[2]; PDIRECTORY_ENTRY pEntries = NULL; DWORD dwCount = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrVal = NULL; PSID pDomainSid = NULL; BAIL_ON_INVALID_PARAMETER(ppSid); BAIL_ON_INVALID_PARAMETER(domain_name); memset(wszAttributes, 0, sizeof(wszAttributes)); pConnCtx = (PCONNECT_CONTEXT)hConn; if (pConnCtx == NULL || pConnCtx->Type != SamrContextConnect) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntStatus = SamrSrvGetFromUnicodeString(&pwszDomainName, domain_name); BAIL_ON_NO_MEMORY(pwszDomainName); if (!wc16scasecmp(pwszDomainName, wszBuiltinDomainName)) { dwObjectClass = DS_OBJECT_CLASS_BUILTIN_DOMAIN; } dwBaseLen = domain_name->MaximumLength + ((sizeof(szDnToken) + 2) * sizeof(WCHAR)); dwFilterLen = (sizeof(wszAttrObjectClass) - 1) + 10 + (sizeof(wszAttrDomain) - 1) + domain_name->Length + sizeof(wszFilter); ntStatus = SamrSrvAllocateMemory(OUT_PPVOID(&pwszFilter), dwFilterLen); BAIL_ON_NTSTATUS_ERROR(ntStatus); if (sw16printfw(pwszFilter, dwFilterLen/sizeof(WCHAR), wszFilter, wszAttrObjectClass, dwObjectClass, wszAttrDomain, pwszDomainName) < 0) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } wszAttributes[0] = wszAttrObjectSID; wszAttributes[1] = NULL; dwError = DirectorySearch(pConnCtx->hDirectory, pwszBase, dwScope, pwszFilter, wszAttributes, FALSE, &pEntries, &dwCount); BAIL_ON_LSA_ERROR(dwError); if (dwCount == 1) { dwError = DirectoryGetEntryAttributeSingle(pEntries, &pAttr); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryGetAttributeValue(pAttr, &pAttrVal); BAIL_ON_LSA_ERROR(dwError); if (pAttrVal->Type == DIRECTORY_ATTR_TYPE_UNICODE_STRING) { ntStatus = SamrSrvAllocateSidFromWC16String( &pDomainSid, pAttrVal->data.pwszStringValue); BAIL_ON_NTSTATUS_ERROR(ntStatus); } else { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NTSTATUS_ERROR(ntStatus); } } else if (dwCount == 0) { ntStatus = STATUS_NO_SUCH_DOMAIN; BAIL_ON_NTSTATUS_ERROR(ntStatus); } else { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NTSTATUS_ERROR(ntStatus); } *ppSid = pDomainSid; cleanup: if (pwszBase) { SamrSrvFreeMemory(pwszBase); } if (pwszDomainName) { SamrSrvFreeMemory(pwszDomainName); } if (pwszFilter) { SamrSrvFreeMemory(pwszFilter); } if (pEntries) { DirectoryFreeEntries(pEntries, dwCount); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pDomainSid) { SamrSrvFreeMemory(&pDomainSid); } *ppSid = NULL; goto cleanup; }
NTSTATUS SamrSrvCreateDomAlias( /* [in] */ handle_t hBinding, /* [in] */ DOMAIN_HANDLE hDomain, /* [in] */ UNICODE_STRING *pAliasName, /* [in] */ UINT32 dwAccessMask, /* [out] */ ACCOUNT_HANDLE *phAlias, /* [out] */ UINT32 *pdwRid ) { NTSTATUS ntStatus = STATUS_SUCCESS; PDOMAIN_CONTEXT pDomCtx = NULL; PWSTR pwszAliasName = NULL; UNICODE_STRING Name = {0}; UINT32 ulAccessGranted = 0; pDomCtx = (PDOMAIN_CONTEXT)hDomain; if (pDomCtx == NULL || pDomCtx->Type != SamrContextDomain) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pDomCtx->dwAccessGranted & DOMAIN_ACCESS_CREATE_ALIAS)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntStatus = SamrSrvGetFromUnicodeString(&pwszAliasName, pAliasName); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = SamrSrvInitUnicodeStringEx(&Name, pwszAliasName); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = SamrSrvCreateAccount(hBinding, hDomain, &Name, DS_OBJECT_CLASS_LOCAL_GROUP, 0, dwAccessMask, phAlias, &ulAccessGranted, pdwRid); if (ntStatus == STATUS_USER_EXISTS) { ntStatus = STATUS_ALIAS_EXISTS; BAIL_ON_NTSTATUS_ERROR(ntStatus); } cleanup: if (pwszAliasName) { SamrSrvFreeMemory(pwszAliasName); } SamrSrvFreeUnicodeStringEx(&Name); return ntStatus; error: *phAlias = NULL; *pdwRid = 0; goto cleanup; }