This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Getting groups you belong to in perl


Andrey Repin wrote:
Greetings, Corinna Vinschen!

Don't know if this list is more appropriate than the Perl one but my
question is actually about porting a Perl script to Cygwin. I need to
check if the current user running the script belongs to a pre-defined group.
----
FWIW, I run a bash script at logon to populate a bash array
called $_GROUPS_.  I mention it, because you could do similarly
in perl if other methods don't work.



echo ${_GROUPS_[@]}
1053 517 512 545 11612288 518 519 513 544 520 201 260
echo -E ${!_GROUPS_[@]}
Bliss\Trusted Local Net Users Bliss\Cert Publishers Bliss\Domain Admins Users High Mandatory Level Bliss\Schema Admins Bliss\Enterprise Admins None Administrators Bliss\Group Policy Creator Owners lawgroup
--
It uses the cygwin 'id' program.

The array in the env is a convenience -- not a secure list.
Better to parse the output of id.

My bash routine is called via my 'bash_env' because bash currently
does not propagate arrays -- so the array is stored in a
string that gets re-expanded w/each call.

Theoretically the parsing of 'id' only happens at login.
I put them in an array, because if they are just in a 'string',
it's hard to tell the groups apart as they have spaces
in the names as well as spaces between the names...

---
The bash code ( I use to parse "id", FWIW):
----
# need to parse output of id, as it is only place we can notice groups
# with spaces in them! NOTE -- this must be done during 'bash_env' time

if [[ -z ${_GPSAFE_:-""} ]] 2>/dev/null ; then
  unset _GROUPS_
  typeset -Ax _GROUPS_

  function _idparse {
    # parse output of id:
    # uid=##(name) gid=##(name) groups=##(name)[,##(name)]...
    # Note, names may be 'absent' (in which case there are no parens).
    # grouplist is *comma* separated! -- but only on output of 'id';
    # I don't "idnames" can start with a number... (we'll assume not)
    # if group has no name, put it's number in as it's name
    # else you wouldn't see you are in those groups

    while read id ; do
      [[ $id =~ .?id= ]] && continue; #skip over uid/gid entries
      id="${id/\(/ }"
      id="${id/\)/}"
      # next line should work -- another bash bug...
      #[[ $id =~ ^[0-9]+$ ]] && id="$id $id"  #dup ID into missing name field
      gid="${id%% *}"
      name="${id#$gid}"
      name=${name##\ }
      [[ -z $name ]] && name="$gid"
      _GROUPS_[$name]="$gid"
    done  < <(id|sed -r '
      s/\) gid/\)\ngid/ ; s/\) groups/\)\ngroups/ ; s/\\/\\\\/g ;
      s/\),([0-9])/)\n\1/g ; s/\b([0-9]+),/\1\n/g ; s/groups=//')
  }
  _idparse

  unset _GPSAFE_ 2>/dev/null ||:
  typeset -xr _GPSAFE_=$(typeset -p _GROUPS_) ||: # save away for future
else
  eval  $_GPSAFE_
fi
-----------------------------------------------
Then I use it:

if [[ -n "${_GROUPS_[wheel]:-""}" ||
      -n "${_GROUPS_[root]:-""}" ||
      -n "${_GROUPS_[Administrators]:-""}" ]] ; then
  _path_prepend PATH /usr/local/sbin /usr/sbin /sbin
fi

----
It's a hack for convenience, though if the perl routines don't work,
it might be the quickest solution....

You could also look in the code of 'id' to see how it gets
the groups (since it works... ;-))....




--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]