Lister tous les membres d'un groupe (Mac OS X)

56

J'ai essayé de chercher sur Google mais je ne suis allé nulle part. Comment puis-je lister tous les membres d'un groupe appelé à mygrouppartir de la ligne de commande sous OS X?

$ dscl . list /groupsva me chercher tous les groupes ... mais comment puis-je voir les membres de chaque groupe?

Meltemi
la source

Réponses:

41

Vous pouvez utiliser:

dscacheutil -q group -a name admin

ou:

dscacheutil -q group -a name staff

etc.

duperuser
la source
Ceci est ma méthode préférée. Facile facile et précis. Merci!
TryTryAgain
C'est une excellente réponse car 90% des cas d'utilisation peuvent être résolus avec cela et non avec les scripts plus élaborés qui ont été postés en tant que réponses.
JakeGould
Ajoutez simplement cela comme alias dans votre fichier de démarrage du shell et vous pouvez en faire une commande d'un mot plus le nom du groupe.
Neil Monroe
Quand j'ai essayé "dscacheutil -q group", j'ai eu 2 paragraphes pour le groupe "admin". Les deux ont le même nom, gid, mais la liste des utilisateurs est différente. Une idée? Merci!
Golden Thumb
Pas nécessairement complet. dscacheutil -q group -a name adminm'a seulement donné 1 résultat, alors que le script shell de la réponse acceptée m'a donné 2 résultats.
Wisbucky
64

Il n'y a pas de commande standard qui répertorie tous les membres d'un groupe dans OS X, alors voici une fonction shell qui le fait:

members () { dscl . -list /Users | while read user; do printf "$user "; dsmemberutil checkmembership -U "$user" -G "$*"; done | grep "is a member" | cut -d " " -f 1; }; 

Copiez la ligne de commande ci-dessus sur le terminal, puis tapez (où groupe est le nom d'un groupe existant).members mygroup


Quelques explications pour ceux qui sont intéressés:

À ma connaissance, un utilisateur peut appartenir à un groupe sous OS X de cinq manières différentes. La commande ne permet pas de générer tous les membres, ni même aucun des membres de mon groupe, car leur appartenance provient également d'utilisateurs. ' ID de groupe principal , appartenance par UUID de l'utilisateur , héritage de l'appartenance d'un groupe à un autre et appartenances calculées par le système, telles que le groupe tout le monde .dscl . -read /Groups/mygroup GroupMembership

Donc, plutôt que d'essayer de garder une trace de tous ceux-ci, il semble être une meilleure idée de simplement vérifier l'adhésion de chaque utilisateur du système (en utilisant dsmemberutil ), et c'est ce que font la fonction shell et le script ci-dessous.


Ce script de membres est équivalent à la fonction shell, mais permet une gestion plus agréable des entrées non valides:

#!/bin/bash

# members -- list all members of a group
#
# SYNOPSIS
#   members groupname
#
# http://superuser.com/questions/279891/list-all-members-of-a-group-mac-os-x
#  by Arne
# Expected to work on Mac OS 10.5 and newer, tested on 10.6 and 10.7.
# It could be rewritten to work on 10.4 by using "dseditgroup -o checkmember"
# instead of "dsmemberutil checkmembership".
# By using dseditgroup, the script could also be extended to handle
# other Directory Service nodes than the default local node.
#

the_group="$1"
# Input check and usage
  if [[ $# != 1 || $1 == -* || $1 =~ [[:space:]] ]]; then
    echo "Usage: ${0##*/} groupname" >&2
    echo "Lists all members of the group." >&2
    exit 64
  elif (dsmemberutil checkmembership -U root -G "$the_group" 2>&1 \
    | grep "group .* cannot be found") >&2; then
    exit 1
  fi

# Check every user
exec dscl . -list /Users \
  | while read each_username
  do
    printf "$each_username "
    dsmemberutil checkmembership -U "$each_username" -G "$the_group"
  done \
    | grep "is a member" | cut -d " " -f 1

# eof

Informations complémentaires:

Les cinq façons d'être membre du groupe sont:

  1. PrimaryGroupID de l'utilisateur
  2. Listé dans le GroupMembership du groupe
  3. UUID listé dans le groupe de groupmembers
  4. Appartenance héritée du groupe X en tant que membre du groupe Y, répertorié dans les groupes imbriqués du groupe X
  5. Adhésion calculée par le système

Ceux-ci peuvent être explorés avec des commandes comme dscl . -read /Groups/somegroup

Exemple 4 : les membres du groupe Print Administrator __lpoperator_ héritent de l'appartenance au groupe d'opérateurs d'impression, tandis que les membres du groupe admin héritent de l'appartenance à ce groupe.

Exemple de 5 :

$ dscl . -read /Groups/netaccounts Comment
Comment:
 Group membership calculated by system
 Accounts from a remote directory server
$ 

VOIR AUSSI
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Arne Stenström
la source
7
C’est le genre de particularités que je pense à moi lorsque je dis aux gens que si OS X est principalement beau en surface, il contient quelques vilaines choses cachées sous les couvertures.
Stefan Schmidt
+1 : Cela fonctionne solidement. Merci.
Slipp D. Thompson
Ce sont les informations dont j'avais besoin pour comprendre comment me retirer du groupe d'administrateurs. Il s'avère que supprimer par nom d'utilisateur n'est pas suffisant, vous devez également supprimer l'UUID, voir github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Jens Timmerman
10

Remarque: C'était ma réponse initiale, écrite avant que je réalise que cette réponse donne toujours un résultat incomplet . (Par exemple, il ne trouve pas les membres du tout groupe!) J'ai donc écrit une meilleure réponse, qui comprend un script qui répertorie tous les membres d'un groupe dans OS X .


La propriété GroupMembership de mygroup peut être imprimée avec dscl comme ceci:

dscl . -read /Groups/mygroup GroupMembership

Mais cela ne garantit pas la sortie de tous (ou même de tous) des membres du groupe. Ce qui manque, ce sont les utilisateurs qui sont membres du groupe uniquement en l'ayant comme identifiant de groupe principal .

Un exemple courant de ceci dans OS X est les comptes de connexion classiques, qui ont un personnel (groupe 20) comme groupe principal, mais ne sont pas répertoriés dans la propriété GroupMembership du groupe de personnel .

Ces utilisateurs peuvent être trouvés en recherchant l' ID numérique du groupe principal (gid) comme dans cet exemple pour le groupe de personnel (gid 20):

dscl . -list /Users PrimaryGroupID | grep " 20$"

et le gid numérique (PrimaryGroupID) de mygroup est trouvé par:

dscl . -read /Groups/mygroup PrimaryGroupID
Arne Stenström
la source
7

Pour obtenir tous les groupes dans lesquels se trouve un utilisateur , vous pouvez utiliser les éléments suivants:

id -nG <username>

Exemple de sortie:

staff com.apple.sharepoint.group.1 everyone localaccounts _appserverusr admin _appserveradm _lpadmin _appstore _lpoperator _developer com.apple.access_ftp com.apple.access_screensharing com.apple.access_ssh

En utilisant la commande ci-dessus, il est possible d’obtenir tous les utilisateurs appartenant à un groupe :

OSX :

group=staff;
for i in $(dscl . list /users);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done

Unix :

group=sudo;
# This only outputs lines that match a username (from the start of line to a colon must not be a hash indicating a comment) 
for i in $(grep -oE "^[^#:]+" /etc/passwd);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done
Jay Brown
la source
C'est un bon conseil pour obtenir la liste des groupes auxquels un utilisateur appartient. Mais c'est l'inverse de ce que demandait le PO, à savoir une liste d'utilisateurs appartenant à un groupe.
Wisbucky
@ wisbucky c'est précisément ce que je recherchais. Je suis venu ici pour "lister tous les groupes d'un utilisateur". Je vais suggérer une modification pour clarifier cela
Isaac
4

dscl . -read /Groups/[groupname] | grep GroupMembership

ATTENTION: La commande ci-dessus n'affiche pas toujours la liste complète de TOUS les membres du groupe. Par exemple, pour le groupe "staff", vous n'obtenez que "root" en tant que membre du groupe, ce qui est incomplet. Pour le vérifier, utilisez l'une des commandes suivantes en tant qu'utilisateur par défaut (PAS "root"): id -GnOUgroups

En conséquence, tous les groupes dont l'utilisateur connecté par défaut est membre s'affichent. L'un d'entre eux devrait être "personnel". Ainsi, outre "root", il y a plus de membres du groupe "staff", qui ne sont pas listés par la commande dscl . -read /Groups/[groupname] | grep GroupMembership. Il en va de même pour la commande dscacheutil -q group -a name staffqui vous suggère également que seul "root" est un membre du groupe "staff", ce qui est évidemment incomplet.

Arne Stenström a déjà fourni la seule méthode fiable pour obtenir réellement TOUS les membres d’un groupe dans le terminal sous OSX. Ceci utilise sa fonction shell resp. son script shell. Les deux fonctionnent très bien!

William Jackson
la source
1

Commander

Semblable à la réponse de @ duperuser, ce qui suit n’imprimera que les utilisateurs du groupe adminavec des espaces entre eux:

dscacheutil -q group -a name admin | grep -e '^users:' | sed 's/users: //'

Sortie

L'exécution de la commande ci-dessus produira quelque chose comme ceci:

root your_username someone_else

Panne

Cette dscacheutilcommande permet d’interroger des informations sur différentes catégories du cache du service d’annuaire du système. L' -qoption vous permet de spécifier la catégorie que vous souhaitez interroger. Les catégories disponibles sont groupe, hôte, montage, protocole, rpc, service et utilisateur. Nous interrogeons ensuite cette catégorie en spécifiant une paire clé-valeur avec l' -aoption. Dans ce cas, nous voulons lister le groupe dont la clé est nameégale à la valeur admin. La dscacheutilcommande ci-dessus produit une sortie comme ceci:

name: admin
password: *
gid: 80
users: root yourusername

Ensuite, nous canalisons ce texte grepet choisissons la ligne contenant la chaîne users:au début. L' -eoption permet à grep de reconnaître les expressions régulières . Le ^caractère spécifie que nous voulons users:être au début de la ligne.

Cela nous donne

users: root yourusername

Enfin, nous passons cela dans sed et remplaçons le texte users:par la chaîne vide. Dans sed , la première lettre ssignifie substituer. /users: /Nous voulons remplacer le texte entre la première paire de barres obliques ( ) et la deuxième paire de barres obliques ( //) que nous voulons remplacer (dans ce cas, rien).

AmadeusDrZaius
la source
0

Voici une implémentation de ce problème dérivée d'une implémentation dans une discussion connexe . La routine est quelque peu générique, avec un point d’accès au service d’annuaire pour toute plate-forme / architecture spécifique, de sorte qu’elle peut être utilisée sans modification sur un réseau hétérogène. Nous avons installé un lien symbolique vers cet utilitaire nommé zed. Les autres origines de cette implémentation sont mentionnées dans la section d'attribution du script. Cet outil est conçu pour être exécuté au moins sur OSX, HP-UX, Linux et SunOS, mais n'a pas encore été mis à jour.testé sur SunOS et HP-UX. Le script a été testé autant que possible sur Ubuntu Linux 12.04 et Mavericks OSX 10.9.1. La sortie de ce script correspond à la sortie de la première implémentation de script shell pour ce problème et est donc considérée comme correcte.

#!/usr/bin/perl
#
# Lists members of all groups, or optionally just the group
# specified on the command line
#
# Date:         12/30/2013
# Author:       William H. McCloskey, Jr.
# Changes:      Added logic to detect host type & tailor subset of getent (OSX)
# Attribution:
#   The logic for this script was directly lifted from Zed Pobre's work.
#     See below for Copyright notice.
#   The idea to use dscl to emulate a subset of the now defunct getent on OSX
#     came from
#       http://zzamboni.org/\
#         brt/2008/01/21/how-to-emulate-unix-getent-with-macosxs-dscl/
#     with an example implementation lifted from
#       https://github.com/petere/getent-osx/blob/master/getent
#
# Copyright © 2010-2013 by Zed Pobre ([email protected] or [email protected])
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#

use strict; use warnings;

$ENV{"PATH"} = "/usr/bin:/bin";

# Only run on supported $os:
my $os;
($os)=(`uname -a` =~ /^([\w-]+)/);
unless ($os =~ /(HU-UX|SunOS|Linux|Darwin)/)
    {die "\$getent or equiv. does not exist:  Cannot run on $os\n";}

my $wantedgroup = shift;

my %groupmembers;

my @users;

# Acquire the list of @users based on what is available on this OS:
if ($os =~ /(SunOS|Linux|HP-UX)/) {
    #HP-UX & Solaris assumed to be like Linux; they have not been tested.
    my $usertext = `getent passwd`;
    @users = $usertext =~ /^([a-zA-Z0-9_-]+):/gm;
};
if ($os =~ /Darwin/) {
    @users = `dscl . -ls /Users`;
    chop @users;
}

# Now just do what Zed did - thanks Zed.
foreach my $userid (@users)
{
    my $usergrouptext = `id -Gn $userid`;
    my @grouplist = split(' ',$usergrouptext);

    foreach my $group (@grouplist)
    {
        $groupmembers{$group}->{$userid} = 1;
    }
}

if($wantedgroup)
{
    print_group_members($wantedgroup);
}
else
{
    foreach my $group (sort keys %groupmembers)
    {
        print "Group ",$group," has the following members:\n";
        print_group_members($group);
        print "\n";
    }
}

sub print_group_members
{
    my ($group) = @_;
    return unless $group;

    foreach my $member (sort keys %{$groupmembers{$group}})
    {
        print $member,"\n";
    }
}
Billy McCloskey
la source