getpwnam_r and getpwuid_r

This commit is contained in:
Motiejus Jakštys 2022-07-06 16:29:21 +03:00
parent 64f6af6e94
commit a2893a366e
2 changed files with 44 additions and 11 deletions

View File

@ -84,10 +84,6 @@ pub const Entry = struct {
next: ?[]const u8, next: ?[]const u8,
}; };
// TODO(motiejus) provide a way to return an entry without decoding the
// additional_gids_offset:
// - will not return the 'next' slice.
// - cannot throw an Overflow error.
pub fn fromBytes(bytes: []const u8) Entry { pub fn fromBytes(bytes: []const u8) Entry {
const inner = mem.bytesAsValue(Inner, bytes[0..@sizeOf(Inner)]); const inner = mem.bytesAsValue(Inner, bytes[0..@sizeOf(Inner)]);
const start_blob = @sizeOf(Inner); const start_blob = @sizeOf(Inner);

View File

@ -22,7 +22,7 @@ const ENV_DB = "TURBONSS_DB";
const ENV_LOGLEVEL = "TURBONSS_LOGLEVEL"; const ENV_LOGLEVEL = "TURBONSS_LOGLEVEL";
const ENV_OMIT_MEMBERS = "TURBONSS_OMIT_MEMBERS"; const ENV_OMIT_MEMBERS = "TURBONSS_OMIT_MEMBERS";
export var turbonss_db_path: [:0]const u8 = "/etc/turbonss/db.turbo"; var turbonss_db_path: [:0]const u8 = "/etc/turbonss/db.turbo";
pub var log_level: std.log.Level = .err; pub var log_level: std.log.Level = .err;
@ -104,16 +104,40 @@ fn shouldOmitMembers(envvar: []const u8, argv: [][*:0]u8) bool {
export fn _nss_turbo_getpwuid_r( export fn _nss_turbo_getpwuid_r(
uid: c_uint, uid: c_uint,
pwd: *CUser, passwd: *CUser,
buf: [*]u8, buffer: [*]u8,
buflen: usize, buflen: usize,
errnop: *c_int, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
const db = get_db(errnop) orelse return c.NSS_STATUS_UNAVAIL; const db = get_db(errnop) orelse return c.NSS_STATUS_UNAVAIL;
if (db.getpwuid(uid, buffer[0..buflen])) |maybe_cuser| {
if (db.getpwuid(uid, buf[0..buflen])) |maybe_cuser| {
if (maybe_cuser) |cuser| { if (maybe_cuser) |cuser| {
pwd.* = cuser; passwd.* = cuser;
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_getpwnam_r(
name: [*:0]u8,
passwd: *CUser,
buffer: [*]u8,
buflen: usize,
errnop: *c_int,
) c.enum_nss_status {
const db = get_db(errnop) orelse return c.NSS_STATUS_UNAVAIL;
const nameSlice = mem.sliceTo(name, 0);
if (db.getpwnam(nameSlice, buffer[0..buflen])) |maybe_cuser| {
if (maybe_cuser) |cuser| {
passwd.* = cuser;
return c.NSS_STATUS_SUCCESS; return c.NSS_STATUS_SUCCESS;
} else { } else {
errnop.* = @enumToInt(os.E.NOENT); errnop.* = @enumToInt(os.E.NOENT);
@ -141,7 +165,20 @@ fn get_db(errnop: *c_int) ?DB {
const testing = std.testing; const testing = std.testing;
test "nss_turbo_getpwuid_r" { test "nss_turbo_getpwuid_r" {
const allocator = testing.allocator;
var errc = ErrCtx{}; var errc = ErrCtx{};
var tf = try File.TestDB.init(testing.allocator, &errc); var tf = try File.TestDB.init(allocator, &errc);
defer tf.deinit(); defer tf.deinit();
std.debug.print("tf.path: {s}\n", .{tf.path});
turbonss_db_path = tf.path;
var passwd: CUser = undefined;
var buffer: [1024]u8 = undefined;
var errno: c_int = 0;
const status = _nss_turbo_getpwuid_r(0, &passwd, &buffer, buffer.len, &errno);
if (true) return error.SkipZigTest;
try testing.expectEqual(@as(c_int, 0), errno);
try testing.expectEqual(c.NSS_STATUS_SUCCESS, status);
} }