Skip to content

Commit

Permalink
Merge pull request #113 from TitanSnow/root
Browse files Browse the repository at this point in the history
privilege manage (escalation & degradation) when running as root
(cherry picked from commit ffa5787)
  • Loading branch information
waruqi committed May 23, 2017
1 parent 08a7802 commit f24069b
Show file tree
Hide file tree
Showing 11 changed files with 499 additions and 19 deletions.
4 changes: 4 additions & 0 deletions core/src/xmake/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ tb_int_t xm_os_getwinsize(lua_State* lua);
tb_int_t xm_os_versioninfo(lua_State* lua);
#ifndef TB_CONFIG_OS_WINDOWS
tb_int_t xm_os_uid(lua_State* lua);
tb_int_t xm_os_gid(lua_State* lua);
tb_int_t xm_os_getown(lua_State* lua);
#endif

// the path functions
Expand Down Expand Up @@ -155,6 +157,8 @@ static luaL_Reg const g_os_functions[] =
, { "versioninfo", xm_os_versioninfo}
#ifndef TB_CONFIG_OS_WINDOWS
, { "uid", xm_os_uid }
, { "gid", xm_os_gid }
, { "getown", xm_os_getown }
#endif
, { tb_null, tb_null }
};
Expand Down
2 changes: 2 additions & 0 deletions core/src/xmake/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ xmake_C_FILES += \
os/getwinsize \
os/versioninfo \
os/uid \
os/gid \
os/getown \
path/relative \
path/absolute \
path/translate \
Expand Down
71 changes: 71 additions & 0 deletions core/src/xmake/os/getown.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*!The Make-like Build Utility based on Lua
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (C) 2015 - 2017, TBOOX Open Source Group.
*
* @author TitanSnow
* @file getown.c
*
*/

/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
#define TB_TRACE_MODULE_NAME "getown"
#define TB_TRACE_MODULE_DEBUG (0)

/* //////////////////////////////////////////////////////////////////////////////////////
* includes
*/
#include "prefix.h"
#ifndef TB_CONFIG_OS_WINDOWS
# include <unistd.h>
# include <sys/stat.h>

/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
// get owner by a given path
tb_int_t xm_os_getown(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);

// get the pathname
tb_char_t const* pathname = luaL_checkstring(lua, 1);
tb_check_return_val(pathname, 0);

// get stat
struct stat sts;
if(stat(pathname, &sts) != 0)
return 0;

// push
lua_newtable(lua);
lua_pushstring(lua, "uid");
lua_pushinteger(lua, sts.st_uid);
lua_settable(lua, -3);
lua_pushstring(lua, "gid");
lua_pushinteger(lua, sts.st_gid);
lua_settable(lua, -3);

// ok
return 1;
}

#endif
149 changes: 149 additions & 0 deletions core/src/xmake/os/gid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*!The Make-like Build Utility based on Lua
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (C) 2015 - 2017, TBOOX Open Source Group.
*
* @author TitanSnow
* @file gid.c
*
*/

/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
#define TB_TRACE_MODULE_NAME "gid"
#define TB_TRACE_MODULE_DEBUG (0)

/* //////////////////////////////////////////////////////////////////////////////////////
* includes
*/
#include "prefix.h"
#ifndef TB_CONFIG_OS_WINDOWS
# include <unistd.h>
# include <errno.h>

/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/

// get & set gid
tb_int_t xm_os_gid(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);

tb_int_t rgidset = -1, egidset = -1;

tb_int_t argc = lua_gettop(lua);

if (argc == 1)
{
if (lua_istable(lua, 1))
{
// os.gid({["rgid"] = rgid, ["egid"] = egid})
lua_getfield(lua, 1, "rgid");
lua_getfield(lua, 1, "egid");
if (!lua_isnil(lua, -1))
{
if (!lua_isnumber(lua, -1))
{
lua_pushfstring(lua, "invalid field type(%s) in `egid` for os.gid", luaL_typename(lua, -1));
lua_error(lua);
return 0;
}
egidset = (tb_int_t)lua_tonumber(lua, -1);
}
lua_pop(lua, 1);
if (!lua_isnil(lua, -1))
{
if (!lua_isnumber(lua, -1))
{
lua_pushfstring(lua, "invalid field type(%s) in `rgid` for os.gid", luaL_typename(lua, -1));
lua_error(lua);
return 0;
}
rgidset = (tb_int_t)lua_tonumber(lua, -1);
}
lua_pop(lua, 1);
} else if (lua_isnumber(lua, 1))
{
// os.gid(gid)
rgidset = egidset = (tb_int_t)lua_tonumber(lua, 1);
} else
{
lua_pushfstring(lua, "invalid argument type(%s) for os.gid", luaL_typename(lua, 1));
lua_error(lua);
return 0;
}
} else if (argc == 2)
{
// os.gid(rgid, egid)
if (!lua_isnil(lua, 1))
{
if (!lua_isnumber(lua, 1))
{
lua_pushfstring(lua, "invalid argument type(%s) for os.gid", luaL_typename(lua, 1));
lua_error(lua);
return 0;
}
rgidset = (tb_int_t)lua_tonumber(lua, 1);
}
if (!lua_isnil(lua, 2))
{
if (!lua_isnumber(lua, 2))
{
lua_pushfstring(lua, "invalid argument type(%s) for os.gid", luaL_typename(lua, 2));
lua_error(lua);
return 0;
}
egidset = (tb_int_t)lua_tonumber(lua, 2);
}
} else if (argc != 0)
{
lua_pushstring(lua, "invalid argument count for os.gid");
lua_error(lua);
return 0;
}

// store return value
lua_newtable(lua);

if (rgidset != -1 || egidset != -1)
{
// set rgid & egid
lua_pushstring(lua, "errno");
lua_pushinteger(lua, setregid(rgidset, egidset) != 0 ? errno : 0);
lua_settable(lua, -3);
}

// get gid & egid
gid_t gid = getgid(), egid = getegid();

// push
lua_pushstring(lua, "rgid");
lua_pushinteger(lua, gid);
lua_settable(lua, -3);
lua_pushstring(lua, "egid");
lua_pushinteger(lua, egid);
lua_settable(lua, -3);

// ok
return 1;
}

#endif
90 changes: 87 additions & 3 deletions core/src/xmake/os/uid.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,107 @@
#include "prefix.h"
#ifndef TB_CONFIG_OS_WINDOWS
# include <unistd.h>
# include <errno.h>

/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/

// get uid & euid
// get & set uid
tb_int_t xm_os_uid(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);

tb_int_t ruidset = -1, euidset = -1;

tb_int_t argc = lua_gettop(lua);

if (argc == 1)
{
if (lua_istable(lua, 1))
{
// os.uid({["ruid"] = ruid, ["euid"] = euid})
lua_getfield(lua, 1, "ruid");
lua_getfield(lua, 1, "euid");
if (!lua_isnil(lua, -1))
{
if (!lua_isnumber(lua, -1))
{
lua_pushfstring(lua, "invalid field type(%s) in `euid` for os.uid", luaL_typename(lua, -1));
lua_error(lua);
return 0;
}
euidset = (tb_int_t)lua_tonumber(lua, -1);
}
lua_pop(lua, 1);
if (!lua_isnil(lua, -1))
{
if (!lua_isnumber(lua, -1))
{
lua_pushfstring(lua, "invalid field type(%s) in `ruid` for os.uid", luaL_typename(lua, -1));
lua_error(lua);
return 0;
}
ruidset = (tb_int_t)lua_tonumber(lua, -1);
}
lua_pop(lua, 1);
} else if (lua_isnumber(lua, 1))
{
// os.uid(uid)
ruidset = euidset = (tb_int_t)lua_tonumber(lua, 1);
} else
{
lua_pushfstring(lua, "invalid argument type(%s) for os.uid", luaL_typename(lua, 1));
lua_error(lua);
return 0;
}
} else if (argc == 2)
{
// os.uid(ruid, euid)
if (!lua_isnil(lua, 1))
{
if (!lua_isnumber(lua, 1))
{
lua_pushfstring(lua, "invalid argument type(%s) for os.uid", luaL_typename(lua, 1));
lua_error(lua);
return 0;
}
ruidset = (tb_int_t)lua_tonumber(lua, 1);
}
if (!lua_isnil(lua, 2))
{
if (!lua_isnumber(lua, 2))
{
lua_pushfstring(lua, "invalid argument type(%s) for os.uid", luaL_typename(lua, 2));
lua_error(lua);
return 0;
}
euidset = (tb_int_t)lua_tonumber(lua, 2);
}
} else if (argc != 0)
{
lua_pushstring(lua, "invalid argument count for os.uid");
lua_error(lua);
return 0;
}

// store return value
lua_newtable(lua);

if (ruidset != -1 || euidset != -1)
{
// set ruid & euid
lua_pushstring(lua, "errno");
lua_pushinteger(lua, setreuid(ruidset, euidset) != 0 ? errno : 0);
lua_settable(lua, -3);
}

// get uid & euid
uid_t uid = getuid(), euid = geteuid();

// push
lua_newtable(lua);
lua_pushstring(lua, "uid");
lua_pushstring(lua, "ruid");
lua_pushinteger(lua, uid);
lua_settable(lua, -3);
lua_pushstring(lua, "euid");
Expand Down
23 changes: 23 additions & 0 deletions xmake/actions/install/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import("core.base.option")
import("core.project.task")
import("core.platform.platform")
import("core.base.privilege")
import("install")

-- main
Expand Down Expand Up @@ -57,6 +58,28 @@ function main()
-- failed or not permission? request administrator permission and install it again
function (errors)

-- try get privilege
if privilege.get() then
local ok = try
{
function ()
-- install target
install.install(targetname or ifelse(option.get("all"), "__all", "__def"))

-- trace
cprint("${bright}install ok!${clear}${ok_hand}")

-- ok
return true
end
}

-- release privilege
privilege.store()

if ok then return end
end

-- show tips
cprint("${bright red}error: ${clear}installation failed, may permission denied!")

Expand Down
Loading

0 comments on commit f24069b

Please sign in to comment.