Mercurial > dropbear
comparison svr-auth.c @ 1537:6a83b1944432
Fix restricted group code for BSDs, move to separate function
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 26 Feb 2018 21:17:13 +0800 |
parents | ed930fd6f60f |
children | f20038b513a5 |
comparison
equal
deleted
inserted
replaced
1536:a55a6901a181 | 1537:6a83b1944432 |
---|---|
224 m_free(username); | 224 m_free(username); |
225 m_free(servicename); | 225 m_free(servicename); |
226 m_free(methodname); | 226 m_free(methodname); |
227 } | 227 } |
228 | 228 |
229 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | |
230 static int check_group_membership(gid_t check_gid, const char* username, gid_t user_gid) { | |
231 int ngroups, i, ret; | |
232 gid_t *grouplist = NULL; | |
233 int match = DROPBEAR_FAILURE; | |
234 | |
235 for (ngroups = 32; ngroups <= DROPBEAR_NGROUP_MAX; ngroups *= 2) { | |
236 grouplist = m_malloc(sizeof(gid_t) * ngroups); | |
237 | |
238 /* BSD returns ret==0 on success. Linux returns ret==ngroups on success */ | |
239 ret = getgrouplist(username, user_gid, grouplist, &ngroups); | |
240 if (ret >= 0) { | |
241 break; | |
242 } | |
243 m_free(grouplist); | |
244 grouplist = NULL; | |
245 } | |
246 | |
247 if (!grouplist) { | |
248 dropbear_log(LOG_ERR, "Too many groups for user '%s'", username); | |
249 return DROPBEAR_FAILURE; | |
250 } | |
251 | |
252 for (i = 0; i < ngroups; i++) { | |
253 if (grouplist[i] == check_gid) { | |
254 match = DROPBEAR_SUCCESS; | |
255 break; | |
256 } | |
257 } | |
258 m_free(grouplist); | |
259 | |
260 return match; | |
261 } | |
262 | |
229 | 263 |
230 /* Check that the username exists and isn't disallowed (root), and has a valid shell. | 264 /* Check that the username exists and isn't disallowed (root), and has a valid shell. |
231 * returns DROPBEAR_SUCCESS on valid username, DROPBEAR_FAILURE on failure */ | 265 * returns DROPBEAR_SUCCESS on valid username, DROPBEAR_FAILURE on failure */ |
232 static int checkusername(char *username, unsigned int userlen) { | 266 static int checkusername(char *username, unsigned int userlen) { |
233 | 267 |
234 char* listshell = NULL; | 268 char* listshell = NULL; |
235 char* usershell = NULL; | 269 char* usershell = NULL; |
236 uid_t uid; | 270 uid_t uid; |
237 int ngroups = 32, ret; | |
238 gid_t *grouplist; | |
239 | |
240 | 271 |
241 TRACE(("enter checkusername")) | 272 TRACE(("enter checkusername")) |
242 if (userlen > MAX_USERNAME_LEN) { | 273 if (userlen > MAX_USERNAME_LEN) { |
243 return DROPBEAR_FAILURE; | 274 return DROPBEAR_FAILURE; |
244 } | 275 } |
282 TRACE(("leave checkusername: root login disabled")) | 313 TRACE(("leave checkusername: root login disabled")) |
283 dropbear_log(LOG_WARNING, "root login rejected"); | 314 dropbear_log(LOG_WARNING, "root login rejected"); |
284 return DROPBEAR_FAILURE; | 315 return DROPBEAR_FAILURE; |
285 } | 316 } |
286 | 317 |
287 /* check for login restricted to certain group if desired */ | 318 /* check for login restricted to certain group if desired */ |
288 if (svr_opts.grouploginid) { | 319 if (svr_opts.restrict_group) { |
289 | 320 if (check_group_membership(svr_opts.restrict_group_gid, |
290 for ( ; (ngroups <= NGROUPS_MAX) && (ngroups <= INT_MAX / 8); ngroups *= 2){ | 321 ses.authstate.pw_name, ses.authstate.pw_gid) == DROPBEAR_FAILURE) { |
291 | 322 dropbear_log(LOG_WARNING, |
292 grouplist = malloc(sizeof(gid_t) * ngroups); | 323 "Logins are restricted to the group %s but user '%s' is not a member", |
293 | 324 svr_opts.restrict_group, ses.authstate.pw_name); |
294 ret = getgrouplist(ses.authstate.pw_name, ses.authstate.pw_gid, grouplist, &ngroups); | 325 return DROPBEAR_FAILURE; |
295 | 326 } |
296 if (ret != -1){ | 327 } |
297 break; | |
298 } | |
299 | |
300 free(grouplist); | |
301 ngroups *= 2; | |
302 } | |
303 | |
304 if ((ngroups > NGROUPS_MAX / 8) || (ngroups > INT_MAX / 8)){ | |
305 | |
306 TRACE(("Cannot walk group structure for current user, too many groups")) | |
307 dropbear_log(LOG_ERR, "Cannot walk group structure for current user, too many groups"); | |
308 return DROPBEAR_FAILURE; | |
309 } | |
310 | |
311 ngroups = 0; | |
312 for (int i = 0; i < ret; i++){ | |
313 if (grouplist[i] == *svr_opts.grouploginid){ | |
314 ngroups = 1; //Just used as a flag to indicate success; | |
315 break; | |
316 } | |
317 | |
318 } | |
319 | |
320 if (!ngroups){ | |
321 TRACE(("leave checkusername: user not in permitted group")) | |
322 dropbear_log(LOG_WARNING, "logins are restricted to the group %s but user %s is not a member", svr_opts.grouploginname, ses.authstate.pw_name); | |
323 return DROPBEAR_FAILURE; | |
324 } | |
325 } | |
326 | 328 |
327 TRACE(("shell is %s", ses.authstate.pw_shell)) | 329 TRACE(("shell is %s", ses.authstate.pw_shell)) |
328 | 330 |
329 /* check that the shell is set */ | 331 /* check that the shell is set */ |
330 usershell = ses.authstate.pw_shell; | 332 usershell = ses.authstate.pw_shell; |