Initial commit for Tizen
[profile/extras/shadow-utils.git] / contrib / groupmems.shar
1 #!/bin/sh
2 # This is a shell archive (produced by GNU sharutils 4.2.1).
3 # To extract the files from this archive, save it to some FILE, remove
4 # everything before the `!/bin/sh' line above, then type `sh FILE'.
5 #
6 # Made on 2000-05-25 14:41 CDT by <gk4@gnu.austin.ibm.com>.
7 # Source directory was `/home/gk4/src/groupmem'.
8 #
9 # Existing files will *not* be overwritten unless `-c' is specified.
10 #
11 # This shar contains:
12 # length mode       name
13 # ------ ---------- ------------------------------------------
14 #   1960 -rw-r--r-- Makefile
15 #   6348 -rw-r--r-- groupmems.c
16 #   3372 -rw------- groupmems.8
17 #
18 save_IFS="${IFS}"
19 IFS="${IFS}:"
20 gettext_dir=FAILED
21 locale_dir=FAILED
22 first_param="$1"
23 for dir in $PATH
24 do
25   if test "$gettext_dir" = FAILED && test -f $dir/gettext \
26      && ($dir/gettext --version >/dev/null 2>&1)
27   then
28     set `$dir/gettext --version 2>&1`
29     if test "$3" = GNU
30     then
31       gettext_dir=$dir
32     fi
33   fi
34   if test "$locale_dir" = FAILED && test -f $dir/shar \
35      && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
36   then
37     locale_dir=`$dir/shar --print-text-domain-dir`
38   fi
39 done
40 IFS="$save_IFS"
41 if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
42 then
43   echo=echo
44 else
45   TEXTDOMAINDIR=$locale_dir
46   export TEXTDOMAINDIR
47   TEXTDOMAIN=sharutils
48   export TEXTDOMAIN
49   echo="$gettext_dir/gettext -s"
50 fi
51 if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
52   shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
53 elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
54   shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
55 elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
56   shar_touch='touch -am $3$4$5$6$2 "$8"'
57 else
58   shar_touch=:
59   echo
60   $echo 'WARNING: not restoring timestamps.  Consider getting and'
61   $echo "installing GNU \`touch', distributed in GNU File Utilities..."
62   echo
63 fi
64 rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
65 #
66 if mkdir _sh10937; then
67   $echo 'x -' 'creating lock directory'
68 else
69   $echo 'failed to create lock directory'
70   exit 1
71 fi
72 # ============= Makefile ==============
73 if test -f 'Makefile' && test "$first_param" != -c; then
74   $echo 'x -' SKIPPING 'Makefile' '(file already exists)'
75 else
76   $echo 'x -' extracting 'Makefile' '(text)'
77   sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
78 /*
79 # Copyright 2000, International Business Machines, Inc.
80 # All rights reserved.
81 #
82 # original author: George Kraft IV, gk4@us.ibm.com
83 #
84 # Redistribution and use in source and binary forms, with or without
85 # modification, are permitted provided that the following conditions
86 # are met:
87 #
88 # 1. Redistributions of source code must retain the above copyright
89 #    notice, this list of conditions and the following disclaimer.
90 # 2. Redistributions in binary form must reproduce the above copyright
91 #    notice, this list of conditions and the following disclaimer in the
92 #    documentation and/or other materials provided with the distribution.
93 # 3. Neither the name of International Business Machines, Inc., nor the 
94 #    names of its contributors may be used to endorse or promote products 
95 #    derived from this software without specific prior written permission.
96 #
97 # THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
98 # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
99 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
100 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL 
101 # INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
102 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 # SUCH DAMAGE.
109
110 X
111 all: groupmems
112 X
113 groupmems: groupmems.c
114 X       cc -g -o groupmems groupmems.c -L. -lshadow
115 X
116 install: groupmems
117 X       -/usr/sbin/groupadd groups
118 X       install -o root -g groups -m 4770 groupmems /usr/bin
119 X
120 install.man: groupmems.8
121 X       install -o root -g root -m 644 groupmems.8 /usr/man/man8
122 X
123 SHAR_EOF
124   (set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") &&
125   chmod 0644 'Makefile' ||
126   $echo 'restore of' 'Makefile' 'failed'
127   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
128   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
129     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
130     || $echo 'Makefile:' 'MD5 check failed'
131 b46cf7ef8d59149093c011ced3f3103c  Makefile
132 SHAR_EOF
133   else
134     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
135     test 1960 -eq "$shar_count" ||
136     $echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!"
137   fi
138 fi
139 # ============= groupmems.c ==============
140 if test -f 'groupmems.c' && test "$first_param" != -c; then
141   $echo 'x -' SKIPPING 'groupmems.c' '(file already exists)'
142 else
143   $echo 'x -' extracting 'groupmems.c' '(text)'
144   sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
145 /*
146 X * Copyright 2000, International Business Machines, Inc.
147 X * All rights reserved.
148 X *
149 X * original author: George Kraft IV, gk4@us.ibm.com
150 X *
151 X * Redistribution and use in source and binary forms, with or without
152 X * modification, are permitted provided that the following conditions
153 X * are met:
154 X *
155 X * 1. Redistributions of source code must retain the above copyright
156 X *    notice, this list of conditions and the following disclaimer.
157 X * 2. Redistributions in binary form must reproduce the above copyright
158 X *    notice, this list of conditions and the following disclaimer in the
159 X *    documentation and/or other materials provided with the distribution.
160 X * 3. Neither the name of International Business Machines, Inc., nor the 
161 X *    names of its contributors may be used to endorse or promote products 
162 X *    derived from this software without specific prior written permission.
163 X *
164 X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
165 X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
166 X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
167 X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL 
168 X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
169 X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
170 X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
171 X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
172 X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
173 X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
174 X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
175 X * SUCH DAMAGE.
176 X */
177 /*
178 **
179 **      Utility "groupmem" adds and deletes members from a user's group.
180 **      
181 **      Setup (as "root"):
182 **      
183 **              groupadd -r groups 
184 **              chmod 2770 groupmems
185 **              chown root.groups groupmems
186 **              groupmems -g groups -a gk4
187 **      
188 **      Usage (as "gk4"):
189 **      
190 **              groupmems -a olive
191 **              groupmems -a jordan
192 **              groupmems -a meghan
193 **              groupmems -a morgan
194 **              groupmems -a jake
195 **              groupmems -l 
196 **              groupmems -d jake
197 **              groupmems -l 
198 */
199 X
200 #include <stdio.h>
201 #include <pwd.h>
202 #include <grp.h>
203 #include <sys/types.h>
204 #include <sys/stat.h>
205 #include <fcntl.h>
206 #include "defines.h"
207 #include "groupio.h"
208 X
209 /* Exit Status Values */
210 X
211 #define EXIT_SUCCESS            0       /* success */
212 #define EXIT_USAGE              1       /* invalid command syntax */
213 #define EXIT_GROUP_FILE         2       /* group file access problems */
214 #define EXIT_NOT_ROOT           3       /* not superuser  */
215 #define EXIT_NOT_EROOT          4       /* not effective superuser  */
216 #define EXIT_NOT_PRIMARY        5       /* not primary owner of group  */
217 #define EXIT_NOT_MEMBER         6       /* member of group does not exist */
218 #define EXIT_MEMBER_EXISTS      7       /* member of group already exists */
219 X
220 #define TRUE 1
221 #define FALSE 0
222 X
223 /* Globals */
224 X
225 extern int optind;
226 extern char *optarg;
227 static char *adduser = NULL;
228 static char *deluser = NULL;
229 static char *thisgroup = NULL;
230 static int purge = FALSE;
231 static int list = FALSE;
232 static int exclusive = 0;
233 X
234 static int isroot(void) {
235 X       return getuid() ? FALSE : TRUE;
236 }
237 X
238 static int isgroup(void) {
239 X       gid_t g = getgid();
240 X       struct group *grp = getgrgid(g);
241 X
242 X       return TRUE;
243 }
244 X
245 static char *whoami(void) {
246 X       struct group *grp = getgrgid(getgid());
247 X       struct passwd *usr = getpwuid(getuid());
248 X
249 X       if (0 == strcmp(usr->pw_name, grp->gr_name)) {
250 X               return (char *)strdup(usr->pw_name);
251 X       } else {
252 X               return NULL;
253 X       } 
254 }
255 X
256 static void
257 addtogroup(char *user, char **members) {
258 X       int i;
259 X       char **pmembers;
260 X
261 X       for (i = 0; NULL != members[i]; i++ ) {
262 X               if (0 == strcmp(user, members[i])) {
263 X                       fprintf(stderr, "Member already exists\n");
264 X                       exit(EXIT_MEMBER_EXISTS);
265 X               }
266 X       }
267 X
268 X       if (0 == i) {
269 X               pmembers = (char **)calloc(2, sizeof(char *));
270 X       } else {
271 X               pmembers = (char **)realloc(members, sizeof(char *)*(i+1));
272 X       }
273 X
274 X       *members = *pmembers;
275 X       members[i] = user;
276 X       members[i+1] = NULL;
277 }
278 X
279 static void
280 rmfromgroup(char *user, char **members) {
281 X       int i;
282 X       int found = FALSE;
283 X
284 X       i = 0;
285 X       while (!found && NULL != members[i]) {
286 X               if (0 == strcmp(user, members[i])) {
287 X                       found = TRUE;
288 X               } else {
289 X                       i++;
290 X               }
291 X       }
292 X
293 X       while (found && NULL != members[i]) {
294 X               members[i] = members[++i];
295 X       }
296 X
297 X       if (!found) {
298 X               fprintf(stderr, "Member to remove could not be found\n");
299 X               exit(EXIT_NOT_MEMBER);
300 X       }
301 }
302 X
303 static void
304 nomembers(char **members) {
305 X       int i;
306 X
307 X       for (i = 0; NULL != members[i]; i++ ) {
308 X               members[i] = NULL;
309 X       }
310 }
311 X
312 static void
313 members(char **members) {
314 X       int i;
315 X
316 X       for (i = 0; NULL != members[i]; i++ ) {
317 X               printf("%s ", members[i]);
318 X
319 X               if (NULL == members[i+1]) {
320 X                       printf("\n");
321 X               } else {
322 X                       printf(" ");
323 X               }
324 X       }
325 }
326 X
327 static void usage(void) {
328 X       fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n");
329 X       exit(EXIT_USAGE);
330 }
331 X
332 main(int argc, char **argv) {
333 X       int arg, i;
334 X       char *name;
335 X       struct group *grp;
336 X
337 X       while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) {
338 X               switch (arg) {
339 X               case 'a':
340 X                       adduser = strdup(optarg);
341 X                       ++exclusive;
342 X                       break;
343 X               case 'd':
344 X                       deluser = strdup(optarg);
345 X                       ++exclusive;
346 X                       break;
347 X               case 'g':
348 X                       thisgroup = strdup(optarg);
349 X                       break;
350 X               case 'D':
351 X                       purge = TRUE;
352 X                       ++exclusive;
353 X                       break;
354 X               case 'l':
355 X                       list = TRUE;
356 X                       ++exclusive;
357 X                       break;
358 X               default:
359 X                       usage();
360 X               }
361 X       }
362 X
363 X       if (exclusive > 1 || optind < argc) {
364 X               usage();
365 X       }
366 X
367 X       if (!isroot() && NULL != thisgroup) {
368 X               fprintf(stderr, "Only root can add members to different groups\n");
369 X               exit(EXIT_NOT_ROOT);
370 X       } else if (isroot() && NULL != thisgroup) {
371 X               name = thisgroup;
372 X       } else if (!isgroup()) {
373 X               fprintf(stderr, "Group access is required\n");
374 X               exit(EXIT_NOT_EROOT);
375 X       } else if (NULL == (name = whoami())) {
376 X               fprintf(stderr, "Not primary owner of current group\n");
377 X               exit(EXIT_NOT_PRIMARY);
378 X       }
379 X
380 X       if (!gr_lock()) {
381 X               fprintf(stderr, "Unable to lock group file\n");
382 X               exit(EXIT_GROUP_FILE);
383 X       }
384 X
385 X       if (!gr_open(O_RDWR)) {
386 X               fprintf(stderr, "Unable to open group file\n");
387 X               exit(EXIT_GROUP_FILE);
388 X       }
389 X
390 X       grp = (struct group *)gr_locate(name);
391 X
392 X       if (NULL != adduser) {
393 X               addtogroup(adduser, grp->gr_mem);
394 X               gr_update(grp);
395 X       } else if (NULL != deluser) {
396 X               rmfromgroup(deluser, grp->gr_mem);
397 X               gr_update(grp);
398 X       } else if (purge) {
399 X               nomembers(grp->gr_mem);
400 X               gr_update(grp);
401 X       } else if (list) {
402 X               members(grp->gr_mem);
403 X       }
404 X
405 X       if (!gr_close()) {
406 X               fprintf(stderr, "Cannot close group file\n");
407 X               exit(EXIT_GROUP_FILE);
408 X       }
409 X
410 X       gr_unlock();
411 X
412 X       exit(EXIT_SUCCESS);
413 }
414 X
415 /* EOF */
416 SHAR_EOF
417   (set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") &&
418   chmod 0644 'groupmems.c' ||
419   $echo 'restore of' 'groupmems.c' 'failed'
420   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
421   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
422     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
423     || $echo 'groupmems.c:' 'MD5 check failed'
424 f0dd68f8d762d89d24d3ce1f4141f981  groupmems.c
425 SHAR_EOF
426   else
427     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`"
428     test 6348 -eq "$shar_count" ||
429     $echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!"
430   fi
431 fi
432 # ============= groupmems.8 ==============
433 if test -f 'groupmems.8' && test "$first_param" != -c; then
434   $echo 'x -' SKIPPING 'groupmems.8' '(file already exists)'
435 else
436   $echo 'x -' extracting 'groupmems.8' '(text)'
437   sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
438 X.\"
439 X.\" Copyright 2000, International Business Machines, Inc.
440 X.\" All rights reserved.
441 X.\"
442 X.\" original author: George Kraft IV, gk4@us.ibm.com
443 X.\"
444 X.\" Redistribution and use in source and binary forms, with or without
445 X.\" modification, are permitted provided that the following conditions
446 X.\" are met:
447 X.\"
448 X.\" 1. Redistributions of source code must retain the above copyright
449 X.\"    notice, this list of conditions and the following disclaimer.
450 X.\" 2. Redistributions in binary form must reproduce the above copyright
451 X.\"    notice, this list of conditions and the following disclaimer in the
452 X.\"    documentation and/or other materials provided with the distribution.
453 X.\" 3. Neither the name of International Business Machines, Inc., nor the 
454 X.\"    names of its contributors may be used to endorse or promote products 
455 X.\"    derived from this software without specific prior written permission.
456 X.\"
457 X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
458 X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
459 X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
460 X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL 
461 X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
462 X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
463 X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
464 X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
465 X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
466 X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
467 X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
468 X.\" SUCH DAMAGE.
469 X.\"
470 X.\" $Id: groupmems.shar 1342 2007-11-10 23:46:11Z nekral-guest $
471 X.\"
472 X.TH GROUPMEMS 8
473 X.SH NAME
474 groupmems \- Administer members of a user's primary group
475 X.SH SYNOPSIS
476 X.B groupmems
477 \fB-a\fI user_name \fR |
478 \fB-d\fI user_name \fR |
479 \fB-l\fR |
480 \fB-D\fR |
481 [\fB-g\fI group_name \fR]
482 X.SH DESCRIPTION
483 The \fBgroupmems\fR utility allows a user to administer his/her own
484 group membership list without the requirement of superuser privileges.
485 The \fBgroupmems\fR utility is for systems that configure its users to
486 be in their own name sake primary group (i.e., guest / guest).
487 X.P
488 Only the superuser, as administrator, can use \fBgroupmems\fR to alter
489 the memberships of other groups.
490 X.IP "\fB-a \fIuser_name\fR"
491 Add a new user to the group membership list.
492 X.IP "\fB-d \fIuser_name\fR"
493 Delete a user from the group membership list.
494 X.IP "\fB-l\fR"
495 List the group membership list.
496 X.IP "\fB-D\fR"
497 Delete all users from the group membership list.
498 X.IP "\fB-g \fIgroup_name\fR"
499 The superuser can specify which group membership list to modify.
500 X.SH SETUP
501 The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR
502 and in group \fBgroups\fR.   The system administrator can add users to
503 group groups to allow or disallow them using the  \fBgroupmems\fR utility
504 to manager their own group membership list.
505 X.P
506 X     $ groupadd -r groups
507 X.br
508 X     $ chmod 2770 groupmems
509 X.br
510 X     $ chown root.groups groupmems
511 X.br
512 X     $ groupmems -g groups -a gk4
513 X.SH FILES
514 /etc/group
515 X.br
516 /etc/gshadow
517 X.SH SEE ALSO
518 X.BR chfn (1),
519 X.BR chsh (1),
520 X.BR useradd (8),
521 X.BR userdel (8),
522 X.BR usermod (8),
523 X.BR passwd (1),
524 X.BR groupadd (8),
525 X.BR groupdel (8)
526 X.SH AUTHOR
527 George Kraft IV (gk4@us.ibm.com)
528 X.\" EOF
529 SHAR_EOF
530   (set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") &&
531   chmod 0600 'groupmems.8' ||
532   $echo 'restore of' 'groupmems.8' 'failed'
533   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
534   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
535     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
536     || $echo 'groupmems.8:' 'MD5 check failed'
537 181e6cd3a3c9d3df320197fa2cde2b4a  groupmems.8
538 SHAR_EOF
539   else
540     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`"
541     test 3372 -eq "$shar_count" ||
542     $echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!"
543   fi
544 fi
545 rm -fr _sh10937
546 exit 0