Registry und SecurityAccess -> RegSetKeySecurity



  • BCB3.0 / WinNT / InstallShield

    Hallo !!!

    Riesenproblem:

    Ich hab' eine Anwendung unter NT, die von jedem angemeldeten User benutzt werden können soll.

    Die Anwendung selbst liest und schreibt!!
    Variablen in der Registry. Mit InstallShield habe ich Schlüssel und Variablen während der Installation angelegt.

    Da die Installation jedoch vom Administrator ausgeführt wird, erhalten die erstellten Schlüssel und Variablen jedoch nur Schreibrechte durch den Admin.

    Wenn ein "normaler" User die Anwendung startet, kann die Anwendung zwar die Schlüssel lesen, aber nicht schreiben...

    Meine Überlegung: Nach der Installation muß die Anwendung einmal durch den Admin gestartet werden, die Anwendung überprüft auf User -> Admin und ändert dann die Zugriffsrechte für "meine" Schlüssel über
    RegSetKeySecurity der WinAPI.

    Jedoch ist das so kompliziert, daß ich mit der Windows-Doku nicht klarkomme. Hat jemand ein Beispiel für mich, wie man über RegSetKeySecurity einen Schlüssel so setzt, daß z.B. "Jeder" "Vollzugriff" hat ??

    Ich weiß, daß ist nicht sehr sicher, aber nur erstmal als "Allround"-Beispiel...

    Vielen Dank !!

    Smarti



  • Unter Windows NT (2000) entscheidet (gottseidank) der Administrator über die Privilegien einzelner Applikationen und NICHT irgendwelche Anwendungsprogramme!



  • Naja, Benno, wie man's nimmt.

    Im Prinzip geb' ich Dir ja recht, aber lies Dir bitte mein Problem nochmal durch:

    - Der Endkunde installiert (als Admin) meine Software mit InstallShield.

    - InstallShield legt die verwendeten Schlüssel an und belegt sie mit Standardwerten.

    - Der Kunde loggt sich als User_xx ein und startet die Anwendung. Als Admin eingeloggt bei der täglichen Arbeit, das kanns ja auch nicht sein.

    - Die Anwendung ist "so" modern, daß sie vom Anwender im Aussehen geändert werden kann. Diese Einstellung soll in der Registry (modern!) gespeichert werden, damit sie beim nächsten Start wiederverwendet wird.

    - Die Anwendung liest die letzte Einstellung (geht!), kann aber keine neue Speichern. weil der User keine Adminrechte hat.

    Mach ich einen Denkfehler ???

    Natürlich kann ich dem Admin mitteilen, daß er nach erfolgter Installation die Zugriffsrechte "dieses" Schlüssels so setzen soll, daß die Anwendung die Werte immer setzen kann, gleich welcher User angemeldet ist. Das hab' ich nun (aus der Not) auch so gehandhabt, ist aber auch nicht das Gelbe, wenn er noch manuell in der Registry rumfummeln muß. Warum kann das nicht das Installationsprogramm?
    Bzw. (wie ich oben geschrieben habe) meine Anwendung, aber nur 1x wenn sie vom Admin gestartet wird, nicht im späteren Betrieb.

    Danke schon mal für Deine Antwort...



  • Sag' das doch gleich 😉

    Vielleicht hilf dir ja diese Code (lernen kannst du von ihm allemal ...):

    /*++ 
    
    Managing user privileges can be achieved programmatically using the 
    following steps: 
    
    1. Open the policy on the target machine with LsaOpenPolicy(). To grant 
       privileges, open the policy with POLICY_CREATE_ACCOUNT and 
       POLICY_LOOKUP_NAMES access. To revoke privileges, open the policy with 
       POLICY_LOOKUP_NAMES access. 
    
    2. Obtain a SID (security identifier) representing the user/group of 
       interest. The LookupAccountName() and LsaLookupNames() APIs can obtain a 
       SID from an account name. 
    
    3. Call LsaAddAccountRights() to grant privileges to the user(s) 
       represented by the supplied SID. 
    
    4. Call LsaRemoveAccountRights() to revoke privileges from the user(s) 
       represented by the supplied SID. 
    
    5. Close the policy with LsaClose(). 
    
    To successfully grant and revoke privileges, the caller needs to be an 
    administrator on the target system. 
    
    The LSA API LsaEnumerateAccountRights() can be used to determine which 
    privileges have been granted to an account. 
    
    The LSA API LsaEnumerateAccountsWithUserRight() can be used to determine 
    which accounts have been granted a specified privilege. 
    
    Documentation and header files for these LSA APIs is provided in the 
    Windows 32 SDK in the MSTOOLS\SECURITY directory. 
    
    NOTE: These LSA APIs are currently implemented as Unicode only. 
    
    This sample will grant the privilege SeServiceLogonRight to the account 
    specified on argv[1]. 
    
    This sample is dependant on these import libs 
    
       advapi32.lib (for LsaXxx) 
       user32.lib (for wsprintf) 
    
    This sample will work properly compiled ANSI or Unicode. 
    
    You can use domain\account as argv[1]. For instance, mydomain\scott will 
    grant the privilege to the mydomain domain account scott. 
    
    The optional target machine is specified as argv[2], otherwise, the 
    account database is updated on the local machine. 
    
    The LSA APIs used by this sample are Unicode only. 
    
    Use LsaRemoveAccountRights() to remove account rights. 
    
    Scott Field (sfield)    12-Jul-95 
    
    --*/ 
    
    #ifndef UNICODE 
    #define UNICODE 
    #endif // UNICODE 
    
    #include  
    #include  
    
    #include "ntsecapi.h" 
    
    NTSTATUS 
    OpenPolicy( 
        LPWSTR ServerName,          // machine to open policy on (Unicode) 
        DWORD DesiredAccess,        // desired access to policy 
        PLSA_HANDLE PolicyHandle    // resultant policy handle 
        ); 
    
    BOOL 
    GetAccountSid( 
        LPTSTR SystemName,          // where to lookup account 
        LPTSTR AccountName,         // account of interest 
        PSID *Sid                   // resultant buffer containing SID 
        ); 
    
    NTSTATUS 
    SetPrivilegeOnAccount( 
        LSA_HANDLE PolicyHandle,    // open policy handle 
        PSID AccountSid,            // SID to grant privilege to 
        LPWSTR PrivilegeName,       // privilege to grant (Unicode) 
        BOOL bEnable                // enable or disable 
        ); 
    
    void 
    InitLsaString( 
        PLSA_UNICODE_STRING LsaString, // destination 
        LPWSTR String                  // source (Unicode) 
        ); 
    
    void 
    DisplayNtStatus( 
        LPSTR szAPI,                // pointer to function name (ANSI) 
        NTSTATUS Status             // NTSTATUS error value 
        ); 
    
    void 
    DisplayWinError( 
        LPSTR szAPI,                // pointer to function name (ANSI) 
        DWORD WinError              // DWORD WinError 
        ); 
    
    #define RTN_OK 0 
    #define RTN_USAGE 1 
    #define RTN_ERROR 13 
    
    // 
    // If you have the ddk, include ntstatus.h. 
    // 
    #ifndef STATUS_SUCCESS 
    #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L) 
    #endif 
    
    int _cdecl 
    main(int argc, char *argv[]) 
    { 
        LSA_HANDLE PolicyHandle; 
        WCHAR wComputerName[256]=L"";   // static machine name buffer 
        TCHAR AccountName[256];         // static account name buffer 
        PSID pSid; 
        NTSTATUS Status; 
        int iRetVal=RTN_ERROR;          // assume error from main 
    
        if(argc == 1) 
        { 
            fprintf(stderr,"Usage: %s  [TargetMachine]\n", 
                argv[0]); 
            return RTN_USAGE; 
        } 
    
        // 
        // Pick up account name on argv[1]. 
        // Assumes source is ANSI. Resultant string is ANSI or Unicode 
        // 
        wsprintf(AccountName, TEXT("%hS"), argv[1]); 
    
        // 
        // Pick up machine name on argv[2], if appropriate 
        // assumes source is ANSI. Resultant string is Unicode. 
        // 
        if(argc == 3) wsprintfW(wComputerName, L"%hS", argv[2]); 
    
        // 
        // Open the policy on the target machine. 
        // 
        if((Status=OpenPolicy( 
                    wComputerName,      // target machine 
                    POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, 
                    &PolicyHandle       // resultant policy handle 
                    )) != STATUS_SUCCESS) { 
            DisplayNtStatus("OpenPolicy", Status); 
            return RTN_ERROR; 
        } 
    
        // 
        // Obtain the SID of the user/group. 
        // Note that we could target a specific machine, but we don't. 
        // Specifying NULL for target machine searches for the SID in the 
        // following order: well-known, Built-in and local, primary domain, 
        // trusted domains. 
        // 
        if(GetAccountSid( 
                NULL,       // default lookup logic 
                AccountName,// account to obtain SID 
                &pSid       // buffer to allocate to contain resultant SID 
                )) { 
            // 
            // We only grant the privilege if we succeeded in obtaining the 
            // SID. We can actually add SIDs which cannot be looked up, but 
            // looking up the SID is a good sanity check which is suitable for 
            // most cases. 
    
            // 
            // Grant the SeServiceLogonRight to users represented by pSid. 
            // 
            if((Status=SetPrivilegeOnAccount( 
                        PolicyHandle,           // policy handle 
                        pSid,                   // SID to grant privilege 
                        L"SeServiceLogonRight", // Unicode privilege 
                        TRUE                    // enable the privilege 
                        )) == STATUS_SUCCESS) 
                iRetVal=RTN_OK; 
            else 
                DisplayNtStatus("AddUserRightToAccount", Status); 
        } 
        else { 
            // 
            // Error obtaining SID. 
            // 
            DisplayWinError("GetAccountSid", GetLastError()); 
        } 
    
        // 
        // Close the policy handle. 
        // 
        LsaClose(PolicyHandle); 
    
        // 
        // Free memory allocated for SID. 
        // 
        if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); 
    
        return iRetVal; 
    } 
    
    void 
    InitLsaString( 
        PLSA_UNICODE_STRING LsaString, 
        LPWSTR String 
        ) 
    { 
        DWORD StringLength; 
    
        if (String == NULL) { 
            LsaString->Buffer = NULL; 
            LsaString->Length = 0; 
            LsaString->MaximumLength = 0; 
            return; 
        } 
    
        StringLength = wcslen(String); 
        LsaString->Buffer = String; 
        LsaString->Length = (USHORT) StringLength * sizeof(WCHAR); 
        LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR); 
    } 
    
    NTSTATUS 
    OpenPolicy( 
        LPWSTR ServerName, 
        DWORD DesiredAccess, 
        PLSA_HANDLE PolicyHandle 
        ) 
    { 
        LSA_OBJECT_ATTRIBUTES ObjectAttributes; 
        LSA_UNICODE_STRING ServerString; 
        PLSA_UNICODE_STRING Server = NULL; 
    
        // 
        // Always initialize the object attributes to all zeroes. 
        // 
        ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); 
    
        if (ServerName != NULL) { 
            // 
            // Make a LSA_UNICODE_STRING out of the LPWSTR passed in 
            // 
            InitLsaString(&ServerString, ServerName); 
            Server = &ServerString; 
        } 
    
        // 
        // Attempt to open the policy. 
        // 
        return LsaOpenPolicy( 
                    Server, 
                    &ObjectAttributes, 
                    DesiredAccess, 
                    PolicyHandle 
                    ); 
    } 
    
    /*++ 
    This function attempts to obtain a SID representing the supplied 
    account on the supplied system. 
    
    If the function succeeds, the return value is TRUE. A buffer is 
    allocated which contains the SID representing the supplied account. 
    This buffer should be freed when it is no longer needed by calling 
    HeapFree(GetProcessHeap(), 0, buffer) 
    
    If the function fails, the return value is FALSE. Call GetLastError() 
    to obtain extended error information. 
    
    Scott Field (sfield)    12-Jul-95 
    --*/ 
    
    BOOL 
    GetAccountSid( 
        LPTSTR SystemName, 
        LPTSTR AccountName, 
        PSID *Sid 
        ) 
    { 
        LPTSTR ReferencedDomain=NULL; 
        DWORD cbSid=128;    // initial allocation attempt 
        DWORD cbReferencedDomain=16; // initial allocation size 
        SID_NAME_USE peUse; 
        BOOL bSuccess=FALSE; // assume this function will fail 
    
        __try { 
    
        // 
        // initial memory allocations 
        // 
        if((*Sid=HeapAlloc( 
                        GetProcessHeap(), 
                        0, 
                        cbSid 
                        )) == NULL) __leave; 
    
        if((ReferencedDomain=HeapAlloc( 
                        GetProcessHeap(), 
                        0, 
                        cbReferencedDomain 
                        )) == NULL) __leave; 
    
        // 
        // Obtain the SID of the specified account on the specified system. 
        // 
        while(!LookupAccountName( 
                        SystemName,         // machine to lookup account on 
                        AccountName,        // account to lookup 
                        *Sid,               // SID of interest 
                        &cbSid,             // size of SID 
                        ReferencedDomain,   // domain account was found on 
                        &cbReferencedDomain, 
                        &peUse 
                        )) { 
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { 
                // 
                // reallocate memory 
                // 
                if((*Sid=HeapReAlloc( 
                            GetProcessHeap(), 
                            0, 
                            *Sid, 
                            cbSid 
                            )) == NULL) __leave; 
    
                if((ReferencedDomain=HeapReAlloc( 
                            GetProcessHeap(), 
                            0, 
                            ReferencedDomain, 
                            cbReferencedDomain 
                            )) == NULL) __leave; 
            } 
            else __leave; 
        } 
    
        // 
        // Indicate success. 
        // 
        bSuccess=TRUE; 
    
        } // finally 
        __finally { 
    
        // 
        // Cleanup and indicate failure, if appropriate. 
        // 
    
        HeapFree(GetProcessHeap(), 0, ReferencedDomain); 
    
        if(!bSuccess) { 
            if(*Sid != NULL) { 
                HeapFree(GetProcessHeap(), 0, *Sid); 
                *Sid = NULL; 
            } 
        } 
    
        } // finally 
    
        return bSuccess; 
    } 
    
    NTSTATUS 
    SetPrivilegeOnAccount( 
        LSA_HANDLE PolicyHandle,    // open policy handle 
        PSID AccountSid,            // SID to grant privilege to 
        LPWSTR PrivilegeName,       // privilege to grant (Unicode) 
        BOOL bEnable                // enable or disable 
        ) 
    { 
        LSA_UNICODE_STRING PrivilegeString; 
    
        // 
        // Create a LSA_UNICODE_STRING for the privilege name. 
        // 
        InitLsaString(&PrivilegeString, PrivilegeName); 
    
        // 
        // grant or revoke the privilege, accordingly 
        // 
        if(bEnable) { 
            return LsaAddAccountRights( 
                    PolicyHandle,       // open policy handle 
                    AccountSid,         // target SID 
                    &PrivilegeString,   // privileges 
                    1                   // privilege count 
                    ); 
        } 
        else { 
            return LsaRemoveAccountRights( 
                    PolicyHandle,       // open policy handle 
                    AccountSid,         // target SID 
                    FALSE,              // do not disable all rights 
                    &PrivilegeString,   // privileges 
                    1                   // privilege count 
                    ); 
        } 
    } 
    
    void 
    DisplayNtStatus( 
        LPSTR szAPI, 
        NTSTATUS Status 
        ) 
    { 
        // 
        // Convert the NTSTATUS to Winerror. Then call DisplayWinError(). 
        // 
        DisplayWinError(szAPI, LsaNtStatusToWinError(Status)); 
    } 
    
    void 
    DisplayWinError( 
        LPSTR szAPI, 
        DWORD WinError 
        ) 
    { 
        LPSTR MessageBuffer; 
        DWORD dwBufferLength; 
    
        // 
        // TODO: Get this fprintf out of here! 
        // 
        fprintf(stderr,"%s error!\n", szAPI); 
    
        if(dwBufferLength=FormatMessageA( 
                            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                            FORMAT_MESSAGE_FROM_SYSTEM, 
                            NULL, 
                            WinError, 
                            GetUserDefaultLangID(), 
                            (LPSTR) &MessageBuffer, 
                            0, 
                            NULL 
                            )) 
        { 
            DWORD dwBytesWritten; // unused 
    
            // 
            // Output message string on stderr. 
            // 
            WriteFile( 
                GetStdHandle(STD_ERROR_HANDLE), 
                MessageBuffer, 
                dwBufferLength, 
                &dwBytesWritten, 
                NULL 
                ); 
    
            // 
            // Free the buffer allocated by the system. 
            // 
            LocalFree(MessageBuffer); 
        } 
    }
    

    [ 09.07.2001: Beitrag editiert von: class CMarcus ]



  • Na also,

    ich bin doch kein Virenprogrammierer, der das System lahmlegen will... nein!!

    Danke für die Hilfe, falls es eine ist... ich muß mich erstmal durchbeißen.

    Smarti


Anmelden zum Antworten