예제 #1
0
int
LeaveMain(
    int argc,
    const char** argv
    )
{
    DWORD dwError = 0;
    LEAVE_ARGS args = { 0 };

    dwError = ParseLeaveArgs(argc, argv, &args);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = DoLeaveDomain(
                    args.pszDomain,
                    args.pszUsername,
                    args.pszPassword,
                    args.JoinFlags);
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        PrintError(dwError);
    }

    FreeLeaveArgsContents(&args);

    return dwError ? 1 : 0;
}
예제 #2
0
static
DWORD
DoLeaveDomain(
    IN PCSTR pszDomain,
    IN OPTIONAL PCSTR pszUsername,
    IN OPTIONAL PCSTR pszPassword,
    IN LSA_NET_JOIN_FLAGS JoinFlags
    )
{
    HANDLE hLsa = NULL;
    DWORD dwError = 0;
    PCSTR pszUseDomain = IsSetFlag(JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE) ? pszDomain : NULL;

    assert(pszDomain);

    printf("Leaving AD Domain: %s\n", pszDomain);

    dwError = LsaOpenServer(&hLsa);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LsaAdLeaveDomain2(hLsa, pszUsername, pszPassword, pszUseDomain, JoinFlags);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    printf("SUCCESS\n");

cleanup:
    if (hLsa)
    {
        LsaCloseServer(hLsa);
    }

    return dwError;
}
예제 #3
0
int
JoinMain(
    int argc,
    const char** argv
    )
{
    DWORD dwError = 0;
    JOIN_ARGS args = { 0 };

    dwError = ParseJoinArgs(argc, argv, &args);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = DoJoinDomain(
                    args.pszDomain,
                    args.pszUsername,
                    args.pszPassword,
                    args.pszMachineName,
                    args.pszDnsSuffix,
                    args.pszOu,
                    args.pszOsName,
                    args.pszOsVersion,
                    args.pszOsServicePack,
                    args.JoinFlags);
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        PrintError(dwError);
    }

    FreeJoinArgsContents(&args);

    return dwError ? 1 : 0;
}
static
DWORD
LwpsConvertTimeWindowsToUnix(
    IN LONG64 WindowsTime,
    OUT time_t* pUnixTime
    )
{
    DWORD dwError = 0;
    LONG64 unixTime = 0;

    if (WindowsTime < 0)
    {
        dwError = ERROR_INVALID_PARAMETER;
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

    unixTime = WindowsTime/10000000LL - 11644473600LL;

    // Ensure the range is within time_t.
    if (unixTime != (time_t) unixTime)
    {
        dwError = ERROR_ARITHMETIC_OVERFLOW;
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

cleanup:
    if (dwError)
    {
        unixTime = 0;
    }

    *pUnixTime = (time_t) unixTime;

    return 0;
}
예제 #5
0
static
DWORD
LsaPstorepGetPluginNames(
    OUT PSTR** Names,
    OUT PDWORD Count
    )
{
    DWORD dwError = 0;
    HANDLE registryConnection = NULL;
    HKEY keyHandle = NULL;
    PSTR* loadOrder = NULL;
    DWORD loadOrderCount = 0;

    dwError = LwRegOpenServer(&registryConnection);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LwRegOpenKeyExA(
                    registryConnection,
                    NULL,
                    LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                    0,
                    GENERIC_READ,
                    &keyHandle);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        dwError = 0;
        GOTO_CLEANUP();
    }
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LsaPstorepRegGetMultiStringA(
                    registryConnection,
                    keyHandle,
                    LSA_PSTORE_REG_VALUE_NAME_PLUGINS_LOAD_ORDER,
                    &loadOrder,
                    &loadOrderCount);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        dwError = 0;
    }
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        LSA_PSTORE_FREE_STRING_ARRAY_A(&loadOrder, &loadOrderCount);
    }

    *Names = loadOrder;
    *Count = loadOrderCount;

    return dwError;
}
예제 #6
0
static
DWORD
GetCurrentDomain(
    OUT PSTR* ppszDnsDomainName
    )
{
    DWORD dwError = 0;
    HANDLE hLsa = NULL;
    PLSA_MACHINE_ACCOUNT_INFO_A pAccountInfo = NULL;
    PSTR pszDnsDomainName = NULL;

    dwError = LsaOpenServer(&hLsa);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LsaAdGetMachineAccountInfo(hLsa, NULL, &pAccountInfo);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LwAllocateString(
                    pAccountInfo->DnsDomainName,
                    &pszDnsDomainName);
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_MEMORY(pszDnsDomainName);
    }

    if (hLsa)
    {
        LsaCloseServer(hLsa);
    }

    if (pAccountInfo)
    {
        LsaAdFreeMachineAccountInfo(pAccountInfo);
    }

    *ppszDnsDomainName = pszDnsDomainName;

    return dwError;
}
예제 #7
0
static
DWORD
CleanupUsername(
    IN PCSTR pszDomain,
    IN OUT PSTR* ppszUsername
    )
{
    DWORD dwError = 0;
    PSTR pszOldUsername = *ppszUsername;
    PSTR pszNewUsername = NULL;

    // Fix up username and prompt for password, if needed.
    if (pszOldUsername)
    {
        PSTR at = NULL;

        if (strchr(pszOldUsername, '\\'))
        {
            fprintf(stderr,
                    "The USERNAME (%s) is not allowed to contain a backslash.\n",
                    pszOldUsername);
            exit(1);
        }

        at = strchr(pszOldUsername, '@');
        if (at)
        {
            LwStrToUpper(at);
        }
        else
        {
            dwError = LwAllocateStringPrintf(
                            &pszNewUsername,
                            "%s@%s",
                            pszOldUsername,
                            pszDomain);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
    }

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_MEMORY(pszNewUsername);
    }

    if (pszNewUsername)
    {
        LW_SAFE_FREE_MEMORY(*ppszUsername);
        *ppszUsername = pszNewUsername;
    }

    return dwError;
}
static
DWORD
LwpsConvertTimeUnixToWindows(
    IN time_t UnixTime,
    OUT PLONG64 pWindowsTime
    )
{
    DWORD dwError = 0;
    LONG64 windowsTime = 0;

#if SIZEOF_TIME_T > 4
    if ((LONG64) UnixTime < - 11644473600LL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }
#endif

    windowsTime = (LONG64) UnixTime + 11644473600LL;
    if (windowsTime < 0)
    {
        dwError = ERROR_ARITHMETIC_OVERFLOW;
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }
    windowsTime *= 10000000LL;
    if (windowsTime < 0)
    {
        dwError = ERROR_ARITHMETIC_OVERFLOW;
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

cleanup:
    if (dwError)
    {
        windowsTime = 0;
    }

    *pWindowsTime = windowsTime;

    return 0;
}
예제 #9
0
static
DWORD
GetArgumentValue(
    IN PCSTR pszProgramName,
    IN SHOW_USAGE_CALLBACK ShowUsageError,
    IN OUT PLW_ARGV_CURSOR pCursor,
    IN OPTIONAL PCSTR pszArgumentName,
    OUT PSTR* ppszArgumentValue
    )
{
    DWORD dwError = 0;
    PSTR result = NULL;
    PCSTR value = LwArgvCursorPop(pCursor);

    if (!value)
    {
        if (pszArgumentName)
        {
            fprintf(stderr, "Missing %s argument.\n", pszArgumentName);
            ShowUsageError(pszProgramName);
        }
    }
    else
    {
        dwError = LwAllocateString(value, &result);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_MEMORY(result);
    }

    *ppszArgumentValue = result;

    return dwError;
}
예제 #10
0
static
DWORD
GetHostname(
    OUT PSTR* ppszHostname
    )
{
    DWORD dwError = 0;
    CHAR buffer[1024] = { 0 };
    PSTR dot = NULL;
    PSTR pszHostname = NULL;

    if (gethostname(buffer, sizeof(buffer) - 1) == -1)
    {
        dwError = LwErrnoToWin32Error(errno);
        assert(dwError);
        GOTO_CLEANUP();
    }

    dot = strchr(buffer, '.');
    if (dot)
    {
        *dot = 0;
    }

    dwError = LwAllocateString(buffer, &pszHostname);
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_STRING(pszHostname);
    }

    *ppszHostname = pszHostname;

    return dwError;
}
예제 #11
0
static
DWORD
ParseLeaveArgs(
    IN int argc,
    IN const char *argv[],
    OUT PLEAVE_ARGS pArgs
    )
{
    DWORD dwError = 0;
    PCSTR programName = NULL;
    PCSTR option = NULL;
    LW_ARGV_CURSOR cursor;
    SHOW_USAGE_CALLBACK ShowUsageHelp = ShowLeaveUsageHelp;
    SHOW_USAGE_CALLBACK ShowUsageError = ShowLeaveUsageError;

    memset(pArgs, 0, sizeof(*pArgs));

    LwArgvCursorInit(&cursor, argc, argv);
    programName = LwArgvCursorPop(&cursor);

    // Process options:
    for (;;)
    {
        option = PopNextOption(&cursor);
        if (!option)
        {
            break;
        }
        else if (IsHelpOption(option))
        {
            ShowUsageHelp(programName);
        }
        else if (!strcmp("--multiple", option))
        {
            SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE);

            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszDomain);
            GOTO_CLEANUP_ON_WINERROR(dwError);

            LwStrToUpper(pArgs->pszDomain);
        }
        else
        {
            fprintf(stderr, "Unrecognized option: %s\n", option);
            ShowUsageError(programName);
        }
    }

    // Optional arguments
    dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL,
                               &pArgs->pszUsername);
    assert(!dwError);
    dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL,
                               &pArgs->pszPassword);
    assert(!dwError);

    if (LwArgvCursorRemaining(&cursor))
    {
        fprintf(stderr, "Too many arguments.\n");
        ShowUsageError(programName);
    }

    // Initialize implicit domain argument.
    if (!pArgs->pszDomain)
    {
        dwError = GetCurrentDomain(&pArgs->pszDomain);
        if (NERR_SetupNotJoined == dwError)
        {
            fprintf(stderr, "The computer is not joined to a domain.\n");
            exit(1);
        }
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

    // If USERNAME was specified, clean it up and get password
    // as needed.
    if (pArgs->pszUsername)
    {
        dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername);
        GOTO_CLEANUP_ON_WINERROR(dwError);

        if (!pArgs->pszPassword)
        {
            dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
    }

cleanup:
    if (dwError)
    {
        FreeLeaveArgsContents(pArgs);
    }

    return dwError;
}
예제 #12
0
static
DWORD
ParseJoinArgs(
    IN int argc,
    IN const char *argv[],
    OUT PJOIN_ARGS pArgs
    )
{
    DWORD dwError = 0;
    PCSTR programName = NULL;
    PCSTR option = NULL;
    LW_ARGV_CURSOR cursor;
    SHOW_USAGE_CALLBACK ShowUsageHelp = ShowJoinUsageHelp;
    SHOW_USAGE_CALLBACK ShowUsageError = ShowJoinUsageError;

    memset(pArgs, 0, sizeof(*pArgs));

    LwArgvCursorInit(&cursor, argc, argv);
    programName = LwArgvCursorPop(&cursor);

    // Process options:
    for (;;)
    {
        option = PopNextOption(&cursor);
        if (!option)
        {
            break;
        }
        else if (IsHelpOption(option))
        {
            ShowUsageHelp(programName);
        }
        else if (!strcmp("--name", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszMachineName);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--dnssuffix", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszDnsSuffix);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--ou", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszOu);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--osname", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszOsName);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--osversion", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszOsVersion);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--osservicepack", option))
        {
            dwError = GetOptionValue(programName, ShowUsageError, &cursor, option,
                                     &pArgs->pszOsServicePack);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else if (!strcmp("--notimesync", option))
        {
            SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC);
        }
        else if (!strcmp("--multiple", option))
        {
            SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC);
            SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE);
        }
        else
        {
            fprintf(stderr, "Unrecognized option: %s\n", option);
            ShowUsageError(programName);
        }
    }

    // Process arguments:
    dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "DOMAIN",
                               &pArgs->pszDomain);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    LwStrToUpper(pArgs->pszDomain);

    dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "USERNAME",
                               &pArgs->pszUsername);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    // Optional argument
    dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL,
                               &pArgs->pszPassword);
    assert(!dwError);

    if (LwArgvCursorRemaining(&cursor))
    {
        fprintf(stderr, "Too many arguments.\n");
        ShowUsageError(programName);
    }

    // Initialize missing options as needed

    if (!pArgs->pszDnsSuffix)
    {
        dwError = LwAllocateString(pArgs->pszDomain, &pArgs->pszDnsSuffix);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }
    LwStrToLower(pArgs->pszDnsSuffix);

    if (!pArgs->pszMachineName)
    {
        dwError = GetHostname(&pArgs->pszMachineName);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

    if (!pArgs->pszOsName ||
        !pArgs->pszOsVersion ||
        !pArgs->pszOsServicePack)
    {
        dwError = GetOsInfo(
                        pArgs->pszOsName ? NULL : &pArgs->pszOsName,
                        pArgs->pszOsVersion ? NULL : &pArgs->pszOsVersion,
                        pArgs->pszOsServicePack ? NULL : &pArgs->pszOsServicePack);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

    dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    if (!pArgs->pszPassword)
    {
        dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

cleanup:
    if (dwError)
    {
        FreeJoinArgsContents(pArgs);
    }

    return dwError;
}
예제 #13
0
static
DWORD
GetPassword(
    OUT PSTR* ppszPassword
    )
{
    DWORD dwError = 0;
    CHAR buffer[129] = { 0 };
    int i = 0;
    BOOLEAN needReset = FALSE;
    struct termios oldAttributes;
    struct termios newAttributes;
    PSTR pszPassword = NULL;

    if (tcgetattr(0, &oldAttributes) == -1)
    {
        dwError = LwErrnoToWin32Error(errno);
        assert(dwError);
        GOTO_CLEANUP();
    }

    newAttributes = oldAttributes;
    ClearFlag(newAttributes.c_lflag, ECHO);

    if (tcsetattr(0, TCSANOW, &newAttributes) == -1)
    {
        dwError = LwErrnoToWin32Error(errno);
        assert(dwError);
        GOTO_CLEANUP();
    }

    needReset = TRUE;

    for (i = 0; i < (sizeof(buffer) - 1); i++)
    {
        if (read(0, &buffer[i], 1))
        {
            if (buffer[i] == '\n')
            {
                buffer[i] = 0;
                break;
            }
        }
        else
        {
            dwError = LwErrnoToWin32Error(errno);
            assert(dwError);
            GOTO_CLEANUP();
        }
    }

    if (i == (sizeof(buffer) - 1))
    {
        dwError = LwErrnoToWin32Error(ENOBUFS);
        assert(dwError);
        GOTO_CLEANUP();
    }

    dwError = LwAllocateString(buffer, &pszPassword);
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_MEMORY(pszPassword);
    }

    if (needReset)
    {
        if (tcsetattr(0, TCSANOW, &oldAttributes) == -1)
        {
            assert(0);
        }
    }

    *ppszPassword = pszPassword;

    return dwError;
}
예제 #14
0
static
DWORD
DoJoinDomain(
    IN PCSTR pszDomain,
    IN PCSTR pszUsername,
    IN PCSTR pszPassword,
    IN PCSTR pszMachineName,
    IN PCSTR pszDnsSuffix,
    IN OPTIONAL PCSTR pszOu,
    IN PCSTR pszOsName,
    IN PCSTR pszOsVersion,
    IN PCSTR pszOsServicePack,
    IN LSA_NET_JOIN_FLAGS JoinFlags
    )
{
    DWORD dwError = 0;
    HANDLE hLsa = NULL;
    PSTR pszCurrentDomain = NULL;

    assert(pszDomain);
    assert(pszUsername);
    assert(pszPassword);
    assert(pszMachineName);
    assert(pszDnsSuffix);
    assert(pszOsName);
    assert(pszOsVersion);
    assert(pszOsServicePack);

    printf("Joining to AD Domain: %s\n"
           "With Computer DNS Name: %s.%s\n\n",
           pszDomain,
           pszMachineName,
           pszDnsSuffix);

    dwError = LsaOpenServer(&hLsa);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LsaAdJoinDomain(
                    hLsa,
                    pszMachineName,
                    pszDnsSuffix,
                    pszDomain,
                    pszOu,
                    pszUsername,
                    pszPassword,
                    pszOsName,
                    pszOsVersion,
                    pszOsServicePack,
                    JoinFlags);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    printf("SUCCESS!\n");

    dwError = GetCurrentDomain(&pszCurrentDomain);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    printf("Your computer is now joined to '%s'\n", pszCurrentDomain);

cleanup:
    if (hLsa)
    {
        LsaCloseServer(hLsa);
    }

    LW_SAFE_FREE_MEMORY(pszCurrentDomain);

    return dwError;
}
예제 #15
0
static
DWORD
GetOsInfo(
    OUT OPTIONAL PSTR* ppszOsName,
    OUT OPTIONAL PSTR* ppszOsVersion,
    OUT OPTIONAL PSTR* ppszOsServicePack
    )
{
    DWORD dwError = 0;
    struct utsname utsBuffer = { { 0 } };
    PSTR pszOsName = NULL;
    PSTR pszOsVersion = NULL;
    PSTR pszOsServicePack = NULL;

    if (uname(&utsBuffer) == -1)
    {
        dwError = LwErrnoToWin32Error(errno);
        assert(dwError);
        GOTO_CLEANUP();
    }

    if (ppszOsName)
    {
        dwError = LwAllocateString(utsBuffer.sysname, &pszOsName);
        GOTO_CLEANUP_ON_WINERROR(dwError);
    }

    if (ppszOsVersion)
    {
        if (!strcmp(utsBuffer.sysname, "AIX"))
        {
            dwError = LwAllocateStringPrintf(
                            &pszOsVersion,
                            "%s.%s",
                            utsBuffer.version, utsBuffer.release);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else
        {
            dwError = LwAllocateString(utsBuffer.release, &pszOsVersion);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
    }

    if (ppszOsServicePack)
    {
        if (!strcmp(utsBuffer.sysname, "AIX"))
        {
            dwError = LwAllocateString("", &pszOsServicePack);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
        else
        {
            dwError = LwAllocateString(utsBuffer.version, &pszOsServicePack);
            GOTO_CLEANUP_ON_WINERROR(dwError);
        }
    }

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_STRING(pszOsName);
        LW_SAFE_FREE_STRING(pszOsVersion);
        LW_SAFE_FREE_STRING(pszOsServicePack);
    }

    if (ppszOsName)
    {
        *ppszOsName = pszOsName;
    }
    if (ppszOsVersion)
    {
        *ppszOsVersion = pszOsVersion;
    }
    if (ppszOsServicePack)
    {
        *ppszOsServicePack = pszOsServicePack;
    }

    return dwError;
}