Domanda

Sto facendo una piccola applicazione che elimina i file di log. Sto usando un'istanza NSTask che corre rm e SRM (rm sicuro) per eliminare i file.

Voglio essere in grado di eliminare i file in:

  • / Library / Logs
  • ~ / Library / Logs

Il problema è che l'account utente non dispone delle autorizzazioni necessarie per accedere ad alcuni file nella cartella libreria di sistema, come ad esempio Adobe log sottocartella e altri. Ad esempio, solo il "sistema" utente (gruppo?) Ha r / w autorizzazioni per la cartella Adobe log e il suo contenuto, e l'utente corrente non ha nemmeno una voce nei permessi mostrati nella finestra Ottieni informazioni per la cartella .

Quello che voglio essere in grado di fare esattamente:

  1. Ottenere i privilegi di amministratore.
  2. Conservare la password nel portachiavi così l'applicazione non ha bisogno di infastidire l'utente ogni volta (è la memorizzazione della password una cattiva idea? E 'possibile?)
  3. Elimina un file di qualunque siano i permessi dei file possono essere.

io sto usando NSTask perché offre le notifiche per il completamento delle attività, ottenendo in uscita il testo dal compito stesso, ecc avrei bisogno di utilizzare qualcosa di diverso? Se sì, come ho potuto replicare il completamento delle notifiche e file di output maniglia di NSTask durante l'esecuzione di rm e SRM con privilegi di amministratore?

Sto cercando il modo più sicuro per gestire la situazione. vale a dire che non voglio la mia domanda per diventare una porta per gli attacchi di privilegi.

Ho guardato il servizi di autorizzazione Guida di programmazione, ma non sono sicuro quale caso si adatta. In un primo momento ho pensato che AuthorizationExecuteWithPrivileges sarebbe stata una buona idea, ma dopo aver letto più su questo argomento sembra che questo metodo non è raccomandato per motivi di sicurezza.

Una risposta dettagliata sarebbe molto benvenuto. Sono sicuro che alcuni di voi già doveva fare qualcosa di simile e avere un po 'di codice e conoscenze da condividere.

Grazie in anticipo!

Aggiornamento:

Sono ora in grado di rendere la finestra di autenticazione pop-up e ottenere i privilegi, in questo modo:

OSStatus status;
AuthorizationRef authRef;
    status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);

AuthorizationRights authRights;
AuthorizationItem authItems[1];

authItems[0].name = kAuthorizationRightExecute;

authRights.count = sizeof(authItems) / sizeof(authItems[0]);
authRights.items = authItems;

AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;

status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, authFlags, NULL);

Dagli sguardi di esso, sembra che il metodo "Factored Applicazione" sembra la più appropriata. Il fatto è che, per me, rm sembra già come uno strumento di supporto esterna . Io non sono sicuro di ottenere l'alternativa setuid suggerito nella documentazione. Potrei impostare il bit setuid su rm ed eseguirlo con il metodo NSTask ho già implementato? Ciò significherebbe che non avrei bisogno di creare il mio strumento di aiuto. Qualcuno potrebbe approfondire questo argomento?

Ho anche guardato il BetterAuthorizationSample che viene proposto come un più sicuro e recente alternativa al metodo bit setuid, ma trovò terribilmente complessa per come il comportamento semplice. Eventuali suggerimenti?

Grazie in anticipo per qualsiasi aiuto!

È stato utile?

Soluzione

ho avuto questo mal di testa a pochi mesi fa. Stavo cercando di ottenere uno script di shell in esecuzione con privilegi di amministratore che arresto il mio computer in un determinato momento. Sento il tuo dolore.

ho usato il BetterAuthorizationSample che è stato un vero incubo a guadare attraverso. Ma ho preso la via più pragmatica - Non mi preoccupai cercando di capire tutto quello che stava succedendo, ho appena preso il coraggio del codice

.

E non mi ci vuole molto tempo per farlo fare quello che volevo. Non ricordo esattamente che cosa ho modificato, ma hai la possibilità di controllare il mio codice:

http://github.com/johngallagher/TurnItOff

Spero che questo aiuta sulla vostra ricerca per un'applicazione sicura!

Altri suggerimenti

Forse un po 'tardi, ma questo potrebbe essere utile in futuro per altre persone. La maggior parte del codice è da questa persona .

In sostanza, ha molto a che fare con l'autorizzazione su Mac. Si può leggere di più su questo qui e qui .

Il codice, che utilizza lo strumento rm:

+ (BOOL)removeFileWithElevatedPrivilegesFromLocation:(NSString *)location
{
    // Create authorization reference
    OSStatus status;
    AuthorizationRef authorizationRef;

    // AuthorizationCreate and pass NULL as the initial
    // AuthorizationRights set so that the AuthorizationRef gets created
    // successfully, and then later call AuthorizationCopyRights to
    // determine or extend the allowable rights.
    // http://developer.apple.com/qa/qa2001/qa1172.html
    status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Error Creating Initial Authorization: %d", status);
        return NO;
    }

    // kAuthorizationRightExecute == "system.privilege.admin"
    AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
    AuthorizationRights rights = {1, &right};
    AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
                                kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;

    // Call AuthorizationCopyRights to determine or extend the allowable rights.
    status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Copy Rights Unsuccessful: %d", status);
        return NO;
    }

    // use rm tool with -rf
    char *tool = "/bin/rm";
    char *args[] = {"-rf", (char *)[location UTF8String], NULL};
    FILE *pipe = NULL;

    status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Error: %d", status);
        return NO;
    }

    // The only way to guarantee that a credential acquired when you
    // request a right is not shared with other authorization instances is
    // to destroy the credential.  To do so, call the AuthorizationFree
    // function with the flag kAuthorizationFlagDestroyRights.
    // http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
    status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
    return YES;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top