2 * Copyright (c) 1996 - 2000, Marek Michałkiewicz
3 * Copyright (c) 2002 - 2006, Tomasz Kłoczko
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the copyright holders or contributors may not be used to
15 * endorse or promote products derived from this software without
16 * specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * grpconv - create or update /etc/gshadow with information from
49 #include "prototypes.h"
58 static bool gr_locked = false;
59 static bool sgr_locked = false;
61 /* local function prototypes */
62 static void fail_exit (int status);
64 static void fail_exit (int status)
67 if (gr_unlock () == 0) {
68 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
69 SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
75 if (sgr_unlock () == 0) {
76 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
77 SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
85 int main (int argc, char **argv)
87 const struct group *gr;
89 const struct sgrp *sg;
93 (void) fputs (_("Usage: grpconv\n"), stderr);
95 Prog = Basename (argv[0]);
97 (void) setlocale (LC_ALL, "");
98 (void) bindtextdomain (PACKAGE, LOCALEDIR);
99 (void) textdomain (PACKAGE);
103 if (gr_lock () == 0) {
105 _("%s: cannot lock %s; try again later.\n"),
110 if (gr_open (O_RDWR) == 0) {
111 fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
115 if (sgr_lock () == 0) {
117 _("%s: cannot lock %s; try again later.\n"),
118 Prog, sgr_dbname ());
122 if (sgr_open (O_CREAT | O_RDWR) == 0) {
123 fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
128 * Remove /etc/gshadow entries for groups not in /etc/group.
131 while ((sg = sgr_next ()) != NULL) {
132 if (gr_locate (sg->sg_name) != NULL) {
136 if (sgr_remove (sg->sg_name) == 0) {
138 * This shouldn't happen (the entry exists) but...
141 _("%s: cannot remove entry '%s' from %s\n"),
142 Prog, sg->sg_name, sgr_dbname ());
148 * Update shadow group passwords if non-shadow password is not "x".
149 * Add any missing shadow group entries.
152 while ((gr = gr_next ()) != NULL) {
153 sg = sgr_locate (gr->gr_name);
155 /* update existing shadow group entry */
157 if (strcmp (gr->gr_passwd, SHADOW_PASSWD_STRING) != 0)
158 sgent.sg_passwd = gr->gr_passwd;
160 static char *empty = 0;
162 /* add new shadow group entry */
163 memset (&sgent, 0, sizeof sgent);
164 sgent.sg_name = gr->gr_name;
165 sgent.sg_passwd = gr->gr_passwd;
166 sgent.sg_adm = ∅
169 * XXX - sg_mem is redundant, it is currently always a copy
170 * of gr_mem. Very few programs actually use sg_mem, and all
171 * of them are in the shadow suite. Maybe this field could
172 * be used for something else? Any suggestions?
174 sgent.sg_mem = gr->gr_mem;
176 if (sgr_update (&sgent) == 0) {
178 _("%s: failed to prepare the new %s entry '%s'\n"),
179 Prog, sgr_dbname (), sgent.sg_name);
182 /* remove password from /etc/group */
184 grent.gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
185 if (gr_update (&grent) == 0) {
187 _("%s: failed to prepare the new %s entry '%s'\n"),
188 Prog, gr_dbname (), grent.gr_name);
193 if (sgr_close () == 0) {
195 _("%s: failure while writing changes to %s\n"),
196 Prog, sgr_dbname ());
197 SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
200 if (gr_close () == 0) {
202 _("%s: failure while writing changes to %s\n"),
204 SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
207 if (sgr_unlock () == 0) {
208 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
209 SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
213 if (gr_unlock () == 0) {
214 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
215 SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
220 nscd_flush_cache ("group");
224 #else /* !SHADOWGRP */
225 int main (int unused(argc), char **argv)
228 "%s: not configured for shadow group support.\n", argv[0]);
231 #endif /* !SHADOWGRP */