示例#1
0
DWORD
LWNetSrvGetPrefixPath(
    PSTR* ppszPath
    )
{
    DWORD dwError = 0;
    PSTR pszPath = NULL;
    BOOLEAN bInLock = FALSE;
  
    LWNET_LOCK_SERVERINFO(bInLock);
    
    if (IsNullOrEmptyString(gpLwnetServerInfo->szPrefixPath)) {
      dwError = ERROR_PATH_NOT_FOUND;
      BAIL_ON_LWNET_ERROR(dwError);
    }
    
    dwError = LWNetAllocateString(gpLwnetServerInfo->szPrefixPath, &pszPath);
    BAIL_ON_LWNET_ERROR(dwError);

    *ppszPath = pszPath;

 cleanup:
    
    LWNET_UNLOCK_SERVERINFO(bInLock);
    
    return dwError;

 error:

    LWNET_SAFE_FREE_STRING(pszPath);

    *ppszPath = NULL;

    goto cleanup;
}
示例#2
0
/* "Second Level" NetBIOS name encoding */
DWORD
LWNetNbStrToNbName2(
    PSTR Fqdn,
    UINT8 suffix,
    PBYTE *retNbNameL2,
    PDWORD retNbNameL2Len)
{
    DWORD dwError = 0;
    DWORD len = 0;
    PSTR p = NULL;
    PSTR token = NULL;
    PSTR tokenPtr = NULL;
    UINT8 *retName = NULL;
    UINT8 *up = NULL;

    /*
     * 32=Max NetBIOS First Level encoding length
     * All . separators are replaced by 1 byte count, so
     * don't need to count number of dots to determine buffer length
     * 2=FirstLevel encoding length + ending length (by definition 0)
     */
    len = LWNB_NETBIOS_ENCNAME_LEN + strlen(Fqdn) + 2;
    dwError = LWNetAllocateMemory(sizeof(CHAR) * len,
                                  (PVOID*)&retName);
    BAIL_ON_LWNET_ERROR(dwError);

    up = retName;

    dwError = LWNetAllocateString(
                  Fqdn,
                  &token);
    BAIL_ON_LWNET_ERROR(dwError);

    p = strchr(token, '.');
    if (p)
    {
        *p++ = '\0';
        Fqdn = token;
    }

    /* Store length of NetBIOS name component before that name */
    *up++ = (UINT8) LWNB_NETBIOS_ENCNAME_LEN;
    LWNetNbStrToNbName(Fqdn, suffix, up);
    up += LWNB_NETBIOS_ENCNAME_LEN;

    /* Work through rest of Fqdn, replacing . with length of stuff before . */
    if (p)
    {
        p = strtok_r(p, ".", &tokenPtr);
    }
    while (p)
    {
        len = strlen(p);
        *up++ = (UINT8) len;
        strncat((char *) up, p, sizeof(CHAR)*len - (up-retName));
        up += len;
        p = strtok_r(NULL, ".", &tokenPtr);
    }
    *up++ = '\0';

    *retNbNameL2 = (UINT8 *) retName;
    *retNbNameL2Len = up - retName;

cleanup:
    LWNET_SAFE_FREE_MEMORY(token);
    return dwError;

error:
    LWNET_SAFE_FREE_MEMORY(retName);
    goto cleanup;
}
示例#3
0
static
DWORD
LWNetSrvPingCLdapProcess(
    IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext,
    IN DWORD dwDsFlags,
    IN LWNET_UNIX_MS_TIME_T StopTime,
    OUT PLWNET_DC_INFO* ppDcInfo,
    OUT PBOOLEAN pbFailedFindWritable
)
{
    DWORD dwError = 0;
    DWORD dwResultType = 0;
    LDAPMessage* pMessage = NULL;
    PBYTE pNetlogonAttributeValue = NULL;
    DWORD dwNetlogonAttributeSize = 0;
    PLWNET_DC_INFO pDcInfo = NULL;
    BOOLEAN bFailedFindWritable = FALSE;
    struct timeval timeout = {0};
    LDAP *ld = NULL;

    ld = LwLdapGetSession(pContext->hDirectory);

    dwResultType =  ldap_result(
                        ld,
                        pContext->msgid,
                        0,
                        &timeout,
                        &pMessage);
    if (dwResultType == 0)
    {
        // timed out
        goto error;
    }
    else if (dwResultType == -1)
    {
        // -1 = problem
        dwError = LDAP_NO_SUCH_OBJECT;
        LWNET_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
    }
    else
    {
        // returns result type
        if (dwResultType != LDAP_RES_SEARCH_ENTRY)
        {
            dwError = LDAP_NO_SUCH_OBJECT;
            LWNET_LOG_DEBUG("Caught incorrect result type on ldap search: %d", dwError);
        }
    }
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwLdapGetBytes(
                  pContext->hDirectory,
                  pMessage,
                  NETLOGON_LDAP_ATTRIBUTE_NAME,
                  &pNetlogonAttributeValue,
                  &dwNetlogonAttributeSize);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetBuildDCInfo(pNetlogonAttributeValue,
                               dwNetlogonAttributeSize,
                               &pDcInfo);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetAllocateString(pContext->pServerInfo->pszAddress, &pDcInfo->pszDomainControllerAddress);
    BAIL_ON_LWNET_ERROR(dwError);

    pDcInfo->dwPingTime = (DWORD)(StopTime - pContext->StartTime);
    if (StopTime < pContext->StartTime)
    {
        LWNET_LOG_ERROR("Stop time is earlier than start time");
    }

    if (!LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags))
    {
        dwError = LW_ERROR_NO_SUCH_OBJECT;

        if (LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags & ~DS_WRITABLE_REQUIRED))
        {
            // We found something, but it failed only because it did
            // not satisfy writability.
            bFailedFindWritable = TRUE;
        }
    }

error:
    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    LWNET_SAFE_FREE_MEMORY(pNetlogonAttributeValue);

    if (dwError)
    {
        LWNET_SAFE_FREE_DC_INFO(pDcInfo);

        LWNetSrvPingCLdapEnd(pContext);
    }

    *ppDcInfo = pDcInfo;
    *pbFailedFindWritable = bFailedFindWritable;

    return dwError;
}
示例#4
0
DWORD
ParseArgs(
    int    argc,
    char*  argv[],
    PSTR*  ppszTargetFQDN,
    PSTR*  ppszSiteName,
    PSTR*  ppszPrimaryDomain,
    PDWORD pdwFlags
    )
{
    typedef enum {
            PARSE_MODE_OPEN = 0,
            PARSE_MODE_SITENAME,
            PARSE_MODE_PREFERRED_DOMAIN,
            PARSE_MODE_OPTIONS
        } ParseMode;

    DWORD dwError = 0;
    int iArg = 1;
    PSTR pszArg = NULL;
    ParseMode parseMode = PARSE_MODE_OPEN;
    PSTR pszTargetFQDN = NULL;
    PSTR pszSiteName = NULL;
    PSTR pszPrimaryDomain = NULL;
    DWORD dwFlags = 0;

    do {
        pszArg = argv[iArg++];
        if (IsNullOrEmptyString(pszArg))
        {
            break;
        }
        
        switch (parseMode)
        {
            case PARSE_MODE_OPEN:
        
                if ((strcmp(pszArg, "--help") == 0) ||
                    (strcmp(pszArg, "-h") == 0))
                {
                    ShowUsage();
                    exit(0);
                }
                else
                {
                    dwError = LWNetAllocateString(pszArg, &pszTargetFQDN);
                    BAIL_ON_LWNET_ERROR(dwError);
        
                    parseMode = PARSE_MODE_OPTIONS;
                }
                break;

            case PARSE_MODE_OPTIONS:
                if(strcmp(pszArg, "--site") == 0)
                {
                    parseMode = PARSE_MODE_SITENAME;
                }
                else if(strcmp(pszArg, "--preferred-domain") == 0)
                {
                    parseMode = PARSE_MODE_PREFERRED_DOMAIN;
                }
                else if(strcmp(pszArg, "--force") == 0)
                {
                    dwError = AddFlag(DS_FORCE_REDISCOVERY, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--ds-required") == 0)
                {
                    dwError = AddFlag(DS_DIRECTORY_SERVICE_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--gc-required") == 0)
                {
                    dwError = AddFlag(DS_GC_SERVER_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--pdc-required") == 0)
                {
                    dwError = AddFlag(DS_PDC_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--background-only") == 0)
                {
                    dwError = AddFlag(DS_BACKGROUND_ONLY, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--kdc-required") == 0)
                {
                    dwError = AddFlag(DS_KDC_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--timeserv-required") == 0)
                {
                    dwError = AddFlag(DS_TIMESERV_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--writeable-required") == 0)
                {
                    dwError = AddFlag(DS_WRITABLE_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--good-timeserv-required") == 0)
                {
                    dwError = AddFlag(DS_GOOD_TIMESERV_REQUIRED, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else if(strcmp(pszArg, "--avoid-self") == 0)
                {
                    dwError = AddFlag(DS_AVOID_SELF, &dwFlags);
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                else 
                {
                    LWNET_LOG_ERROR("Invalid argument: %s", pszArg);
                    dwError = ERROR_INVALID_PARAMETER;
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                break;
            case PARSE_MODE_SITENAME:
                
                if(!IsNullOrEmptyString(pszSiteName))
                {
                    LWNET_LOG_ERROR("Invalid argument: %s", pszArg);
                    dwError = ERROR_INVALID_PARAMETER;
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                
                dwError = LWNetAllocateString(pszArg, &pszSiteName);
                BAIL_ON_LWNET_ERROR(dwError);
                
                parseMode = PARSE_MODE_OPTIONS;
                break;
            case PARSE_MODE_PREFERRED_DOMAIN:
                
                if(!IsNullOrEmptyString(pszPrimaryDomain))
                {
                    LWNET_LOG_ERROR("Invalid argument: %s", pszArg);
                    dwError = ERROR_INVALID_PARAMETER;
                    BAIL_ON_LWNET_ERROR(dwError);
                }
                
                dwError = LWNetAllocateString(pszArg, &pszPrimaryDomain);
                BAIL_ON_LWNET_ERROR(dwError);
                
                parseMode = PARSE_MODE_OPTIONS;
                break;
        }
        
    } while (iArg < argc);

    
    if(IsNullOrEmptyString(pszTargetFQDN))
    {
        ShowUsage();
        exit(0);
    }
    
error:
    if (dwError)
    {
        LWNET_SAFE_FREE_STRING(pszTargetFQDN);
        LWNET_SAFE_FREE_STRING(pszSiteName);
        LWNET_SAFE_FREE_STRING(pszPrimaryDomain);
        dwFlags = 0;
    }

    *ppszTargetFQDN = pszTargetFQDN;
    *ppszSiteName = pszSiteName;
    *ppszPrimaryDomain = pszPrimaryDomain;
    *pdwFlags = dwFlags;

    return dwError;
}
示例#5
0
DWORD
LWNetDnsGetAddressForServer(
    IN PDLINKEDLIST pAdditionalsList,
    IN PCSTR pszHostname,
    OUT PSTR* ppszAddress
    )
{
    DWORD dwError = 0;
    PSTR  pszAddress = NULL;
    PDLINKEDLIST pListMember = NULL;
    
    pListMember = pAdditionalsList;
    while (pListMember)
    {
        PDNS_RECORD pRecord = (PDNS_RECORD)pListMember->pItem;
        
        if ( (pRecord->wType == ns_t_a ) &&
             !strcasecmp( pRecord->pszName, pszHostname ) )
        {
            dwError = LwAllocateStringPrintf(&pszAddress, "%d.%d.%d.%d",
                                                pRecord->pData[0],
                                                pRecord->pData[1],
                                                pRecord->pData[2],
                                                pRecord->pData[3]);
            BAIL_ON_LWNET_ERROR(dwError);
            break;
        }

        pListMember = pListMember->pNext;
    }

    if (IsNullOrEmptyString(pszAddress))
    {
        struct hostent * host;

        LWNET_LOG_VERBOSE("Getting address for '%s'", pszHostname);

        host = gethostbyname(pszHostname);
        if (host  && host->h_name)
        {
            // ISSUE-2008/07/01-dalmeida -- Need to check that address type is IPv4
            dwError = LWNetAllocateString(inet_ntoa(*(struct in_addr*)(host->h_addr_list[0])),
                                          &pszAddress);
            BAIL_ON_LWNET_ERROR(dwError);
        }
    }

    if (IsNullOrEmptyString(pszAddress))
    {
        LWNET_LOG_WARNING("Unable to get IP address for '%s'", pszHostname);
        dwError = ERROR_NOT_FOUND;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    
error:
    if (dwError)
    {
        LWNET_SAFE_FREE_STRING(pszAddress);
    }

    *ppszAddress = pszAddress;

    return dwError;
}
示例#6
0
DWORD
LWNetDnsGetHostInfoEx(
    OUT OPTIONAL PSTR* ppszHostname,
    OUT OPTIONAL PSTR* ppszFqdn,
    OUT OPTIONAL PSTR* ppszDomain
    )
{
    DWORD dwError = 0;
    struct hostent * host = NULL;
    CHAR szBuffer[256] = { 0 };
    PSTR pszDot = NULL;
    PSTR pszFoundFqdn = NULL;
    PSTR pszFoundDomain = NULL;
    PSTR pszHostname = NULL;
    PSTR pszDomain = NULL;
    PSTR pszFqdn = NULL;

    if (!ppszHostname && !ppszFqdn && !ppszDomain)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    if (gethostname(szBuffer, sizeof(szBuffer)-1) != 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LWNET_ERROR(dwError);
    }

    /* Test to see if the name is still dotted. If so we will chop it down to
       just the hostname field. */
    pszDot = strchr(szBuffer, '.');
    if (pszDot)
    {
        pszDot[0] = '\0';
    }

    if (ppszHostname)
    {
        dwError = LWNetAllocateString(szBuffer, &pszHostname);
        BAIL_ON_LWNET_ERROR(dwError);
    }

    if (!ppszFqdn && !ppszDomain)
    {
        // done, so bail out
        dwError = 0;
        goto error;
    }

    host = gethostbyname(szBuffer);
    if ( !host )
    {
        dwError = LwMapHErrnoToLwError(h_errno);
        BAIL_ON_LWNET_ERROR(dwError);
    }

    //
    // We look for the first name that looks like an FQDN.  This is
    // the same heuristics used by other software such as Kerberos and
    // Samba.
    //
    pszDot = strchr(host->h_name, '.');
    if (pszDot)
    {
        pszFoundFqdn = host->h_name;
        pszFoundDomain = pszDot + 1;
    }
    else
    {
        int i;
        for (i = 0; host->h_aliases[i]; i++)
        {
            pszDot = strchr(host->h_aliases[i], '.');
            if (pszDot)
            {
                pszFoundFqdn = host->h_aliases[i];
                pszFoundDomain = pszDot + 1;
                break;
            }
        }
    }

    // If we still have nothing, just return the first name, but no Domain part.
    if (!pszFoundFqdn)
    {
        pszFoundFqdn = host->h_name;
    }
    if (pszFoundFqdn && !pszFoundFqdn[0])
    {
        pszFoundFqdn = NULL;
    }
    if (pszFoundDomain && !pszFoundDomain[0])
    {
        pszFoundDomain = NULL;
    }

    if (ppszFqdn)
    {
        if (pszFoundFqdn)
        {
            dwError = LWNetAllocateString(pszFoundFqdn, &pszFqdn);
            BAIL_ON_LWNET_ERROR(dwError);
        }
        else
        {
            dwError = ERROR_NOT_FOUND;
            BAIL_ON_LWNET_ERROR(dwError);
        }
    }

    if (ppszDomain)
    {
        if (pszFoundDomain)
        {
            dwError = LWNetAllocateString(pszFoundDomain, &pszDomain);
            BAIL_ON_LWNET_ERROR(dwError);
        }
        else
        {
            dwError = ERROR_NOT_FOUND;
            BAIL_ON_LWNET_ERROR(dwError);
        }
    }

error:
    if (dwError)
    {
        LWNET_SAFE_FREE_STRING(pszHostname);
        LWNET_SAFE_FREE_STRING(pszFqdn);
        LWNET_SAFE_FREE_STRING(pszDomain);
    }

    if (ppszHostname)
    {
        *ppszHostname = pszHostname;
    }

    if (ppszDomain)
    {
        *ppszDomain = pszDomain;
    }

    if (ppszFqdn)
    {
        *ppszFqdn = pszFqdn;
    }

    return dwError;
}
示例#7
0
DWORD
LWNetDnsGetNameServerList(
    OUT PSTR** pppszNameServerList,
    OUT PDWORD pdwNumServers
    )
// Call LWNET_SAFE_FREE_STRING_ARRAY on returned server list
{
    DWORD   dwError = 0;
    PSTR*   ppszNameServerList = NULL;
    DWORD   dwNumServers = 0;
    FILE*   fp = NULL;
    BOOLEAN bFileExists = FALSE;
    PCSTR   pszConfigFilePath = "/etc/resolv.conf";
    const   DWORD dwMaxLineLen = 1024;
    CHAR    szBuf[dwMaxLineLen + 1];
    regex_t rx;
    PDLINKEDLIST pNameServerList = NULL;
    PSTR    pszNameServer = NULL;
    
    memset(&rx, 0, sizeof(rx));
    
    if (regcomp(&rx, "^nameserver[[:space:]].*$", REG_EXTENDED) < 0) {
        dwError = ERROR_BAD_FORMAT;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    
    dwError = LwCheckFileTypeExists(
                    pszConfigFilePath,
                    LWFILE_REGULAR,
                    &bFileExists);
    BAIL_ON_LWNET_ERROR(dwError);
    
    if (!bFileExists) {
        *pppszNameServerList = NULL;
        *pdwNumServers = 0;
        goto cleanup;
    }
    
    if ((fp = fopen(pszConfigFilePath, "r")) == NULL) {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LWNET_ERROR(dwError);
    } 
    
    while (1)
    {
          if (fgets(szBuf, dwMaxLineLen, fp) == NULL) {
             if (!feof(fp)) {
                dwError = LwMapErrnoToLwError(errno);
                BAIL_ON_LWNET_ERROR(dwError);
             } else {
                break;
             }
          }
          
          LwStripWhitespace(szBuf, TRUE, TRUE);
          
          if (!LWNetDnsConfigLineIsComment(szBuf) &&
              !regexec(&rx, szBuf, (size_t)0, NULL, 0))
          {
             PSTR pszLocation = NULL;
             PCSTR pszSearchString = "nameserver";
             
             if ((pszLocation = strstr(szBuf, pszSearchString))) {
                pszLocation += strlen(pszSearchString);
                
                if (!IsNullOrEmptyString(pszLocation)) {
                   dwError = LWNetAllocateString(pszLocation, &pszNameServer);
                   BAIL_ON_LWNET_ERROR(dwError);
                }
                
                dwError = LWNetDLinkedListAppend(
                                    &pNameServerList,
                                    pszNameServer);
                BAIL_ON_LWNET_ERROR(dwError);
                
                pszNameServer = NULL;
                
                dwNumServers++;
             }
          }
    }
    
    if (dwNumServers)
    {
        PDLINKEDLIST pListMember = NULL;
        DWORD iMember = 0;

        dwError = LWNetAllocateMemory(dwNumServers * sizeof(PSTR), (PVOID*)&ppszNameServerList);
        BAIL_ON_LWNET_ERROR(dwError);

        pListMember = pNameServerList;
        while (pListMember)
        {
            ppszNameServerList[iMember++] = (PSTR)pListMember->pItem;
            pListMember->pItem = NULL;
            pListMember = pListMember->pNext;
        }
    }

    *pppszNameServerList = ppszNameServerList;
    *pdwNumServers = dwNumServers;

cleanup:

    regfree(&rx);
    
    LWNetDLinkedListFree(pNameServerList);
    
    LWNET_SAFE_FREE_STRING(pszNameServer);
    
    if (fp) {
        fclose(fp);
    }

    return dwError;
    
error:

    *pppszNameServerList = NULL;
    *pdwNumServers = 0;
    
    if (ppszNameServerList) {
       LWNetFreeStringArray(ppszNameServerList, dwNumServers);
    }

    goto cleanup;
}