View source with formatted comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2011-2013, VU University Amsterdam
    7    All rights reserved.
    8
    9    Redistribution and use in source and binary forms, with or without
   10    modification, are permitted provided that the following conditions
   11    are met:
   12
   13    1. Redistributions of source code must retain the above copyright
   14       notice, this list of conditions and the following disclaimer.
   15
   16    2. Redistributions in binary form must reproduce the above copyright
   17       notice, this list of conditions and the following disclaimer in
   18       the documentation and/or other materials provided with the
   19       distribution.
   20
   21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32    POSSIBILITY OF SUCH DAMAGE.
   33*/
   34
   35:- module(uid,
   36          [ getuid/1,                   % -UID
   37            getgid/1,                   % -GID
   38            geteuid/1,                  % -UID
   39            getegid/1,                  % -GID
   40            getgroups/1,                % -GIDs
   41            user_info/2,                % +User, -UserInfo
   42            group_info/2,               % +Group, -GroupInfo
   43            user_data/3,                % +Field, +UserInfo, -Value
   44            group_data/3,               % +Field, +GroupInfo, -Value
   45            setuid/1,                   % +UID
   46            setgid/1,                   % +GID
   47            seteuid/1,                  % +UID
   48            setegid/1,                  % +GID
   49
   50            set_user_and_group/1,       % +User
   51            set_user_and_group/2        % +User, +Group
   52          ]).   53
   54:- use_foreign_library(foreign(uid)).   55
   56:- if(predicate_property(initgroups(_,_), defined)).   57:- export(initgroups/2).   58:- else.   59initgroups(_,_).
   60:- endif.   61
   62:- if(predicate_property(setgroups(_), defined)).   63:- export(setgroups/1).   64:- endif.   65
   66/** <module> User and group management on Unix systems
   67
   68This module provides and interface  to   user  and  group information on
   69Posix systems. In addition, it allows for   changing user and group ids.
   70When changing user and group settings for   the calling process, bear in
   71mind that:
   72
   73  - Changing user and groups of the calling process requires permission.
   74  - The functions setgroups() and initgroups() are not part of the
   75    POSIX standard and therefore the derived predicates may not be
   76    present.
   77
   78@see    Please check the documentation of your OS for details on the
   79        semantics of this predicates.
   80*/
   81
   82%!  getuid(-UID) is det.
   83%
   84%   UID is the real user ID of the calling process.
   85
   86%!  getgid(-GID) is det.
   87%
   88%   GID is the real group ID of the calling process.
   89
   90%!  geteuid(-UID) is det.
   91%
   92%   UID is the effective user ID of the calling process.
   93
   94%!  getegid(-GID) is det.
   95%
   96%   GID is the effective group ID of the calling process.
   97
   98%!  getgroups(-GroupsIDs:list(integer)) is det.
   99%
  100%   GroupsIDs is the set of supplementary   group IDs of the calling
  101%   process.  Note  that  these   are    numeric   identifiers.  Use
  102%   group_info/2  to  obtain  details   on    the   returned   group
  103%   identifiers.
  104
  105%!  user_info(+User, -UserData) is det.
  106%
  107%   UserData represent the passwd  information   for  User.  User is
  108%   either a numeric UID or a   user name. The predicate user_data/3
  109%   can be used to extract information from UserData.
  110
  111%!  user_data(?Field, ?UserData, ?Value)
  112%
  113%   Value is the value for Field in UserData.  Defined fields are:
  114%
  115%     * name
  116%     Name of the user
  117%     * password
  118%     Password hash of the user (or =x= if this is not accessible)
  119%     * uid
  120%     Numeric user id of the user
  121%     * gid
  122%     Numeric primary group id of the user
  123%     * comment
  124%     The _gecos_ field
  125%     * home
  126%     Home directory of the user
  127%     * shell
  128%     Default (login) shell of the user.
  129
  130user_data(name,     user_info(Nam, _, _, _, _, _, _), Nam).
  131user_data(password, user_info(_, PWD, _, _, _, _, _), PWD).
  132user_data(uid,      user_info(_, _, UID, _, _, _, _), UID).
  133user_data(gid,      user_info(_, _, _, GID, _, _, _), GID).
  134user_data(comment,  user_info(_, _, _, _, GEC, _, _), GEC).
  135user_data(home,     user_info(_, _, _, _, _, HOM, _), HOM).
  136user_data(shell,    user_info(_, _, _, _, _, _, SHE), SHE).
  137
  138%!  group_info(+Group, -GroupData) is det.
  139%
  140%   GroupData represent the group information   for  Group. Group is
  141%   either a numeric GID or a group name. The predicate group_data/3
  142%   can be used to extract information from GroupData.
  143
  144%!  group_data(?Field, ?GroupData, ?Value)
  145%
  146%   Value is the value for Field  GroupData.  Defined fields are:
  147%
  148%     * name
  149%     Name of the user
  150%     * password
  151%     Password hash of the user (or =x= if this is not accessible)
  152%     * gid
  153%     Numeric group id of the group
  154%     * members
  155%     List of user-names that are member of this group.
  156
  157group_data(name,     group_info(Nam, _, _, _), Nam).
  158group_data(password, group_info(_, PWD, _, _), PWD).
  159group_data(gid,      group_info(_, _, GID, _), GID).
  160group_data(members,  group_info(_, _, _, MBR), MBR).
  161
  162                 /*******************************
  163                 *             SETTING          *
  164                 *******************************/
  165
  166%!  setuid(+UID)
  167%
  168%   Set the user id of the calling process.
  169
  170%!  seteuid(+UID)
  171%
  172%   Set the effective user id of the calling process.
  173
  174
  175%!  setgid(+GID)
  176%
  177%   Set the group id of the calling process.
  178
  179%!  setegid(+GID)
  180%
  181%   Set the effective group id of the calling process.
  182
  183%!  initgroups(+User, +Group) is det.
  184%
  185%   Initialise the group access list of   the calling process to the
  186%   registered groups for User and the   group Group. This predicate
  187%   is only available if the underlying OS provides it.
  188
  189%!  setgroups(+Groups:list(integer)) is det.
  190%
  191%   Set the group access list of the caling process to the indicated
  192%   groups. This predicate is only available   if  the underlying OS
  193%   provides it.
  194
  195%!  set_user_and_group(+User) is det.
  196%!  set_user_and_group(+User, +Group) is det.
  197%
  198%   Set the UID and GID to the User. User  is either a UID or a user
  199%   name. If Group is not specified, the   primary  group of User is
  200%   used. If initgroups/2 is available,   the resulting group access
  201%   list of the calling process consists   of  the registered groups
  202%   for User and the specified Group.
  203
  204set_user_and_group(User) :-
  205    user_info(User, Data),
  206    user_data(uid, Data, UID),
  207    user_data(gid, Data, GID),
  208    initgroups(User, GID),
  209    setgid(GID),
  210    setuid(UID).
  211
  212set_user_and_group(User, Group) :-
  213    user_info(User, Data),
  214    group_info(Group, GData),
  215    user_data(uid, Data, UID),
  216    user_data(gid, Data, UGID),
  217    group_data(gid, GData, GID),
  218    initgroups(User, UGID),
  219    setgid(GID),
  220    setuid(UID)