Adding signature checking
[platform/core/system/tizen-platform-wrapper.git] / src / passwd.c
1 /*
2  * Copyright (C) 2013-2014 Intel Corporation.
3  * 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors:
19  *   José Bollo <jose.bollo@open.eurogiciel.org>
20  *   Stéphane Desneux <stephane.desneux@open.eurogiciel.org>
21  *   Jean-Benoit Martin <jean-benoit.martin@open.eurogiciel.org>
22  *
23  */
24 #define _GNU_SOURCE
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <errno.h>
34
35 #include "heap.h"
36 #include "passwd.h"
37
38 #ifndef NOT_PASSWD_ONLY
39
40 #include "buffer.h"
41
42 /* index of fields */
43 enum { iname, ipasswd, iuid, igid, icmt, idir, ishell };
44
45 static const char pwfile[] = "/etc/passwd";
46 static struct buffer buffer;
47 static size_t pos, lengths[7];
48 static const char *starts[7];
49
50 #define is(s,i) (!strncmp(s,starts[i],lengths[i]) && !s[lengths[i]])
51
52 /* open the passwd file */
53 static int oppw()
54 {
55     pos = 0;
56     return buffer_create( &buffer, pwfile);
57 }
58
59 /* close the passwd file */
60 static void clpw()
61 {
62     buffer_destroy( &buffer);
63 }
64
65 /* read the passwd file */
66 static int rdpw()
67 {
68     int col = 0;
69     const char *head = buffer.buffer + pos;
70     const char *end = buffer.buffer + buffer.length;
71     while (head != end) {
72         starts[col] = head;
73         while(head!=end && *head!=':' && *head!='\n') head++;
74         lengths[col] = head - starts[col];
75         col++;
76         if (col == 7) {
77             if (head==end) {
78                 pos = head - buffer.buffer;
79                 return 1;
80             }
81             if (*head=='\n') {
82                 head++;
83                 pos = head - buffer.buffer;
84                 return 1;
85             }
86             while (head!=end && *head!='\n') head++;
87             if (head!=end) head++;
88             col = 0;
89         }
90         else {
91             if (head != end) {
92                 if (*head++=='\n') 
93                     col = 0;
94             }
95         }
96     }
97     pos = head - buffer.buffer;
98     return 0;
99 }
100
101 int pw_get( struct heap *heap, struct pwget **items)
102 {
103     size_t user, home;
104     int result;
105     int i, n, s;
106
107     for( n = 0 ; items[n] != NULL ; n++ )
108         items[n]->set = 0;
109
110     result = oppw();
111     if (result == 0) {
112         s = n;
113         while (s && rdpw()) {
114             user = home = HNULL;
115             for( i = 0 ; i < n ; i++ ) {
116                 if (!items[i]->set && is(items[i]->id,iuid)) {
117                     if (user==HNULL) {
118                         user = heap_strndup( heap,
119                                             starts[iname], lengths[iname]);
120                         home = heap_strndup( heap,
121                                             starts[idir], lengths[idir]);
122                     }
123                     items[i]->set = 1;
124                     items[i]->user = user;
125                     items[i]->home = home;
126                     s--;
127                 }
128             }
129         }
130         clpw();
131     }
132     return result;
133 }
134
135 int pw_has_uid( uid_t uid)
136 {
137     if (oppw() == 0) {
138         while (rdpw()) {
139             if (lengths[iuid] && (int)uid == atoi(starts[iuid])) {
140                 clpw();
141                 return 1;
142             }
143         }
144         clpw();
145     }
146     return 0;
147 }
148
149 int pw_get_uid( const char *name, uid_t *uid)
150 {
151     int result = oppw();
152     if (result == 0) {
153         while (rdpw()) {
154             if (is(name,iname)) {
155                 *uid = (uid_t)atoi(starts[iuid]);
156                 clpw();
157                 return 0;
158             }
159         }
160         clpw();
161         result = -1;
162         errno = EEXIST;
163     }
164     return result;
165 }
166
167 int pw_get_gid( const char *name, gid_t *gid)
168 {
169     int result = oppw();
170     if (result == 0) {
171         while (rdpw()) {
172             if (is(name,iname)) {
173                 *gid = (gid_t)atoi(starts[igid]);
174                 clpw();
175                 return 0;
176             }
177         }
178         clpw();
179         result = -1;
180         errno = EEXIST;
181     }
182     return result;
183 }
184
185 #else
186
187 #include <pwd.h>
188
189 #define BUFSIZE  4096
190
191 int pw_get( struct heap *heap, struct pwget **items)
192 {
193     char buffer[BUFSIZE];
194     struct passwd entry, *pe;
195     int result;
196     int n;
197     uid_t id;
198
199     for( n = 0 ; items[n] != NULL ; n++ ) {
200         id = (uid_t)atoi(items[n]->id);
201         result = getpwuid_r( id, &entry, buffer, sizeof buffer, &pe);
202         if (result != 0) {
203             while(items[n] != NULL) items[n++]->set = 0;
204             return result;
205         }
206         if (pe == NULL) 
207             items[n]->set = 0;
208         else {
209             items[n]->set = 1;
210             items[n]->user = heap_strdup( heap, pe->pw_name);
211             items[n]->home = heap_strdup( heap, pe->pw_dir);
212         }
213     }
214     return 0;
215 }
216
217 int pw_has_uid( uid_t uid)
218 {
219     char buffer[BUFSIZE];
220     struct passwd entry, *pe;
221     int result;
222
223     result = getpwuid_r( uid, &entry, buffer, sizeof buffer, &pe);
224     return !result && pe;
225 }
226
227 int pw_get_uid( const char *name, uid_t *uid)
228 {
229     char buffer[BUFSIZE];
230     struct passwd entry, *pe;
231     int result = getpwnam_r( name, &entry, buffer, sizeof buffer, &pe);
232     if (result == 0) {
233         if (pe == NULL) {
234             errno = EEXIST;
235             result = -1;
236         }
237         else {
238             *uid = entry.pw_uid;
239         }
240     }
241     return result;
242 }
243
244 int pw_get_gid( const char *name, gid_t *gid)
245 {
246     char buffer[BUFSIZE];
247     struct passwd entry, *pe;
248     int result = getpwnam_r( name, &entry, buffer, sizeof buffer, &pe);
249     if (result == 0) {
250         if (pe == NULL) {
251             errno = EEXIST;
252             result = -1;
253         }
254         else {
255             *gid = entry.pw_gid;
256         }
257     }
258     return result;
259 }
260
261 #endif
262
263 #ifdef TEST_PASSWD
264 #include <stdio.h>
265 int main(int argc,char**argv) {
266     struct heap heap;
267     enum { uid, gid, names } action = uid;
268     heap_create(&heap,1000);
269     while(*++argv) {
270         if (!strcmp(*argv,"-u"))
271             action = uid;
272         else if (!strcmp(*argv,"-g"))
273             action = gid;
274         else if (!strcmp(*argv,"-n"))
275             action = names;
276         else if (action == uid) {
277             uid_t u = 0;
278             int sts = pw_get_uid( *argv, &u);
279             printf("uid(%s)=%d [%d]\n",*argv,(int)u,sts);
280         }
281         else if (action == gid) {
282             gid_t g = 0;
283             int sts = pw_get_gid( *argv, &g);
284             printf("gid(%s)=%d [%d]\n",*argv,(int)g,sts);
285         }
286         else if (action == names) {
287             struct pwget pw = { .id=*argv }, *ppw[2] = { &pw, NULL };
288             int sts = pw_get( &heap, ppw);
289             printf("names(%s) set=%d",*argv,pw.set);
290             if (pw.set) {
291                 printf(" name=%s home=%s",
292                     pw.user==HNULL ? "(null)" 
293                                     : (char*)heap_address( &heap, pw.user),
294                     pw.home==HNULL ? "(null)" 
295                                     : (char*)heap_address( &heap, pw.home));
296             }
297             printf(" [%d]\n",sts);
298         }
299     }
300     return 0;
301 }
302 #endif
303
304