Initial commit for Tizen
[profile/extras/shadow-utils.git] / src / pwunconv.c
1 /*
2  * Copyright (c) 1989 - 1994, Julianne Frances Haugh
3  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
4  * Copyright (c) 2001 - 2005, 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 #include <config.h>
34
35 #ident "$Id: pwunconv.c 2852 2009-04-30 21:44:35Z nekral-guest $"
36
37 #include <fcntl.h>
38 #include <pwd.h>
39 #include <stdio.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include "defines.h"
43 #include "nscd.h"
44 #include "prototypes.h"
45 #include "pwio.h"
46 #include "shadowio.h"
47
48 /*
49  * Global variables
50  */
51 char *Prog;
52
53 static bool spw_locked = false;
54 static bool pw_locked = false;
55
56 /* local function prototypes */
57 static void fail_exit (int status);
58
59 static void fail_exit (int status)
60 {
61         if (spw_locked) {
62                 if (spw_unlock () == 0) {
63                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
64                         SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
65                         /* continue */
66                 }
67         }
68         if (pw_locked) {
69                 if (pw_unlock () == 0) {
70                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
71                         SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
72                         /* continue */
73                 }
74         }
75         exit (status);
76 }
77
78
79 int main (int argc, char **argv)
80 {
81         const struct passwd *pw;
82         struct passwd pwent;
83         const struct spwd *spwd;
84
85         if (1 != argc) {
86                 (void) fputs (_("Usage: pwunconv\n"), stderr);
87         }
88         Prog = Basename (argv[0]);
89
90         (void) setlocale (LC_ALL, "");
91         (void) bindtextdomain (PACKAGE, LOCALEDIR);
92         (void) textdomain (PACKAGE);
93
94         OPENLOG ("pwunconv");
95
96         if (!spw_file_present ()) {
97                 /* shadow not installed, do nothing */
98                 exit (0);
99         }
100
101         if (pw_lock () == 0) {
102                 fprintf (stderr,
103                          _("%s: cannot lock %s; try again later.\n"),
104                          Prog, pw_dbname ());
105                 fail_exit (5);
106         }
107         pw_locked = true;
108         if (pw_open (O_RDWR) == 0) {
109                 fprintf (stderr,
110                          _("%s: cannot open %s\n"),
111                          Prog, pw_dbname ());
112                 fail_exit (1);
113         }
114
115         if (spw_lock () == 0) {
116                 fprintf (stderr,
117                          _("%s: cannot lock %s; try again later.\n"),
118                          Prog, spw_dbname ());
119                 fail_exit (5);
120         }
121         spw_locked = true;
122         if (spw_open (O_RDWR) == 0) {
123                 fprintf (stderr,
124                          _("%s: cannot open %s\n"),
125                          Prog, spw_dbname ());
126                 fail_exit (1);
127         }
128
129         pw_rewind ();
130         while ((pw = pw_next ()) != NULL) {
131                 spwd = spw_locate (pw->pw_name);
132                 if (NULL == spwd) {
133                         continue;
134                 }
135
136                 pwent = *pw;
137
138                 /*
139                  * Update password if non-shadow is "x".
140                  */
141                 if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
142                         pwent.pw_passwd = spwd->sp_pwdp;
143                 }
144
145                 /*
146                  * Password aging works differently in the two different
147                  * systems. With shadow password files you apparently must
148                  * have some aging information. The maxweeks or minweeks
149                  * may not map exactly. In pwconv we set max == 10000,
150                  * which is about 30 years. Here we have to undo that
151                  * kludge. So, if maxdays == 10000, no aging information is
152                  * put into the new file. Otherwise, the days are converted
153                  * to weeks and so on.
154                  */
155                 if (pw_update (&pwent) == 0) {
156                         fprintf (stderr,
157                                  _("%s: failed to prepare the new %s entry '%s'\n"),
158                                  Prog, pw_dbname (), pwent.pw_name);
159                         fail_exit (3);
160                 }
161         }
162
163         if (spw_close () == 0) {
164                 fprintf (stderr,
165                          _("%s: failure while writing changes to %s\n"),
166                          Prog, spw_dbname ());
167                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
168                 fail_exit (3);
169         }
170
171         if (pw_close () == 0) {
172                 fprintf (stderr,
173                          _("%s: failure while writing changes to %s\n"),
174                          Prog, pw_dbname ());
175                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
176                 fail_exit (3);
177         }
178
179         if (unlink (SHADOW) != 0) {
180                 fprintf (stderr,
181                          _("%s: cannot delete %s\n"), Prog, SHADOW);
182                 SYSLOG ((LOG_ERR, "cannot delete %s", SHADOW));
183                 fail_exit (3);
184         }
185
186         if (spw_unlock () == 0) {
187                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
188                 SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
189                 /* continue */
190         }
191         if (pw_unlock () == 0) {
192                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
193                 SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
194                 /* continue */
195         }
196
197         nscd_flush_cache ("passwd");
198
199         return 0;
200 }
201