# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 2013 RackTop Systems. # # Copyright (c) 2018, Joyent, Inc. include ../../Makefile.cmd GROUPADD= groupadd GROUPDEL= groupdel GROUPMOD= groupmod SBINPROG= $(GROUPADD) $(GROUPDEL) $(GROUPMOD) PROG= $(SBINPROG) ADD_OBJ= groupadd.o add_group.o messages.o DEL_OBJ= groupdel.o del_group.o messages.o MOD_OBJ= groupmod.o mod_group.o messages.o OBJECTS= $(ADD_OBJ) $(DEL_OBJ) $(MOD_OBJ) SRCS= $(OBJECTS:.o=.c) LIBDIR= ../lib LIBUSRGRP= $(LIBDIR)/lib.a LOCAL= ../inc HERE= . LINTFLAGS= -u INSSBINPROG= $(SBINPROG:%=$(ROOTUSRSBIN)/%) CPPFLAGS= -I$(HERE) -I$(LOCAL) $(CPPFLAGS.master) FILEMODE= 0555 # not linted SMATCH=off $(GROUPADD) : OBJS = $(ADD_OBJ) $(GROUPADD) : LDLIBS += $(LIBUSRGRP) -lcmdutils $(GROUPDEL) : OBJS = $(DEL_OBJ) $(GROUPDEL) : LDLIBS += $(LIBUSRGRP) $(GROUPMOD) : OBJS = $(MOD_OBJ) $(GROUPMOD) : LDLIBS += $(LIBUSRGRP) all: $(PROG) $(PROG): $$(OBJS) $(LIBUSRGRP) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) $(GROUPADD): $(ADD_OBJ) $(GROUPMOD): $(MOD_OBJ) $(GROUPDEL): $(DEL_OBJ) install: all $(INSSBINPROG) clean: $(RM) $(OBJECTS) lint: lint_SRCS include ../../Makefile.targ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include #include #include #include #include #define GRPTMP "/etc/gtmp" #define GRPBUFSIZ 5120 int add_group(group, gid) char *group; /* name of group to add */ gid_t gid; /* gid of group to add */ { FILE *etcgrp; /* /etc/group file */ FILE *etctmp; /* temp file */ int o_mask; /* old umask value */ int newdone = 0; /* set true when new entry done */ struct stat sb; /* stat buf to copy modes */ char buf[GRPBUFSIZ]; if ((etcgrp = fopen(GROUP, "r")) == NULL) { return (EX_UPDATE); } if (fstat(fileno(etcgrp), &sb) < 0) { /* If we can't get mode, take a default */ sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; } o_mask = umask(077); etctmp = fopen(GRPTMP, "w+"); (void) umask(o_mask); if (etctmp == NULL) { fclose(etcgrp); return (EX_UPDATE); } if (fchmod(fileno(etctmp), sb.st_mode) != 0 || fchown(fileno(etctmp), sb.st_uid, sb.st_gid) != 0 || lockf(fileno(etctmp), F_LOCK, 0) != 0) { fclose(etcgrp); fclose(etctmp); unlink(GRPTMP); return (EX_UPDATE); } while (fgets(buf, GRPBUFSIZ, etcgrp) != NULL) { /* Check for NameService reference */ if (!newdone && (buf[0] == '+' || buf[0] == '-')) { (void) fprintf(etctmp, "%s::%u:\n", group, gid); newdone = 1; } fputs(buf, etctmp); } (void) fclose(etcgrp); if (!newdone) { (void) fprintf(etctmp, "%s::%u:\n", group, gid); } if (rename(GRPTMP, GROUP) < 0) { fclose(etctmp); unlink(GRPTMP); return (EX_UPDATE); } (void) fclose(etctmp); return (EX_SUCCESS); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include #include #include #include #include #include #include #include #include #include "users.h" #include "messages.h" /* lint error-killers: */ int errmsg(int, int); /* Delete a group from the GROUP file */ int del_group(char *group) { int deleted; FILE *e_fptr, *t_fptr; struct group *grpstruct; char tname[] = "/etc/gtmp.XXXXXX"; int fd; struct stat sbuf; boolean_t haserr; int line = 1; if ((e_fptr = fopen(GROUP, "r")) == NULL) return (EX_UPDATE); if (fstat(fileno(e_fptr), &sbuf) != 0) return (EX_UPDATE); if ((fd = mkstemp(tname)) == -1) return (EX_UPDATE); if ((t_fptr = fdopen(fd, "w")) == NULL) { (void) close(fd); (void) unlink(tname); return (EX_UPDATE); } /* * Get ownership and permissions correct */ if (fchmod(fd, sbuf.st_mode) != 0 || fchown(fd, sbuf.st_uid, sbuf.st_gid) != 0) { (void) fclose(t_fptr); (void) unlink(tname); return (EX_UPDATE); } /* loop thru GROUP looking for the one to delete */ deleted = 0; while ((grpstruct = fgetgrent(e_fptr)) != NULL) { /* check to see if group is one to delete */ if (strcmp(grpstruct->gr_name, group) == 0) deleted = 1; else putgrent(grpstruct, t_fptr); line++; } haserr = !feof(e_fptr); if (haserr) errmsg(M_SYNTAX, line); (void) fclose(e_fptr); if (fclose(t_fptr) != 0 || haserr) { /* GROUP file contains bad entries or write failed. */ (void) unlink(tname); return (EX_UPDATE); } /* If deleted, update GROUP file */ if (deleted) { if (rename(tname, GROUP) != 0) { (void) unlink(tname); return (EX_UPDATE); } return (EX_SUCCESS); } else { (void) unlink(tname); return (EX_NAME_NOT_EXIST); } } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 2013 RackTop Systems. */ #include #include #include #include #include #include #include #include #include #include #include "messages.h" extern int errmsg(); extern int valid_gid(), add_group(); /* * groupadd [-g gid [-o]] group * * This command adds new groups to the system. Arguments are: * * gid - a gid_t less than MAXUID * group - a string of printable characters excluding colon(:) and less * than MAXGLEN characters long. */ char *cmdname = "groupadd"; int main(int argc, char *argv[]) { int ch; /* return from getopt */ gid_t gid; /* group id */ int oflag = 0; /* flags */ int rc; char *gidstr = NULL; /* gid from command line */ char *grpname; /* group name from command line */ int warning; while ((ch = getopt(argc, argv, "g:o")) != EOF) switch (ch) { case 'g': gidstr = optarg; break; case 'o': oflag++; break; case '?': errmsg(M_AUSAGE); exit(EX_SYNTAX); } if ((oflag && !gidstr) || optind != argc - 1) { errmsg(M_AUSAGE); exit(EX_SYNTAX); } grpname = argv[optind]; switch (valid_gname(grpname, NULL, &warning)) { case INVALID: errmsg(M_GRP_INVALID, grpname); exit(EX_BADARG); /*NOTREACHED*/ case NOTUNIQUE: errmsg(M_GRP_USED, grpname); exit(EX_NAME_EXISTS); /*NOTREACHED*/ } if (warning) warningmsg(warning, grpname); if (gidstr) { /* Given a gid string - validate it */ char *ptr; errno = 0; gid = (gid_t)strtol(gidstr, &ptr, 10); if (*ptr || errno == ERANGE) { errmsg(M_GID_INVALID, gidstr); exit(EX_BADARG); } switch (valid_gid(gid, NULL)) { case RESERVED: errmsg(M_RESERVED, gid); break; case NOTUNIQUE: if (!oflag) { errmsg(M_GRP_USED, gidstr); exit(EX_ID_EXISTS); } break; case INVALID: errmsg(M_GID_INVALID, gidstr); exit(EX_BADARG); case TOOBIG: errmsg(M_TOOBIG, gid); exit(EX_BADARG); } } else { if (findnextgid(DEFRID+1, MAXUID, &gid) != 0) { errmsg(M_GID_INVALID, "default id"); exit(EX_ID_EXISTS); } } if ((rc = add_group(grpname, gid)) != EX_SUCCESS) errmsg(M_UPDATE, "created"); return (rc); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include #include #include #include "messages.h" /* * groupdel group * * This command deletes groups from the system. Arguments are: * * group - a character string group name */ char *cmdname = "groupdel"; extern void errmsg(), exit(); extern int del_group(); int main(int argc, char **argv) { char *group; /* group name from command line */ int retval = 0; if (argc != 2) { errmsg(M_DUSAGE); exit(EX_SYNTAX); } group = argv[1]; switch (retval = del_group(group)) { case EX_UPDATE: errmsg(M_UPDATE, "deleted"); break; case EX_NAME_NOT_EXIST: errmsg(M_NO_GROUP, group); break; } return (retval); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include #include #include #include #include #include #include #include #include "messages.h" /* * groupmod -g gid [-o] | -n name group * * This command modifies groups on the system. Arguments are: * * gid - a gid_t less than UID_MAX * name - a string of printable characters excluding colon (:) and less * than MAXGLEN characters long. * group - a string of printable characters excluding colon(:) and less * than MAXGLEN characters long. */ extern int valid_gid(), mod_group(); extern void errmsg(); char *cmdname = "groupmod"; int main(int argc, char *argv[]) { int ch; /* return from getopt */ gid_t gid; /* group id */ int oflag = 0; /* flags */ int valret; /* return from valid_gid() */ char *gidstr = NULL; /* gid from command line */ char *newname = NULL; /* new group name with -n option */ char *grpname; /* group name from command line */ int warning; oflag = 0; /* flags */ while ((ch = getopt(argc, argv, "g:on:")) != EOF) { switch (ch) { case 'g': gidstr = optarg; break; case 'o': oflag++; break; case 'n': newname = optarg; break; case '?': errmsg(M_MUSAGE); exit(EX_SYNTAX); } } if ((oflag && !gidstr) || optind != argc - 1) { errmsg(M_MUSAGE); exit(EX_SYNTAX); } grpname = argv[optind]; if (gidstr) { /* convert gidstr to integer */ char *ptr; errno = 0; gid = (gid_t)strtol(gidstr, &ptr, 10); if (*ptr || errno == ERANGE) { errmsg(M_GID_INVALID, gidstr); exit(EX_BADARG); } switch (valid_gid(gid, NULL)) { case RESERVED: errmsg(M_RESERVED, gid); break; case NOTUNIQUE: if (!oflag) { errmsg(M_GRP_USED, gidstr); exit(EX_ID_EXISTS); } break; case INVALID: errmsg(M_GID_INVALID, gidstr); exit(EX_BADARG); /*NOTREACHED*/ case TOOBIG: errmsg(M_TOOBIG, gid); exit(EX_BADARG); /*NOTREACHED*/ } } else gid = -1; if (newname) { switch (valid_gname(newname, NULL, &warning)) { case INVALID: errmsg(M_GRP_INVALID, newname); exit(EX_BADARG); case NOTUNIQUE: errmsg(M_GRP_USED, newname); exit(EX_NAME_EXISTS); } if (warning) warningmsg(warning, newname); } if ((valret = mod_group(grpname, gid, newname)) != EX_SUCCESS) { if (valret == EX_NAME_NOT_EXIST) errmsg(M_NO_GROUP, grpname); else errmsg(M_UPDATE, "modified"); } return (valret); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ char *errmsgs[] = { "WARNING: gid %ld is reserved.\n", "ERROR: invalid syntax.\nusage: groupadd [-g gid [-o]] group\n", "ERROR: invalid syntax.\nusage: groupdel group\n", "ERROR: invalid syntax.\nusage: groupmod -g gid [-o] | -n name group\n", "ERROR: Cannot update system files - group cannot be %s.\n", "ERROR: %s is not a valid group id. Choose another.\n", "ERROR: %s is already in use. Choose another.\n", "ERROR: %s is not a valid group name. Choose another.\n", "ERROR: %s does not exist.\n", "ERROR: Group id %ld is too big. Choose another.\n", "ERROR: Permission denied.\n", "ERROR: Syntax error in group file at line %d.\n", }; int lasterrmsg = sizeof (errmsgs) / sizeof (char *); /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* WARNING: gid %d is reserved.\n */ #define M_RESERVED 0 /* ERROR: invalid syntax.\nusage: groupadd [-g gid [-o]] group\n */ #define M_AUSAGE 1 /* ERROR: invalid syntax.\nusage: groupdel group\n */ #define M_DUSAGE 2 /* ERROR: invalid syntax.\nusage: groupmod -g gid [-o] | -n name group\n */ #define M_MUSAGE 3 /* ERROR: Cannot update system files - group cannot be %s.\n */ #define M_UPDATE 4 /* ERROR: %s is not a valid group id. Choose another.\n */ #define M_GID_INVALID 5 /* ERROR: %s is already in use. Choose another.\n */ #define M_GRP_USED 6 /* ERROR: %s is not a valid group name. Choose another.\n */ #define M_GRP_INVALID 7 /* ERROR: %s does not exist.\n */ #define M_NO_GROUP 8 /* ERROR: Group id %d is too big. Choose another.\n */ #define M_TOOBIG 9 /* ERROR: Permission denied.\n */ #define M_PERM_DENIED 10 /* ERROR: Syntax error in group file at line %d.\n */ #define M_SYNTAX 11 /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include #include #include #include #include #include #include #include #include #include "users.h" #include "messages.h" /* lint error-killers: */ void errmsg(int, int); /* Modify group to new gid and/or new name */ int mod_group(char *group, gid_t gid, char *newgroup) { int modified = 0; int fd; char tname[] = "/etc/gtmp.XXXXXX"; FILE *e_fptr, *t_fptr; struct group *g_ptr; struct stat sbuf; boolean_t haserr; int line = 1; if ((e_fptr = fopen(GROUP, "r")) == NULL) return (EX_UPDATE); if (fstat(fileno(e_fptr), &sbuf) != 0) return (EX_UPDATE); if ((fd = mkstemp(tname)) == -1) return (EX_UPDATE); if ((t_fptr = fdopen(fd, "w")) == NULL) { (void) close(fd); (void) unlink(tname); return (EX_UPDATE); } /* * Get ownership and permissions correct */ if (fchmod(fd, sbuf.st_mode) != 0 || fchown(fd, sbuf.st_uid, sbuf.st_gid) != 0) { (void) fclose(t_fptr); (void) unlink(tname); return (EX_UPDATE); } while ((g_ptr = fgetgrent(e_fptr)) != NULL) { /* check to see if group is one to modify */ if (strcmp(g_ptr->gr_name, group) == 0) { if (newgroup != NULL) g_ptr->gr_name = newgroup; if (gid != -1) g_ptr->gr_gid = gid; modified++; } putgrent(g_ptr, t_fptr); line++; } haserr = !feof(e_fptr); if (haserr) errmsg(M_SYNTAX, line); (void) fclose(e_fptr); if (fclose(t_fptr) != 0 || haserr) { /* GROUP file contains bad entries or write failed. */ (void) unlink(tname); return (EX_UPDATE); } if (modified) { if (rename(tname, GROUP) != 0) { (void) unlink(tname); return (EX_UPDATE); } return (EX_SUCCESS); } else { (void) unlink(tname); return (EX_NAME_NOT_EXIST); } }