passwd fields now have sentinels
This commit is contained in:
parent
4a3d43561f
commit
a63c60cc6f
18
src/DB.zig
18
src/DB.zig
@ -280,13 +280,13 @@ pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
||||
}
|
||||
|
||||
// dumps PackedGroup to []u8 and returns a CGroup.
|
||||
fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{OutOfMemory}!CGroup {
|
||||
fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
|
||||
const members_slice = self.groupmembers[group.members_offset..];
|
||||
var vit = compress.VarintSliceIteratorMust(members_slice);
|
||||
const num_members = vit.remaining;
|
||||
|
||||
const ptr_end = @sizeOf(?[*:0]const u8) * (num_members + 1);
|
||||
if (ptr_end > buf.len) return error.OutOfMemory;
|
||||
if (ptr_end > buf.len) return error.BufferTooSmall;
|
||||
var member_ptrs = mem.bytesAsSlice(?[*:0]const u8, buf[0..ptr_end]);
|
||||
member_ptrs[member_ptrs.len - 1] = null;
|
||||
var buf_offset: usize = ptr_end;
|
||||
@ -297,7 +297,7 @@ fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{OutOfMemory}!C
|
||||
const entry = PackedUser.fromBytes(self.users[member_offset << 3 ..]);
|
||||
const start = buf_offset;
|
||||
const name = entry.user.name();
|
||||
if (buf_offset + name.len + 1 > buf.len) return error.OutOfMemory;
|
||||
if (buf_offset + name.len + 1 > buf.len) return error.BufferTooSmall;
|
||||
mem.copy(u8, buf[buf_offset..], name);
|
||||
buf_offset += name.len;
|
||||
buf[buf_offset] = 0;
|
||||
@ -309,7 +309,7 @@ fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{OutOfMemory}!C
|
||||
}
|
||||
|
||||
const name = group.name();
|
||||
if (buf_offset + name.len + 1 > buf.len) return error.OutOfMemory;
|
||||
if (buf_offset + name.len + 1 > buf.len) return error.BufferTooSmall;
|
||||
mem.copy(u8, buf[buf_offset..], name);
|
||||
buf[buf_offset + name.len] = 0;
|
||||
|
||||
@ -321,7 +321,7 @@ fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{OutOfMemory}!C
|
||||
}
|
||||
|
||||
// get a CGroup entry by name.
|
||||
fn getgrnam(self: *const DB, name: []const u8, buf: []u8) error{OutOfMemory}!?CGroup {
|
||||
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{OutOfMemory}!?CG
|
||||
}
|
||||
|
||||
// get a CGroup entry by it's gid.
|
||||
fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{OutOfMemory}!?CGroup {
|
||||
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];
|
||||
@ -342,12 +342,12 @@ fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{OutOfMemory}!?CGroup {
|
||||
return try self.getGroup(group, buf);
|
||||
}
|
||||
|
||||
fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*]const u8 {
|
||||
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;
|
||||
offset.* += str.len + 1;
|
||||
return @ptrCast([*]const u8, &buf[start]);
|
||||
return @ptrCast([*:0]const u8, &buf[start]);
|
||||
}
|
||||
|
||||
fn getUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!CUser {
|
||||
@ -725,7 +725,7 @@ test "getgrnam/getgrgid" {
|
||||
|
||||
_ = try db.getgrnam("all", buf);
|
||||
buf.len -= 1;
|
||||
try testing.expectError(error.OutOfMemory, db.getgrnam("all", buf));
|
||||
try testing.expectError(error.BufferTooSmall, db.getgrnam("all", buf));
|
||||
}
|
||||
|
||||
test "getpwnam/getpwuid" {
|
||||
|
@ -43,11 +43,12 @@ pub const TestDB = struct {
|
||||
dir: testing.TmpDir,
|
||||
path: [:0]const u8,
|
||||
|
||||
pub fn init(allocator: Allocator, errc: *ErrCtx) !TestDB {
|
||||
pub fn init(allocator: Allocator) !TestDB {
|
||||
var errc = ErrCtx{};
|
||||
var corpus = try Corpus.testCorpus(allocator);
|
||||
defer corpus.deinit();
|
||||
|
||||
var db = try DB.fromCorpus(allocator, &corpus, errc);
|
||||
var db = try DB.fromCorpus(allocator, &corpus, &errc);
|
||||
defer db.deinit(allocator);
|
||||
|
||||
var tmp = testing.tmpDir(.{});
|
||||
|
10
src/User.zig
10
src/User.zig
@ -145,13 +145,13 @@ pub fn fromReader(allocator: Allocator, err: *ErrCtx, reader: anytype) ![]User {
|
||||
}
|
||||
|
||||
pub const CUser = extern struct {
|
||||
pw_name: [*]const u8,
|
||||
pw_passwd: [*]const u8 = pw_passwd,
|
||||
pw_name: [*:0]const u8,
|
||||
pw_passwd: [*:0]const u8 = pw_passwd,
|
||||
pw_uid: u32,
|
||||
pw_gid: u32,
|
||||
pw_gecos: [*]const u8,
|
||||
pw_dir: [*]const u8,
|
||||
pw_shell: [*]const u8,
|
||||
pw_gecos: [*:0]const u8,
|
||||
pw_dir: [*:0]const u8,
|
||||
pw_shell: [*:0]const u8,
|
||||
};
|
||||
|
||||
const testing = std.testing;
|
||||
|
@ -127,7 +127,7 @@ export fn _nss_turbo_getpwuid_r(
|
||||
}
|
||||
|
||||
export fn _nss_turbo_getpwnam_r(
|
||||
name: [*:0]u8,
|
||||
name: [*:0]const u8,
|
||||
passwd: *CUser,
|
||||
buffer: [*]u8,
|
||||
buflen: usize,
|
||||
@ -164,17 +164,54 @@ fn get_db(errnop: *c_int) ?DB {
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "nss_turbo_getpwuid_r" {
|
||||
var errc = ErrCtx{};
|
||||
var tf = try File.TestDB.init(testing.allocator, &errc);
|
||||
test "getpwuid_r and getpwnam_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 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);
|
||||
var passwd: CUser = undefined;
|
||||
try testing.expectEqual(
|
||||
c.NSS_STATUS_SUCCESS,
|
||||
_nss_turbo_getpwuid_r(128, &passwd, &buffer, buffer.len, &errno),
|
||||
);
|
||||
try testing.expectEqual(@as(c_int, 0), errno);
|
||||
try testing.expectEqual(c.NSS_STATUS_SUCCESS, status);
|
||||
try testVidmantas(passwd);
|
||||
|
||||
passwd = undefined;
|
||||
try testing.expectEqual(
|
||||
c.NSS_STATUS_SUCCESS,
|
||||
_nss_turbo_getpwnam_r("vidmantas", &passwd, &buffer, buffer.len, &errno),
|
||||
);
|
||||
try testing.expectEqual(@as(c_int, 0), errno);
|
||||
try testVidmantas(passwd);
|
||||
|
||||
passwd = undefined;
|
||||
try testing.expectEqual(
|
||||
c.NSS_STATUS_NOTFOUND,
|
||||
_nss_turbo_getpwnam_r("does not exist", &passwd, &buffer, buffer.len, &errno),
|
||||
);
|
||||
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
|
||||
|
||||
passwd = undefined;
|
||||
var small_buffer: [1]u8 = undefined;
|
||||
try testing.expectEqual(
|
||||
c.NSS_STATUS_TRYAGAIN,
|
||||
_nss_turbo_getpwuid_r(0, &passwd, &small_buffer, small_buffer.len, &errno),
|
||||
);
|
||||
try testing.expectEqual(@enumToInt(os.E.RANGE), @intCast(u16, errno));
|
||||
}
|
||||
|
||||
fn testVidmantas(u: CUser) !void {
|
||||
try testing.expectEqualStrings("vidmantas", mem.sliceTo(u.pw_name, 0));
|
||||
try testing.expectEqual(@as(u32, 128), u.pw_uid);
|
||||
try testing.expectEqual(@as(u32, 128), u.pw_gid);
|
||||
try testing.expectEqualStrings("Vidmantas Kaminskas", mem.sliceTo(u.pw_gecos, 0));
|
||||
try testing.expectEqualStrings("/bin/bash", mem.sliceTo(u.pw_shell, 0));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user