bc2184f99cc6257cb4c37b18e4984950aa74116f
[project/luci.git] / libs / nixio / src / user.c
1 /*
2  * nixio - Linux I/O library for lua
3  *
4  *   Copyright (C) 2009 Steven Barth <steven@midlink.org>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  */
18
19 #include "nixio.h"
20 #include <sys/types.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include <sys/param.h>
24
25 #ifndef __WINNT__
26
27 #include <grp.h>
28 #include <pwd.h>
29
30 #ifndef BSD
31 #include <shadow.h>
32 #include <crypt.h>
33 #endif
34
35 int nixio__check_group(lua_State *L, int idx) {
36         if (lua_isnumber(L, idx)) {
37                 return lua_tointeger(L, idx);
38         } else if (lua_isstring(L, idx)) {
39                 struct group *g = getgrnam(lua_tostring(L, idx));
40                 return (!g) ? -1 : g->gr_gid;
41         } else {
42                 return luaL_argerror(L, idx, "supported values: <groupname>, <gid>");
43         }
44 }
45
46 int nixio__check_user(lua_State *L, int idx) {
47         if (lua_isnumber(L, idx)) {
48                 return lua_tointeger(L, idx);
49         } else if (lua_isstring(L, idx)) {
50                 struct passwd *p = getpwnam(lua_tostring(L, idx));
51                 return (!p) ? -1 : p->pw_uid;
52         } else {
53                 return luaL_argerror(L, idx, "supported values: <username>, <uid>");
54         }
55 }
56
57
58 static int nixio__push_group(lua_State *L, struct group *gr) {
59         lua_createtable(L, 0, 4);
60         lua_pushstring(L, gr->gr_name);
61         lua_setfield(L, -2, "name");
62         lua_pushstring(L, gr->gr_passwd);
63         lua_setfield(L, -2, "passwd");
64         lua_pushinteger(L, gr->gr_gid);
65         lua_setfield(L, -2, "gid");
66         lua_newtable(L);
67
68         for (int i=0; gr->gr_mem[i]; i++) {
69                 lua_pushstring(L, gr->gr_mem[i]);
70                 lua_rawseti(L, -2, i+1);
71         }
72
73         lua_setfield(L, -2, "mem");
74         return 1;
75 }
76
77 static int nixio_getgr(lua_State *L) {
78         struct group *gr;
79         errno = 0;
80         if (lua_isnumber(L, 1)) {
81                 gr = getgrgid(lua_tointeger(L, 1));
82         } else if (lua_isstring(L, 1)) {
83                 gr = getgrnam(lua_tostring(L, 1));
84         } else if (lua_isnoneornil(L, 1)) {
85                 lua_newtable(L);
86                 int i = 0;
87
88                 setgrent();
89                 while ((gr = getgrent())) {
90                         nixio__push_group(L, gr);
91                         lua_rawseti(L, -2, ++i);
92                 }
93
94                 if (errno) {
95                         return nixio__perror(L);
96                 }
97
98                 endgrent();
99                 return 1;
100         } else {
101                 return luaL_argerror(L, 1, "supported values: <groupname>, <gid>");
102         }
103
104         if (!gr) {
105                 return nixio__perror(L);
106         } else {
107                 return nixio__push_group(L, gr);
108         }
109 }
110
111 static int nixio__push_passwd(lua_State *L, struct passwd *pw) {
112         lua_createtable(L, 0, 7);
113         lua_pushstring(L, pw->pw_name);
114         lua_setfield(L, -2, "name");
115         lua_pushstring(L, pw->pw_passwd);
116         lua_setfield(L, -2, "passwd");
117         lua_pushinteger(L, pw->pw_gid);
118         lua_setfield(L, -2, "gid");
119         lua_pushinteger(L, pw->pw_uid);
120         lua_setfield(L, -2, "uid");
121         lua_pushstring(L, pw->pw_dir);
122         lua_setfield(L, -2, "dir");
123         lua_pushstring(L, pw->pw_gecos);
124         lua_setfield(L, -2, "gecos");
125         lua_pushstring(L, pw->pw_shell);
126         lua_setfield(L, -2, "shell");
127         return 1;
128 }
129
130 static int nixio_getpw(lua_State *L) {
131         struct passwd *pw;
132         errno = 0;
133         if (lua_isnumber(L, 1)) {
134                 pw = getpwuid(lua_tointeger(L, 1));
135         } else if (lua_isstring(L, 1)) {
136                 pw = getpwnam(lua_tostring(L, 1));
137         } else if (lua_isnoneornil(L, 1)) {
138                 lua_newtable(L);
139                 int i = 0;
140
141                 setpwent();
142                 while ((pw = getpwent())) {
143                         nixio__push_passwd(L, pw);
144                         lua_rawseti(L, -2, ++i);
145                 }
146
147                 if (errno) {
148                         return nixio__perror(L);
149                 }
150
151                 endpwent();
152                 return 1;
153         } else {
154                 return luaL_argerror(L, 1, "supported values: <username>, <uid>");
155         }
156
157         if (!pw) {
158                 return nixio__perror(L);
159         } else {
160                 return nixio__push_passwd(L, pw);
161         }
162 }
163
164 #ifndef BSD
165 static int nixio__push_spwd(lua_State *L, struct spwd *sp) {
166         lua_createtable(L, 0, 9);
167         lua_pushstring(L, sp->sp_namp);
168         lua_setfield(L, -2, "namp");
169         lua_pushinteger(L, sp->sp_expire);
170         lua_setfield(L, -2, "expire");
171         lua_pushinteger(L, sp->sp_flag);
172         lua_setfield(L, -2, "flag");
173         lua_pushinteger(L, sp->sp_inact);
174         lua_setfield(L, -2, "inact");
175         lua_pushinteger(L, sp->sp_lstchg);
176         lua_setfield(L, -2, "lstchg");
177         lua_pushinteger(L, sp->sp_max);
178         lua_setfield(L, -2, "max");
179         lua_pushinteger(L, sp->sp_min);
180         lua_setfield(L, -2, "min");
181         lua_pushinteger(L, sp->sp_warn);
182         lua_setfield(L, -2, "warn");
183         lua_pushstring(L, sp->sp_pwdp);
184         lua_setfield(L, -2, "pwdp");
185         return 1;
186 }
187
188 static int nixio_getsp(lua_State *L) {
189         struct spwd *sp;
190         errno = 0;
191         if (lua_isstring(L, 1)) {
192                 sp = getspnam(lua_tostring(L, 1));
193         } else if (lua_isnoneornil(L, 1)) {
194                 lua_newtable(L);
195                 int i = 0;
196
197                 setspent();
198                 while ((sp = getspent())) {
199                         nixio__push_spwd(L, sp);
200                         lua_rawseti(L, -2, ++i);
201                 }
202
203                 if (errno) {
204                         return nixio__perror(L);
205                 }
206
207                 endspent();
208                 return 1;
209         } else {
210                 return luaL_argerror(L, 1, "supported values: <username>");
211         }
212
213         if (!sp) {
214                 return nixio__perror(L);
215         } else {
216                 return nixio__push_spwd(L, sp);
217         }
218 }
219 #endif /* !BSD */
220
221 static int nixio_crypt(lua_State *L) {
222         const char *key = luaL_checkstring(L, 1);
223         const char *salt = luaL_checkstring(L, 2);
224         const char *hash = crypt(key, salt);
225
226         if (hash) {
227                 lua_pushstring(L, hash);
228         } else {
229                 lua_pushnil(L);
230         }
231
232         return 1;
233 }
234
235
236 /* module table */
237 static const luaL_reg R[] = {
238         {"crypt",               nixio_crypt},
239         {"getgr",               nixio_getgr},
240         {"getpw",               nixio_getpw},
241 #ifndef BSD
242         {"getsp",               nixio_getsp},
243 #endif
244         {NULL,                  NULL}
245 };
246
247 #else /* __WINNT__ */
248
249 static const luaL_reg R[] = {
250                 {NULL,                  NULL}
251 };
252
253 #endif
254
255 void nixio_open_user(lua_State *L) {
256         luaL_register(L, NULL, R);
257 }