Exemplo n.º 1
0
static
DWORD
UmnSrvUpdateUser(
    PLW_EVENTLOG_CONNECTION pEventlog,
    HANDLE hReg,
    HKEY hUsers,
    long long PreviousRun,
    long long Now,
    struct passwd *pUser
    )
{
    DWORD dwError = 0;
    HKEY hKey = NULL;
    USER_MONITOR_PASSWD old = { 0 };
    DWORD dwNow = Now;
    PSTR pEncodedUser = NULL;

    dwError = LwURLEncodeString(
                    pUser->pw_name,
                    &pEncodedUser);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = RegOpenKeyExA(
                    hReg,
                    hUsers,
                    pEncodedUser,
                    0,
                    KEY_ALL_ACCESS,
                    &hKey);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        UMN_LOG_INFO("Adding user '%s' (uid %d)",
                        pUser->pw_name, pUser->pw_uid);

        dwError = RegCreateKeyExA(
                        hReg,
                        hUsers,
                        pEncodedUser,
                        0,
                        NULL,
                        0,
                        KEY_ALL_ACCESS,
                        NULL,
                        &hKey,
                        NULL);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteUserValues(
                        hReg,
                        hKey,
                        pUser);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteUserEvent(
                        pEventlog,
                        PreviousRun,
                        NULL,
                        Now,
                        pUser);
        BAIL_ON_UMN_ERROR(dwError);
    }
    else
    {
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvReadUser(
                        "Users",
                        pEncodedUser,
                        &old);
        BAIL_ON_UMN_ERROR(dwError);

        if (strcmp(pUser->pw_name, old.pw_name) ||
                strcmp(pUser->pw_passwd, old.pw_passwd) ||
                pUser->pw_uid != old.pw_uid ||
                pUser->pw_gid != old.pw_gid ||
                strcmp(pUser->pw_gecos, old.pw_gecos) ||
                strcmp(pUser->pw_dir, old.pw_dir) ||
                strcmp(pUser->pw_shell, old.pw_shell))
        {
            UMN_LOG_INFO("User '%s' (uid %d) changed",
                            pUser->pw_name, pUser->pw_uid);
            dwError = UmnSrvWriteUserValues(
                            hReg,
                            hKey,
                            pUser);
            BAIL_ON_UMN_ERROR(dwError);

            dwError = UmnSrvWriteUserEvent(
                            pEventlog,
                            PreviousRun,
                            &old,
                            Now,
                            pUser);
            BAIL_ON_UMN_ERROR(dwError);
        }
    }

    dwError = RegSetValueExA(
                    hReg,
                    hKey,
                    "LastUpdated",
                    0,
                    REG_DWORD,
                    (PBYTE)&dwNow,
                    sizeof(dwNow));
    BAIL_ON_UMN_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_STRING(pEncodedUser);
    UmnSrvFreeUserContents(&old);
    if (hKey)
    {
        RegCloseKey(
                hReg,
                hKey);
    }
    return dwError;
    
error:
    goto cleanup;
}
Exemplo n.º 2
0
DWORD
UmnSrvUpdateADGroupMember(
    PLW_EVENTLOG_CONNECTION pEventlog,
    HANDLE hReg,
    HKEY hGroups,
    long long PreviousRun,
    long long Now,
    PLSA_SECURITY_OBJECT pGroup,
    PCSTR pMember
    )
{
    DWORD dwError = 0;
    HKEY hKey = NULL;
    HKEY hMembers = NULL;
    DWORD dwNow = Now;
    PSTR pEncodedMember = NULL;
    PSTR pKeyName = NULL;
    PSTR pEncodedGroup = NULL;
    PSTR pMembersKeyName = NULL;

    dwError = LwURLEncodeString(
                    pMember,
                    &pEncodedMember);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = LwURLEncodeString(
                    pGroup->groupInfo.pszUnixName,
                    &pEncodedGroup);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = LwAllocateStringPrintf(
                    &pKeyName,
                    "%s\\Members\\%s",
                    pEncodedGroup,
                    pEncodedMember);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = RegOpenKeyExA(
                    hReg,
                    hGroups,
                    pKeyName,
                    0,
                    KEY_ALL_ACCESS,
                    &hKey);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        UMN_LOG_INFO("Adding user member '%s' to group '%s' (gid %d)",
                        pMember, pGroup->groupInfo.pszUnixName, pGroup->groupInfo.gid);

        dwError = LwAllocateStringPrintf(
                        &pMembersKeyName,
                        "%s\\Members",
                        pEncodedGroup);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = RegOpenKeyExA(
                        hReg,
                        hGroups,
                        pMembersKeyName,
                        0,
                        KEY_ALL_ACCESS,
                        &hMembers);
        if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
        {
            // Previous run left registry in inconsistent state
            dwError = RegCreateKeyExA(
                            hReg,
                            hGroups,
                            pMembersKeyName,
                            0,
                            NULL,
                            0,
                            KEY_ALL_ACCESS,
                            NULL,
                            &hMembers,
                            NULL);
            BAIL_ON_UMN_ERROR(dwError);
        }
        BAIL_ON_UMN_ERROR(dwError);

        dwError = RegCreateKeyExA(
                        hReg,
                        hMembers,
                        pEncodedMember,
                        0,
                        NULL,
                        0,
                        KEY_ALL_ACCESS,
                        NULL,
                        &hKey,
                        NULL);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteGroupMemberEvent(
                        pEventlog,
                        Now,
                        "AD Groups",
                        PreviousRun,
                        TRUE, //Add member
                        FALSE, //Not gid change
                        pMember,
                        pGroup->groupInfo.gid,
                        pGroup->groupInfo.pszUnixName);
        BAIL_ON_UMN_ERROR(dwError);
    }

    dwError = RegSetValueExA(
                    hReg,
                    hKey,
                    "LastUpdated",
                    0,
                    REG_DWORD,
                    (PBYTE)&dwNow,
                    sizeof(dwNow));
    BAIL_ON_UMN_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_STRING(pEncodedGroup);
    LW_SAFE_FREE_STRING(pKeyName);
    LW_SAFE_FREE_STRING(pMembersKeyName);
    LW_SAFE_FREE_STRING(pEncodedMember);
    if (hKey)
    {
        RegCloseKey(
                hReg,
                hKey);
    }
    if (hMembers)
    {
        RegCloseKey(
                hReg,
                hMembers);
    }
    return dwError;
    
error:
    goto cleanup;
}
Exemplo n.º 3
0
static
DWORD
UmnSrvUpdateADUser(
    PLW_EVENTLOG_CONNECTION pEventlog,
    HANDLE hReg,
    HKEY hUsers,
    long long PreviousRun,
    long long Now,
    PLSA_SECURITY_OBJECT pUser
    )
{
    DWORD dwError = 0;
    HKEY hKey = NULL;
    USER_MONITOR_PASSWD old = { 0 };
    DWORD dwNow = Now;
    PSTR pEncodedUser = NULL;

    dwError = LwURLEncodeString(
                    pUser->userInfo.pszUnixName,
                    &pEncodedUser);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = RegOpenKeyExA(
                    hReg,
                    hUsers,
                    pEncodedUser,
                    0,
                    KEY_ALL_ACCESS,
                    &hKey);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        UMN_LOG_INFO("Adding user '%s' (uid %d)",
                        pUser->userInfo.pszUnixName, pUser->userInfo.uid);

        dwError = RegCreateKeyExA(
                        hReg,
                        hUsers,
                        pEncodedUser,
                        0,
                        NULL,
                        0,
                        KEY_ALL_ACCESS,
                        NULL,
                        &hKey,
                        NULL);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADUserValues(
                        hReg,
                        hKey,
                        pUser);
        if (dwError == ERROR_NO_UNICODE_TRANSLATION)
        {
            UMN_LOG_ERROR("Ignoring user with URL encoding %s because one of their fields has no UCS-2 representation", pEncodedUser);

            // Delete the key so it does not show up with blank values next
            // time.
            dwError = RegCloseKey(
                    hReg,
                    hKey);
            BAIL_ON_UMN_ERROR(dwError);
            hKey = NULL;

            dwError = RegDeleteKeyA(
                            hReg,
                            hUsers,
                            pEncodedUser);
            BAIL_ON_UMN_ERROR(dwError);

            dwError = ERROR_NO_UNICODE_TRANSLATION;
            BAIL_ON_UMN_ERROR(dwError);
        }
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADUserEvent(
                        pEventlog,
                        PreviousRun,
                        NULL,
                        Now,
                        pUser);
        BAIL_ON_UMN_ERROR(dwError);
    }
    else
    {
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvReadUser(
                        "AD Users",
                        pEncodedUser,
                        &old);
        BAIL_ON_UMN_ERROR(dwError);

        if (strcmp((pUser->userInfo.pszPasswd ?
                        pUser->userInfo.pszPasswd : "x"),
                    old.pw_passwd) ||
                pUser->userInfo.uid != old.pw_uid ||
                pUser->userInfo.gid != old.pw_gid ||
                !UmnSrvStringsEqual(pUser->userInfo.pszGecos, old.pw_gecos) ||
                !UmnSrvStringsEqual(pUser->userInfo.pszHomedir, old.pw_dir) ||
                !UmnSrvStringsEqual(pUser->userInfo.pszShell, old.pw_shell) ||
                !UmnSrvStringsEqual(pUser->userInfo.pszDisplayName,
                    old.pDisplayName))
        {
            UMN_LOG_INFO("User '%s' (uid %d) changed",
                            pUser->userInfo.pszUnixName, pUser->userInfo.uid);
            dwError = UmnSrvWriteADUserValues(
                            hReg,
                            hKey,
                            pUser);
            BAIL_ON_UMN_ERROR(dwError);

            dwError = UmnSrvWriteADUserEvent(
                            pEventlog,
                            PreviousRun,
                            &old,
                            Now,
                            pUser);
            BAIL_ON_UMN_ERROR(dwError);
        }
    }

    dwError = RegSetValueExA(
                    hReg,
                    hKey,
                    "LastUpdated",
                    0,
                    REG_DWORD,
                    (PBYTE)&dwNow,
                    sizeof(dwNow));
    BAIL_ON_UMN_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_STRING(pEncodedUser);
    UmnSrvFreeUserContents(&old);
    if (hKey)
    {
        RegCloseKey(
                hReg,
                hKey);
    }
    return dwError;
    
error:
    goto cleanup;
}
Exemplo n.º 4
0
DWORD
UmnSrvUpdateADGroup(
    PLW_EVENTLOG_CONNECTION pEventlog,
    HANDLE hReg,
    HKEY hGroups,
    long long PreviousRun,
    long long Now,
    PLSA_SECURITY_OBJECT pGroup
    )
{
    DWORD dwError = 0;
    HKEY hKey = NULL;
    HKEY hMembers = NULL;
    USER_MONITOR_GROUP old = { 0 };
    DWORD dwNow = Now;
    old.gr_gid = -1;
    PSTR pEncodedGroup = NULL;

    dwError = LwURLEncodeString(
                    pGroup->groupInfo.pszUnixName,
                    &pEncodedGroup);
    BAIL_ON_UMN_ERROR(dwError);

    dwError = RegOpenKeyExA(
                    hReg,
                    hGroups,
                    pEncodedGroup,
                    0,
                    KEY_ALL_ACCESS,
                    &hKey);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        dwError = 0;
    }
    else
    {
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvReadGroup(
                        "AD Groups",
                        pEncodedGroup,
                        &old);
        BAIL_ON_UMN_ERROR(dwError);
    }
    // Check if the key does not exist yet, or it was not fully populated.
    if (old.LastUpdated == 0)
    {
        UMN_LOG_INFO("Adding group '%s' (gid %d)",
                        pGroup->groupInfo.pszUnixName, pGroup->groupInfo.gid);

        dwError = RegCreateKeyExA(
                        hReg,
                        hGroups,
                        pEncodedGroup,
                        0,
                        NULL,
                        0,
                        KEY_ALL_ACCESS,
                        NULL,
                        &hKey,
                        NULL);
        if (dwError == LWREG_ERROR_KEYNAME_EXIST)
        {
            // The key exists, but the values were not fully populated on a
            // previous run because the user monitor crashed or was killed. Use
            // the existing key and let the values get overwritten.
            dwError = 0;
        }
        BAIL_ON_UMN_ERROR(dwError);

        dwError = RegCreateKeyExA(
                        hReg,
                        hKey,
                        "Members",
                        0,
                        NULL,
                        0,
                        KEY_ALL_ACCESS,
                        NULL,
                        &hMembers,
                        NULL);
        if (dwError == LWREG_ERROR_KEYNAME_EXIST)
        {
            // The key exists, but the values were not fully populated on a
            // previous run because the user monitor crashed or was killed. Use
            // the existing key and let the values get overwritten.
            dwError = 0;
        }
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADGroupValues(
                        hReg,
                        hKey,
                        pGroup);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADGroupEvent(
                        pEventlog,
                        PreviousRun,
                        NULL,
                        Now,
                        pGroup);
        BAIL_ON_UMN_ERROR(dwError);
    }
    else if (strcmp(pGroup->groupInfo.pszUnixName, old.gr_name))
    {
        // The group's name changed. This is too drastic of a change for a
        // change event. File a deletion and addition event.
        dwError = UmnSrvWriteADGroupEvent(
                        pEventlog,
                        PreviousRun,
                        &old,
                        Now,
                        NULL);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADGroupEvent(
                        pEventlog,
                        PreviousRun,
                        NULL,
                        Now,
                        pGroup);
        BAIL_ON_UMN_ERROR(dwError);
    }
    else if (strcmp((pGroup->groupInfo.pszPasswd ?
                    pGroup->groupInfo.pszPasswd : "x"),
                old.gr_passwd) ||
            pGroup->groupInfo.gid != old.gr_gid)
    {
        UMN_LOG_INFO("Group '%s' (gid %d) changed",
                        pGroup->groupInfo.pszUnixName,
                        pGroup->groupInfo.gid);

        dwError = UmnSrvWriteADGroupValues(
                        hReg,
                        hKey,
                        pGroup);
        BAIL_ON_UMN_ERROR(dwError);

        dwError = UmnSrvWriteADGroupEvent(
                        pEventlog,
                        PreviousRun,
                        &old,
                        Now,
                        pGroup);
        BAIL_ON_UMN_ERROR(dwError);

        if (pGroup->groupInfo.gid != old.gr_gid)
        {
            // Send out membership deletion events for all members. They
            // will get readded through normal processing with the new gid
            dwError = RegOpenKeyExA(
                            hReg,
                            hKey,
                            "Members",
                            0,
                            KEY_ALL_ACCESS,
                            &hMembers);
            BAIL_ON_UMN_ERROR(dwError);

            dwError = UmnSrvFindDeletedGroupMembers(
                            pEventlog,
                            hReg,
                            "AD Groups",
                            hMembers,
                            Now,
                            TRUE,
                            old.gr_gid,
                            old.gr_name);
            BAIL_ON_UMN_ERROR(dwError);
        }
    }

    dwError = RegSetValueExA(
                    hReg,
                    hKey,
                    "LastUpdated",
                    0,
                    REG_DWORD,
                    (PBYTE)&dwNow,
                    sizeof(dwNow));
    BAIL_ON_UMN_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_STRING(pEncodedGroup);
    UmnSrvFreeGroupContents(&old);
    if (hKey)
    {
        RegCloseKey(
                hReg,
                hKey);
    }
    if (hMembers)
    {
        RegCloseKey(
                hReg,
                hMembers);
    }
    return dwError;
    
error:
    goto cleanup;
}