1
Fork 0

wip: getgrnam_r and getgrgid_r

main
Motiejus Jakštys 2022-07-07 06:54:27 +03:00
parent 1995da9a77
commit 5f49a9f881
2 changed files with 79 additions and 11 deletions

View File

@ -321,7 +321,7 @@ fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall
}
// get a CGroup entry by name.
fn getgrnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSmall}!?CGroup {
pub fn getgrnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSmall}!?CGroup {
const idx = bdz.search(self.bdz_groupname, name);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_groupname2group[idx];
@ -332,7 +332,7 @@ fn getgrnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSmall}!
}
// get a CGroup entry by it's gid.
fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{BufferTooSmall}!?CGroup {
pub fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{BufferTooSmall}!?CGroup {
const idx = bdz.search_u32(self.bdz_gid, gid);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_gid2group[idx];
@ -344,8 +344,8 @@ fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{BufferTooSmall}!?CGroup
fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {
const start = offset.*;
mem.copy(u8, buf[offset.*..], str);
buf[offset.* + str.len] = 0;
mem.copy(u8, buf[start..], str);
buf[start + str.len] = 0;
offset.* += str.len + 1;
return @ptrCast([*:0]const u8, &buf[start]);
}

View File

@ -95,13 +95,6 @@ fn init() void {
};
}
fn shouldOmitMembers(envvar: []const u8, argv: [][*:0]u8) bool {
if (mem.eql(u8, envvar, "1")) return true;
if (mem.eql(u8, envvar, "0")) return false;
if (argv.len == 0) return false;
return mem.eql(u8, mem.sliceTo(argv[0], 0), "id");
}
export fn _nss_turbo_getpwuid_r(
uid: c_uint,
passwd: *CUser,
@ -151,6 +144,55 @@ export fn _nss_turbo_getpwnam_r(
}
}
export fn _nss_turbo_getgrgid_r(
gid: c_uint,
gr: *CGroup,
buffer: [*]u8,
buflen: usize,
errnop: *c_int,
) c.enum_nss_status {
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
if (db.getgrgid(gid, buffer[0..buflen])) |maybe_cgroup| {
if (maybe_cgroup) |cgroup| {
gr.* = cgroup;
return c.NSS_STATUS_SUCCESS;
} else {
errnop.* = @enumToInt(os.E.NOENT);
return c.NSS_STATUS_NOTFOUND;
}
} else |err| switch (err) {
error.BufferTooSmall => {
errnop.* = @enumToInt(os.E.RANGE);
return c.NSS_STATUS_TRYAGAIN;
},
}
}
export fn _nss_turbo_getgrnam_r(
name: [*:0]const u8,
group: *CGroup,
buffer: [*]u8,
buflen: usize,
errnop: *c_int,
) c.enum_nss_status {
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
const nameSlice = mem.sliceTo(name, 0);
if (db.getgrnam(nameSlice, buffer[0..buflen])) |maybe_cgroup| {
if (maybe_cgroup) |cgroup| {
group.* = cgroup;
return c.NSS_STATUS_SUCCESS;
} else {
errnop.* = @enumToInt(os.E.NOENT);
return c.NSS_STATUS_NOTFOUND;
}
} else |err| switch (err) {
error.BufferTooSmall => {
errnop.* = @enumToInt(os.E.RANGE);
return c.NSS_STATUS_TRYAGAIN;
},
}
}
fn getDb(errnop: *c_int) ?DB {
global_init.call();
if (global_state.file) |file| {
@ -214,3 +256,29 @@ fn testVidmantas(u: CUser) !void {
try testing.expectEqualStrings("Vidmantas Kaminskas", mem.sliceTo(u.pw_gecos, 0));
try testing.expectEqualStrings("/bin/bash", mem.sliceTo(u.pw_shell, 0));
}
test "getgrgid_r and getgrnam_r" {
var tf = try File.TestDB.init(testing.allocator);
defer tf.deinit();
const turbonss_db_path_old = turbonss_db_path;
turbonss_db_path = tf.path;
defer {
turbonss_db_path = turbonss_db_path_old;
}
var buffer: [1024]u8 = undefined;
var errno: c_int = 0;
var group: CGroup = undefined;
try testing.expectEqual(
c.NSS_STATUS_SUCCESS,
_nss_turbo_getgrgid_r(128, &group, &buffer, buffer.len, &errno),
);
try testing.expectEqual(@as(c_int, 0), errno);
try testVidmantasGroup(group);
}
fn testVidmantasGroup(g: CGroup) !void {
try testing.expectEqual(@as(u32, 128), g.gid);
const members = g.members;
try testing.expect(members[0] != null);
}