| 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 | } |
|---|