]> granicus.if.org Git - shadow/blob - src/groups.c
[svn-upgrade] Integrating new upstream version, shadow (4.0.5)
[shadow] / src / groups.c
1 /*
2  * Copyright 1991 - 1993, Julianne Frances Haugh
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <config.h>
31
32 #include "rcsid.h"
33 RCSID (PKG_VER "$Id: groups.c,v 1.8 2002/01/05 15:41:43 kloczek Exp $")
34 #include <stdio.h>
35 #include <pwd.h>
36 #include <grp.h>
37 #include "prototypes.h"
38 #include "defines.h"
39 /* local function prototypes */
40 static void print_groups (const char *);
41
42 /*
43  * print_groups - print the groups which the named user is a member of
44  *
45  *      print_groups() scans the groups file for the list of groups which
46  *      the user is listed as being a member of.
47  */
48
49 static void print_groups (const char *member)
50 {
51         int groups = 0;
52         struct group *grp;
53         struct passwd *pwd;
54         int flag = 0;
55
56         setgrent ();
57
58         if ((pwd = getpwnam (member)) == 0) {
59                 fprintf (stderr, _("unknown user %s\n"), member);
60                 exit (1);
61         }
62         while ((grp = getgrent ())) {
63                 if (is_on_list (grp->gr_mem, member)) {
64                         if (groups++)
65                                 putchar (' ');
66
67                         printf ("%s", grp->gr_name);
68                         if (grp->gr_gid == pwd->pw_gid)
69                                 flag = 1;
70                 }
71         }
72         if (!flag && (grp = getgrgid (pwd->pw_gid))) {
73                 if (groups++)
74                         putchar (' ');
75
76                 printf ("%s", grp->gr_name);
77         }
78         if (groups)
79                 putchar ('\n');
80 }
81
82 /*
83  * groups - print out the groups a process is a member of
84  */
85
86 int main (int argc, char **argv)
87 {
88         long sys_ngroups;
89
90 #ifdef HAVE_GETGROUPS
91         int ngroups;
92         GETGROUPS_T *groups;
93         int pri_grp;
94         int i;
95         struct group *gr;
96 #else
97         char *logname;
98         char *getlogin ();
99 #endif
100
101         sys_ngroups = sysconf (_SC_NGROUPS_MAX);
102 #ifdef HAVE_GETGROUPS
103         groups = malloc (sys_ngroups * sizeof (GETGROUPS_T));
104 #endif
105         setlocale (LC_ALL, "");
106         bindtextdomain (PACKAGE, LOCALEDIR);
107         textdomain (PACKAGE);
108
109         if (argc == 1) {
110
111                 /*
112                  * Called with no arguments - give the group set for the
113                  * current user.
114                  */
115
116 #ifdef HAVE_GETGROUPS
117                 /*
118                  * This system supports concurrent group sets, so I can ask
119                  * the system to tell me which groups are currently set for
120                  * this process.
121                  */
122
123                 ngroups = getgroups (sys_ngroups, groups);
124                 if (ngroups < 0) {
125                         perror ("getgroups");
126                         exit (1);
127                 }
128
129                 /*
130                  * The groupset includes the primary group as well.
131                  */
132
133                 pri_grp = getegid ();
134                 for (i = 0; i < ngroups; i++)
135                         if (pri_grp == (int) groups[i])
136                                 break;
137
138                 if (i != ngroups)
139                         pri_grp = -1;
140
141                 /*
142                  * Print out the name of every group in the current group
143                  * set. Unknown groups are printed as their decimal group ID
144                  * values.
145                  */
146
147                 if (pri_grp != -1) {
148                         if ((gr = getgrgid (pri_grp)))
149                                 printf ("%s", gr->gr_name);
150                         else
151                                 printf ("%d", pri_grp);
152                 }
153
154                 for (i = 0; i < ngroups; i++) {
155                         if (i || pri_grp != -1)
156                                 putchar (' ');
157
158                         if ((gr = getgrgid (groups[i])))
159                                 printf ("%s", gr->gr_name);
160                         else
161                                 printf ("%ld", (long) groups[i]);
162                 }
163                 putchar ('\n');
164 #else
165                 /*
166                  * This system does not have the getgroups() system call, so
167                  * I must check the groups file directly.
168                  */
169
170                 if ((logname = getlogin ()))
171                         print_groups (logname);
172                 else
173                         exit (1);
174 #endif
175         } else {
176
177                 /*
178                  * The invoker wanted to know about some other user. Use
179                  * that name to look up the groups instead.
180                  */
181
182                 print_groups (argv[1]);
183         }
184         exit (0);
185 }