mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 03:33:42 +00:00
Feature: uid support in run_as
This commit is contained in:
+25
-2
@@ -28,6 +28,7 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#ifndef __MINGW32__
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@@ -86,6 +87,15 @@ ss_itoa(int i)
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
ss_isnumeric(const char *s) {
|
||||
if (!s || !*s)
|
||||
return 0;
|
||||
while (isdigit(*s))
|
||||
++s;
|
||||
return *s == '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* setuid() and setgid() for a specified user.
|
||||
*/
|
||||
@@ -94,6 +104,18 @@ run_as(const char *user)
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
if (user[0]) {
|
||||
printf("user: %s\n", user);
|
||||
/* Convert user to a long integer if it is a non-negative number.
|
||||
* -1 means it is a user name. */
|
||||
long uid = -1;
|
||||
if (ss_isnumeric(user)) {
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
uid = strtol(user, &endptr, 10);
|
||||
if (errno || endptr == user)
|
||||
uid = -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETPWNAM_R
|
||||
struct passwd pwdbuf, *pwd;
|
||||
size_t buflen;
|
||||
@@ -105,7 +127,8 @@ run_as(const char *user)
|
||||
/* Note that we use getpwnam_r() instead of getpwnam(),
|
||||
* which returns its result in a statically allocated buffer and
|
||||
* cannot be considered thread safe. */
|
||||
err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd);
|
||||
err = uid >= 0 ? getpwuid_r((uid_t)uid, &pwdbuf, buf, buflen, &pwd)
|
||||
: getpwnam_r(user, &pwdbuf, buf, buflen, &pwd);
|
||||
|
||||
if (err == 0 && pwd) {
|
||||
/* setgid first, because we may not be allowed to do it anymore after setuid */
|
||||
@@ -145,7 +168,7 @@ run_as(const char *user)
|
||||
/* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */
|
||||
struct passwd *pwd;
|
||||
|
||||
if (!(pwd = getpwnam(user))) {
|
||||
if (!(pwd = uid >=0 ? getpwuid((uid_t)uid) : getpwnam(user))) {
|
||||
LOGE("run_as user %s could not be found.", user);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -209,6 +209,7 @@ void ERROR(const char *s);
|
||||
#endif
|
||||
|
||||
char *ss_itoa(int i);
|
||||
int ss_isnumeric(const char *s);
|
||||
int run_as(const char *user);
|
||||
void FATAL(const char *msg);
|
||||
void usage(void);
|
||||
|
||||
Reference in New Issue
Block a user