Merge pull request #429 from chris5560/master
[project/luci.git] / libs / luci-lib-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 #ifndef NO_SHADOW
32 #include <shadow.h>
33 #endif
34 #include <crypt.h>
35 #endif
36
37 int nixio__check_group(lua_State *L, int idx) {
38         if (lua_isnumber(L, idx)) {
39                 return lua_tointeger(L, idx);
40         } else if (lua_isstring(L, idx)) {
41                 struct group *g = getgrnam(lua_tostring(L, idx));
42                 return (!g) ? -1 : g->gr_gid;
43         } else {
44                 return luaL_argerror(L, idx, "supported values: <groupname>, <gid>");
45         }
46 }
47
48 int nixio__check_user(lua_State *L, int idx) {
49         if (lua_isnumber(L, idx)) {
50                 return lua_tointeger(L, idx);
51         } else if (lua_isstring(L, idx)) {
52                 struct passwd *p = getpwnam(lua_tostring(L, idx));
53                 return (!p) ? -1 : p->pw_uid;
54         } else {
55                 return luaL_argerror(L, idx, "supported values: <username>, <uid>");
56         }
57 }
58
59
60 static int nixio__push_group(lua_State *L, struct group *gr) {
61         lua_createtable(L, 0, 4);
62         lua_pushstring(L, gr->gr_name);
63         lua_setfield(L, -2, "name");
64         lua_pushstring(L, gr->gr_passwd);
65         lua_setfield(L, -2, "passwd");
66         lua_pushinteger(L, gr->gr_gid);
67         lua_setfield(L, -2, "gid");
68         lua_newtable(L);
69
70         for (int i=0; gr->gr_mem[i]; i++) {
71                 lua_pushstring(L, gr->gr_mem[i]);
72                 lua_rawseti(L, -2, i+1);
73         }
74
75         lua_setfield(L, -2, "mem");
76         return 1;
77 }
78
79 static int nixio_getgr(lua_State *L) {
80         struct group *gr;
81         errno = 0;
82         if (lua_isnumber(L, 1)) {
83                 gr = getgrgid(lua_tointeger(L, 1));
84         } else if (lua_isstring(L, 1)) {
85                 gr = getgrnam(lua_tostring(L, 1));
86         } else if (lua_isnoneornil(L, 1)) {
87                 lua_newtable(L);
88                 int i = 0;
89
90                 setgrent();
91                 while ((gr = getgrent())) {
92                         nixio__push_group(L, gr);
93                         lua_rawseti(L, -2, ++i);
94                 }
95
96                 if (errno) {
97                         return nixio__perror(L);
98                 }
99
100                 endgrent();
101                 return 1;
102         } else {
103                 return luaL_argerror(L, 1, "supported values: <groupname>, <gid>");
104         }
105
106         if (!gr) {
107                 return nixio__perror(L);
108         } else {
109                 return nixio__push_group(L, gr);
110         }
111 }
112
113 static int nixio__push_passwd(lua_State *L, struct passwd *pw) {
114         lua_createtable(L, 0, 7);
115         lua_pushstring(L, pw->pw_name);
116         lua_setfield(L, -2, "name");
117         lua_pushstring(L, pw->pw_passwd);
118         lua_setfield(L, -2, "passwd");
119         lua_pushinteger(L, pw->pw_gid);
120         lua_setfield(L, -2, "gid");
121         lua_pushinteger(L, pw->pw_uid);
122         lua_setfield(L, -2, "uid");
123         lua_pushstring(L, pw->pw_dir);
124         lua_setfield(L, -2, "dir");
125         lua_pushstring(L, pw->pw_gecos);
126         lua_setfield(L, -2, "gecos");
127         lua_pushstring(L, pw->pw_shell);
128         lua_setfield(L, -2, "shell");
129         return 1;
130 }
131
132 static int nixio_getpw(lua_State *L) {
133         struct passwd *pw;
134         errno = 0;
135         if (lua_isnumber(L, 1)) {
136                 pw = getpwuid(lua_tointeger(L, 1));
137         } else if (lua_isstring(L, 1)) {
138                 pw = getpwnam(lua_tostring(L, 1));
139         } else if (lua_isnoneornil(L, 1)) {
140                 lua_newtable(L);
141                 int i = 0;
142
143                 setpwent();
144                 while ((pw = getpwent())) {
145                         nixio__push_passwd(L, pw);
146                         lua_rawseti(L, -2, ++i);
147                 }
148
149                 if (errno) {
150                         return nixio__perror(L);
151                 }
152
153                 endpwent();
154                 return 1;
155         } else {
156                 return luaL_argerror(L, 1, "supported values: <username>, <uid>");
157         }
158
159         if (!pw) {
160                 return nixio__perror(L);
161         } else {
162                 return nixio__push_passwd(L, pw);
163         }
164 }
165
166 #ifndef BSD
167 #ifndef NO_SHADOW
168 static int nixio__push_spwd(lua_State *L, struct spwd *sp) {
169         lua_createtable(L, 0, 9);
170         lua_pushstring(L, sp->sp_namp);
171         lua_setfield(L, -2, "namp");
172         lua_pushinteger(L, sp->sp_expire);
173         lua_setfield(L, -2, "expire");
174         lua_pushinteger(L, sp->sp_flag);
175         lua_setfield(L, -2, "flag");
176         lua_pushinteger(L, sp->sp_inact);
177         lua_setfield(L, -2, "inact");
178         lua_pushinteger(L, sp->sp_lstchg);
179         lua_setfield(L, -2, "lstchg");
180         lua_pushinteger(L, sp->sp_max);
181         lua_setfield(L, -2, "max");
182         lua_pushinteger(L, sp->sp_min);
183         lua_setfield(L, -2, "min");
184         lua_pushinteger(L, sp->sp_warn);
185         lua_setfield(L, -2, "warn");
186         lua_pushstring(L, sp->sp_pwdp);
187         lua_setfield(L, -2, "pwdp");
188         return 1;
189 }
190
191 static int nixio_getsp(lua_State *L) {
192         struct spwd *sp;
193         errno = 0;
194         if (lua_isstring(L, 1)) {
195                 sp = getspnam(lua_tostring(L, 1));
196         } else if (lua_isnoneornil(L, 1)) {
197                 lua_newtable(L);
198                 int i = 0;
199
200                 setspent();
201                 while ((sp = getspent())) {
202                         nixio__push_spwd(L, sp);
203                         lua_rawseti(L, -2, ++i);
204                 }
205
206                 if (errno) {
207                         return nixio__perror(L);
208                 }
209
210                 endspent();
211                 return 1;
212         } else {
213                 return luaL_argerror(L, 1, "supported values: <username>");
214         }
215
216         if (!sp) {
217                 return nixio__perror(L);
218         } else {
219                 return nixio__push_spwd(L, sp);
220         }
221 }
222 #endif /* !NO_SHADOW */
223 #endif /* !BSD */
224
225 static int nixio_crypt(lua_State *L) {
226         const char *key = luaL_checkstring(L, 1);
227         const char *salt = luaL_checkstring(L, 2);
228         const char *hash = crypt(key, salt);
229
230         if (hash) {
231                 lua_pushstring(L, hash);
232         } else {
233                 lua_pushnil(L);
234         }
235
236         return 1;
237 }
238
239
240 /* module table */
241 static const luaL_reg R[] = {
242         {"crypt",               nixio_crypt},
243         {"getgr",               nixio_getgr},
244         {"getpw",               nixio_getpw},
245 #ifndef BSD
246 #ifndef NO_SHADOW
247         {"getsp",               nixio_getsp},
248 #endif
249 #endif
250         {NULL,                  NULL}
251 };
252
253 #else /* __WINNT__ */
254
255 static const luaL_reg R[] = {
256                 {NULL,                  NULL}
257 };
258
259 #endif
260
261 void nixio_open_user(lua_State *L) {
262         luaL_register(L, NULL, R);
263 }