Initial commit for Tizen
[profile/extras/shadow-utils.git] / lib / sgetspent.c
1 /*
2  * Copyright (c) 1989 - 1994, Julianne Frances Haugh
3  * Copyright (c) 1996 - 1998, Marek Michałkiewicz
4  * Copyright (c) 2003 - 2005, Tomasz Kłoczko
5  * Copyright (c) 2009       , 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 /* Newer versions of Linux libc already have shadow support.  */
36 #ifndef HAVE_SGETSPENT
37
38 #ident "$Id$"
39
40 #include <sys/types.h>
41 #include "prototypes.h"
42 #include "defines.h"
43 #include <stdio.h>
44 #define FIELDS  9
45 #define OFIELDS 5
46 /*
47  * sgetspent - convert string in shadow file format to (struct spwd *)
48  */
49 struct spwd *sgetspent (const char *string)
50 {
51         static char spwbuf[1024];
52         static struct spwd spwd;
53         char *fields[FIELDS];
54         char *cp;
55         char *cpp;
56         int i;
57
58         /*
59          * Copy string to local buffer.  It has to be tokenized and we
60          * have to do that to our private copy.
61          */
62
63         if (strlen (string) >= sizeof spwbuf) {
64                 return 0;       /* fail if too long */
65         }
66         strcpy (spwbuf, string);
67
68         cp = strrchr (spwbuf, '\n');
69         if (NULL != cp) {
70                 *cp = '\0';
71         }
72
73         /*
74          * Tokenize the string into colon separated fields.  Allow up to
75          * FIELDS different fields.
76          */
77
78         for (cp = spwbuf, i = 0; ('\0' != *cp) && (i < FIELDS); i++) {
79                 fields[i] = cp;
80                 while (('\0' != *cp) && (':' != *cp)) {
81                         cp++;
82                 }
83
84                 if ('\0' != *cp) {
85                         *cp = '\0';
86                         cp++;
87                 }
88         }
89
90         if (i == (FIELDS - 1)) {
91                 fields[i++] = cp;
92         }
93
94         if ( ((NULL != cp) && ('\0' != *cp)) ||
95              ((i != FIELDS) && (i != OFIELDS)) ) {
96                 return 0;
97         }
98
99         /*
100          * Start populating the structure.  The fields are all in
101          * static storage, as is the structure we pass back.
102          */
103
104         spwd.sp_namp = fields[0];
105         spwd.sp_pwdp = fields[1];
106
107         /*
108          * Get the last changed date.  For all of the integer fields,
109          * we check for proper format.  It is an error to have an
110          * incorrectly formatted number.
111          */
112
113         if (fields[2][0] == '\0') {
114                 spwd.sp_lstchg = -1;
115         } else if (   (getlong (fields[2], &spwd.sp_lstchg) == 0)
116                    || (spwd.sp_lstchg < 0)) {
117                 return 0;
118         }
119
120         /*
121          * Get the minimum period between password changes.
122          */
123
124         if (fields[3][0] == '\0') {
125                 spwd.sp_min = -1;
126         } else if (   (getlong (fields[3], &spwd.sp_min) == 0)
127                    || (spwd.sp_min < 0)) {
128                 return 0;
129         }
130
131         /*
132          * Get the maximum number of days a password is valid.
133          */
134
135         if (fields[4][0] == '\0') {
136                 spwd.sp_max = -1;
137         } else if (   (getlong (fields[4], &spwd.sp_max) == 0)
138                    || (spwd.sp_max < 0)) {
139                 return 0;
140         }
141
142         /*
143          * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
144          * formatted file), initialize the other field members to -1.
145          */
146
147         if (i == OFIELDS) {
148                 spwd.sp_warn   = -1;
149                 spwd.sp_inact  = -1;
150                 spwd.sp_expire = -1;
151                 spwd.sp_flag   = SHADOW_SP_FLAG_UNSET;
152
153                 return &spwd;
154         }
155
156         /*
157          * Get the number of days of password expiry warning.
158          */
159
160         if (fields[5][0] == '\0') {
161                 spwd.sp_warn = -1;
162         } else if (   (getlong (fields[5], &spwd.sp_warn) == 0)
163                    || (spwd.sp_warn < 0)) {
164                 return 0;
165         }
166
167         /*
168          * Get the number of days of inactivity before an account is
169          * disabled.
170          */
171
172         if (fields[6][0] == '\0') {
173                 spwd.sp_inact = -1;
174         } else if (   (getlong (fields[6], &spwd.sp_inact) == 0)
175                    || (spwd.sp_inact < 0)) {
176                 return 0;
177         }
178
179         /*
180          * Get the number of days after the epoch before the account is
181          * set to expire.
182          */
183
184         if (fields[7][0] == '\0') {
185                 spwd.sp_expire = -1;
186         } else if (   (getlong (fields[7], &spwd.sp_expire) == 0)
187                    || (spwd.sp_expire < 0)) {
188                 return 0;
189         }
190
191         /*
192          * This field is reserved for future use.  But it isn't supposed
193          * to have anything other than a valid integer in it.
194          */
195
196         if (fields[8][0] == '\0') {
197                 spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
198         } else if (getlong (fields[8], &spwd.sp_flag) == 0) {
199                 /* FIXME: add a getulong function */
200                 return 0;
201         }
202
203         return (&spwd);
204 }
205 #else
206 extern int errno;               /* warning: ANSI C forbids an empty source file */
207 #endif
208