1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28/*	  All Rights Reserved  	*/
29
30
31#pragma ident	"%Z%%M%	%I%	%E% SMI"
32
33#include <sys/types.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <ctype.h>
37#include <limits.h>
38#include <userdefs.h>
39#include <users.h>
40#include <errno.h>
41#include "messages.h"
42
43/*
44 *  groupmod -g gid [-o] | -n name group
45 *
46 *	This command modifies groups on the system.  Arguments are:
47 *
48 *	gid - a gid_t less than UID_MAX
49 *	name - a string of printable characters excluding colon (:) and less
50 *		than MAXGLEN characters long.
51 *	group - a string of printable characters excluding colon(:) and less
52 *		than MAXGLEN characters long.
53 */
54
55extern int valid_gid(), mod_group();
56extern void errmsg();
57
58char *cmdname = "groupmod";
59
60int
61main(int argc, char *argv[])
62{
63	int ch;				/* return from getopt */
64	gid_t gid;			/* group id */
65	int oflag = 0;			/* flags */
66	int valret;			/* return from valid_gid() */
67	char *gidstr = NULL;		/* gid from command line */
68	char *newname = NULL;		/* new group name with -n option */
69	char *grpname;			/* group name from command line */
70	int warning;
71
72	oflag = 0;	/* flags */
73
74	while ((ch = getopt(argc, argv, "g:on:")) != EOF)  {
75		switch (ch) {
76			case 'g':
77				gidstr = optarg;
78				break;
79			case 'o':
80				oflag++;
81				break;
82			case 'n':
83				newname = optarg;
84				break;
85			case '?':
86				errmsg(M_MUSAGE);
87				exit(EX_SYNTAX);
88		}
89	}
90
91	if ((oflag && !gidstr) || optind != argc - 1) {
92		errmsg(M_MUSAGE);
93		exit(EX_SYNTAX);
94	}
95
96	grpname = argv[optind];
97
98	if (gidstr) {
99		/* convert gidstr to integer */
100		char *ptr;
101
102		errno = 0;
103		gid = (gid_t)strtol(gidstr, &ptr, 10);
104
105		if (*ptr || errno == ERANGE) {
106			errmsg(M_GID_INVALID, gidstr);
107			exit(EX_BADARG);
108		}
109
110		switch (valid_gid(gid, NULL)) {
111		case RESERVED:
112			errmsg(M_RESERVED, gid);
113			break;
114
115		case NOTUNIQUE:
116			if (!oflag) {
117				errmsg(M_GRP_USED, gidstr);
118				exit(EX_ID_EXISTS);
119			}
120			break;
121
122		case INVALID:
123			errmsg(M_GID_INVALID, gidstr);
124			exit(EX_BADARG);
125			/*NOTREACHED*/
126
127		case TOOBIG:
128			errmsg(M_TOOBIG, gid);
129			exit(EX_BADARG);
130			/*NOTREACHED*/
131
132		}
133
134	} else gid = -1;
135
136	if (newname) {
137		switch (valid_gname(newname, NULL, &warning)) {
138		case INVALID:
139			errmsg(M_GRP_INVALID, newname);
140			exit(EX_BADARG);
141		case NOTUNIQUE:
142			errmsg(M_GRP_USED, newname);
143			exit(EX_NAME_EXISTS);
144		}
145		if (warning)
146			warningmsg(warning, newname);
147	}
148
149	if ((valret = mod_group(grpname, gid, newname)) != EX_SUCCESS) {
150		if (valret == EX_NAME_NOT_EXIST)
151			errmsg(M_NO_GROUP, grpname);
152		else
153			errmsg(M_UPDATE, "modified");
154	}
155
156	return (valret);
157}
158