|
|
@ -19,12 +19,13 @@ const c = @cImport({
|
|
|
|
@cInclude("unistd.h");
|
|
|
|
@cInclude("unistd.h");
|
|
|
|
@cInclude("grp.h");
|
|
|
|
@cInclude("grp.h");
|
|
|
|
@cInclude("crypt.h");
|
|
|
|
@cInclude("crypt.h");
|
|
|
|
|
|
|
|
@cInclude("string.h");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
fn getGroups(alloc: mem.Allocator, passwd: c.passwd) ![]c.gid_t {
|
|
|
|
fn getGroups(alloc: mem.Allocator, passwd: c.passwd) ![]c.gid_t {
|
|
|
|
var ngr: c_int = 0;
|
|
|
|
var ngr: c_int = 0;
|
|
|
|
_ = c.getgrouplist(passwd.pw_name, passwd.pw_gid, null, &ngr);
|
|
|
|
_ = c.getgrouplist(passwd.pw_name, passwd.pw_gid, null, &ngr);
|
|
|
|
const groups = try alloc.alloc(c.gid_t, @intCast(usize, ngr));
|
|
|
|
const groups = try alloc.alloc(c.gid_t, @intCast(ngr));
|
|
|
|
_ = c.getgrouplist(passwd.pw_name, passwd.pw_gid, groups.ptr, &ngr);
|
|
|
|
_ = c.getgrouplist(passwd.pw_name, passwd.pw_gid, groups.ptr, &ngr);
|
|
|
|
return groups;
|
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -32,16 +33,16 @@ fn getGroups(alloc: mem.Allocator, passwd: c.passwd) ![]c.gid_t {
|
|
|
|
pub fn main() !u8 {
|
|
|
|
pub fn main() !u8 {
|
|
|
|
const stderr = io.getStdErr().writer();
|
|
|
|
const stderr = io.getStdErr().writer();
|
|
|
|
if (os.argv.len <= 1) {
|
|
|
|
if (os.argv.len <= 1) {
|
|
|
|
try stderr.print("Not enough arguments\n", .{});
|
|
|
|
try stderr.print("Not enough arguments\n", .{});
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const passwd = c.getpwuid(c.getuid()).*;
|
|
|
|
const passwd = c.getpwuid(c.getuid()).*;
|
|
|
|
|
|
|
|
|
|
|
|
const shadowEntry = c.getspnam(passwd.pw_name);
|
|
|
|
const shadowEntry = c.getspnam(passwd.pw_name);
|
|
|
|
if (shadowEntry == null) {
|
|
|
|
if (shadowEntry == null) {
|
|
|
|
try stderr.print("Missing setuid on binary {s}\n", .{os.argv[0]});
|
|
|
|
try stderr.print("Missing setuid on binary {s}\n", .{os.argv[0]});
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const shadow = shadowEntry.*;
|
|
|
|
const shadow = shadowEntry.*;
|
|
|
|
|
|
|
|
|
|
|
@ -55,18 +56,20 @@ pub fn main() !u8 {
|
|
|
|
const gr = c.getgrgid(gr_id).*;
|
|
|
|
const gr = c.getgrgid(gr_id).*;
|
|
|
|
if (gr.gr_gid == wheel.gr_gid) {
|
|
|
|
if (gr.gr_gid == wheel.gr_gid) {
|
|
|
|
const pass = mem.span(c.getpass("#: "));
|
|
|
|
const pass = mem.span(c.getpass("#: "));
|
|
|
|
if (cstr.cmp(shadow.sp_pwdp, c.crypt(pass, shadow.sp_pwdp)) == 0) {
|
|
|
|
if (c.strcmp(shadow.sp_pwdp, c.crypt(pass, shadow.sp_pwdp)) == 0) {
|
|
|
|
crypto.utils.secureZero(u8, pass);
|
|
|
|
crypto.utils.secureZero(u8, pass);
|
|
|
|
_ = c.setuid(0);
|
|
|
|
_ = c.setuid(0);
|
|
|
|
_ = c.setgid(0);
|
|
|
|
_ = c.setgid(0);
|
|
|
|
|
|
|
|
const rootGroups = try getGroups(gpa, c.getpwuid(0).*);
|
|
|
|
|
|
|
|
_ = c.setgroups(rootGroups.len, rootGroups.ptr);
|
|
|
|
var argl = ArrayList([]const u8).init(gpa);
|
|
|
|
var argl = ArrayList([]const u8).init(gpa);
|
|
|
|
for (os.argv[1..]) |arg| {
|
|
|
|
for (os.argv[1..]) |arg| {
|
|
|
|
try argl.append(mem.span(arg));
|
|
|
|
try argl.append(mem.span(arg));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return process.execv(gpa, try argl.toOwnedSlice());
|
|
|
|
return process.execv(gpa, try argl.toOwnedSlice());
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
try stderr.print("Wrong Password\n", .{});
|
|
|
|
try stderr.print("Wrong Password\n", .{});
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|