Initial commit for Tizen
[profile/extras/shadow-utils.git] / src / grpunconv.c
1 /*
2  * Copyright (c) 1996       , Michael Meskes
3  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
4  * Copyright (c) 2002 - 2006, Tomasz Kłoczko
5  * Copyright (c) 2008       , Nicolas François
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the copyright holders or contributors may not be used to
17  *    endorse or promote products derived from this software without
18  *    specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * grpunconv - update /etc/group with information from /etc/gshadow.
35  *
36  */
37
38 #include <config.h>
39
40 #ident "$Id: grpunconv.c 2348 2008-09-06 12:51:53Z nekral-guest $"
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <fcntl.h>
46 #include <time.h>
47 #include <unistd.h>
48 #include <grp.h>
49 #include "nscd.h"
50 #include "prototypes.h"
51 #ifdef SHADOWGRP
52 #include "groupio.h"
53 #include "sgroupio.h"
54 /*
55  * Global variables
56  */
57 char *Prog;
58
59 static bool gr_locked  = false;
60 static bool sgr_locked = false;
61
62 /* local function prototypes */
63 static void fail_exit (int status);
64
65 static void fail_exit (int status)
66 {
67         if (gr_locked) {
68                 if (gr_unlock () == 0) {
69                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
70                         SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
71                         /* continue */
72                 }
73         }
74
75         if (sgr_locked) {
76                 if (sgr_unlock () == 0) {
77                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
78                         SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
79                         /* continue */
80                 }
81         }
82
83         exit (status);
84 }
85
86 int main (int argc, char **argv)
87 {
88         const struct group *gr;
89         struct group grent;
90         const struct sgrp *sg;
91
92         if (1 != argc) {
93                 (void) fputs (_("Usage: grpunconv\n"), stderr);
94         }
95         Prog = Basename (argv[0]);
96
97         (void) setlocale (LC_ALL, "");
98         (void) bindtextdomain (PACKAGE, LOCALEDIR);
99         (void) textdomain (PACKAGE);
100
101         OPENLOG ("grpunconv");
102
103         if (sgr_file_present () == 0) {
104                 exit (0);       /* no /etc/gshadow, nothing to do */
105         }
106
107         if (gr_lock () == 0) {
108                 fprintf (stderr,
109                          _("%s: cannot lock %s; try again later.\n"),
110                          Prog, gr_dbname ());
111                 fail_exit (5);
112         }
113         gr_locked = true;
114         if (gr_open (O_RDWR) == 0) {
115                 fprintf (stderr,
116                          _("%s: cannot open %s\n"), Prog, gr_dbname ());
117                 fail_exit (1);
118         }
119
120         if (sgr_lock () == 0) {
121                 fprintf (stderr,
122                          _("%s: cannot lock %s; try again later.\n"),
123                          Prog, sgr_dbname ());
124                 fail_exit (5);
125         }
126         sgr_locked = true;
127         if (sgr_open (O_RDWR) == 0) {
128                 fprintf (stderr,
129                          _("%s: cannot open %s\n"), Prog, sgr_dbname ());
130                 fail_exit (1);
131         }
132
133         /*
134          * Update group passwords if non-shadow password is "x".
135          */
136         gr_rewind ();
137         while ((gr = gr_next ()) != NULL) {
138                 sg = sgr_locate (gr->gr_name);
139                 if (   (NULL != sg)
140                     && (strcmp (gr->gr_passwd, SHADOW_PASSWD_STRING) == 0)) {
141                         /* add password to /etc/group */
142                         grent = *gr;
143                         grent.gr_passwd = sg->sg_passwd;
144                         if (gr_update (&grent) == 0) {
145                                 fprintf (stderr,
146                                          _("%s: failed to prepare the new %s entry '%s'\n"),
147                                          Prog, gr_dbname (), grent.gr_name);
148                                 fail_exit (3);
149                         }
150                 }
151         }
152
153         if (sgr_close () == 0) {
154                 fprintf (stderr,
155                          _("%s: failure while writing changes to %s\n"),
156                          Prog, sgr_dbname ());
157                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
158                 fail_exit (3);
159         }
160
161         if (gr_close () == 0) {
162                 fprintf (stderr,
163                          _("%s: failure while writing changes to %s\n"),
164                          Prog, gr_dbname ());
165                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
166                 fail_exit (3);
167         }
168
169         if (unlink (SGROUP_FILE) != 0) {
170                 fprintf (stderr,
171                          _("%s: cannot delete %s\n"),
172                          Prog, SGROUP_FILE);
173                 SYSLOG ((LOG_ERR, "cannot delete %s", SGROUP_FILE));
174                 fail_exit (3);
175         }
176
177         if (gr_unlock () == 0) {
178                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
179                 SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
180                 /* continue */
181         }
182
183         if (sgr_unlock () == 0) {
184                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
185                 SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
186                 /* continue */
187         }
188
189         nscd_flush_cache ("group");
190
191         return 0;
192 }
193 #else                           /* !SHADOWGRP */
194 int main (int unused(argc), char **argv)
195 {
196         fprintf (stderr,
197                  "%s: not configured for shadow group support.\n", argv[0]);
198         exit (1);
199 }
200 #endif                          /* !SHADOWGRP */
201