wip initgroups_dyn
This commit is contained in:
parent
df14c1fc67
commit
434f9e1571
21
src/DB.zig
21
src/DB.zig
@ -280,7 +280,7 @@ pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dumps PackedGroup to []u8 and returns a CGroup.
|
// dumps PackedGroup to []u8 and returns a CGroup.
|
||||||
pub fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
|
pub fn packCGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
|
||||||
const members_slice = self.groupmembers[group.members_offset..];
|
const members_slice = self.groupmembers[group.members_offset..];
|
||||||
var vit = compress.VarintSliceIteratorMust(members_slice);
|
var vit = compress.VarintSliceIteratorMust(members_slice);
|
||||||
const num_members = vit.remaining;
|
const num_members = vit.remaining;
|
||||||
@ -328,7 +328,7 @@ pub fn getgrnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSma
|
|||||||
const nbits = PackedGroup.alignment_bits;
|
const nbits = PackedGroup.alignment_bits;
|
||||||
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
|
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
|
||||||
if (!mem.eql(u8, name, group.name())) return null;
|
if (!mem.eql(u8, name, group.name())) return null;
|
||||||
return try self.getGroup(group, buf);
|
return try self.packCGroup(group, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a CGroup entry by it's gid.
|
// get a CGroup entry by it's gid.
|
||||||
@ -339,7 +339,7 @@ pub fn getgrgid(self: *const DB, gid: u32, buf: []u8) error{BufferTooSmall}!?CGr
|
|||||||
const nbits = PackedGroup.alignment_bits;
|
const nbits = PackedGroup.alignment_bits;
|
||||||
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
|
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
|
||||||
if (gid != group.gid()) return null;
|
if (gid != group.gid()) return null;
|
||||||
return try self.getGroup(group, buf);
|
return try self.packCGroup(group, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {
|
fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {
|
||||||
@ -350,7 +350,7 @@ fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {
|
|||||||
return buf[start .. start + str.len :0].ptr;
|
return buf[start .. start + str.len :0].ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!CUser {
|
pub fn writeUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!CUser {
|
||||||
const shell_reader = ShellReader{
|
const shell_reader = ShellReader{
|
||||||
.index = self.shell_index,
|
.index = self.shell_index,
|
||||||
.blob = self.shell_blob,
|
.blob = self.shell_blob,
|
||||||
@ -383,8 +383,7 @@ fn getUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!C
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a CUser entry by name.
|
pub fn getUser(self: *const DB, name: []const u8) ?PackedUser {
|
||||||
pub fn getpwnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSmall}!?CUser {
|
|
||||||
const idx = bdz.search(self.bdz_username, name);
|
const idx = bdz.search(self.bdz_username, name);
|
||||||
// bdz may return a hash that's bigger than the number of users
|
// bdz may return a hash that's bigger than the number of users
|
||||||
if (idx >= self.header.num_users) return null;
|
if (idx >= self.header.num_users) return null;
|
||||||
@ -392,7 +391,13 @@ pub fn getpwnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSma
|
|||||||
const nbits = PackedUser.alignment_bits;
|
const nbits = PackedUser.alignment_bits;
|
||||||
const user = PackedUser.fromBytes(self.users[offset << nbits ..]).user;
|
const user = PackedUser.fromBytes(self.users[offset << nbits ..]).user;
|
||||||
if (!mem.eql(u8, name, user.name())) return null;
|
if (!mem.eql(u8, name, user.name())) return null;
|
||||||
return try self.getUser(user, buf);
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a CUser entry by name.
|
||||||
|
pub fn getpwnam(self: *const DB, name: []const u8, buf: []u8) error{BufferTooSmall}!?CUser {
|
||||||
|
const user = self.getUser(name) orelse return null;
|
||||||
|
return try self.writeUser(user, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a CUser entry by uid.
|
// get a CUser entry by uid.
|
||||||
@ -403,7 +408,7 @@ pub fn getpwuid(self: *const DB, uid: u32, buf: []u8) error{BufferTooSmall}!?CUs
|
|||||||
const nbits = PackedUser.alignment_bits;
|
const nbits = PackedUser.alignment_bits;
|
||||||
const user = PackedUser.fromBytes(self.users[offset << nbits ..]).user;
|
const user = PackedUser.fromBytes(self.users[offset << nbits ..]).user;
|
||||||
if (uid != user.uid()) return null;
|
if (uid != user.uid()) return null;
|
||||||
return try self.getUser(user, buf);
|
return try self.writeUser(user, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shellSections(
|
fn shellSections(
|
||||||
|
125
src/libnss.zig
125
src/libnss.zig
@ -117,13 +117,13 @@ export fn _nss_turbo_getpwuid_r(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cuser) |got| {
|
const got_cuser = cuser orelse {
|
||||||
passwd.* = got;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
passwd.* = got_cuser;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_getpwnam_r(
|
export fn _nss_turbo_getpwnam_r(
|
||||||
@ -144,13 +144,13 @@ export fn _nss_turbo_getpwnam_r(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cuser) |got| {
|
const got_cuser = cuser orelse {
|
||||||
passwd.* = got;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
passwd.* = got_cuser;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_getgrgid_r(
|
export fn _nss_turbo_getgrgid_r(
|
||||||
@ -168,13 +168,13 @@ export fn _nss_turbo_getgrgid_r(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cgroup) |got| {
|
const got_cgroup = cgroup orelse {
|
||||||
gr.* = got;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
gr.* = got_cgroup;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_getgrnam_r(
|
export fn _nss_turbo_getgrnam_r(
|
||||||
@ -194,13 +194,13 @@ export fn _nss_turbo_getgrnam_r(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cgroup) |got| {
|
const got_cgroup = cgroup orelse {
|
||||||
group.* = got;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
group.* = got_cgroup;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_setpwent(_: c_int) void {
|
export fn _nss_turbo_setpwent(_: c_int) void {
|
||||||
@ -221,11 +221,11 @@ export fn _nss_turbo_setpwent(_: c_int) void {
|
|||||||
|
|
||||||
export fn _nss_turbo_endpwent() void {
|
export fn _nss_turbo_endpwent() void {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
if (global_state) |*state| {
|
var state = global_state orelse return;
|
||||||
state.getpwent_iterator_mu.lock();
|
|
||||||
defer state.getpwent_iterator_mu.unlock();
|
state.getpwent_iterator_mu.lock();
|
||||||
state.getpwent_iterator = null;
|
state.getpwent_iterator = null;
|
||||||
}
|
state.getpwent_iterator_mu.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_setgrent(_: c_int) void {
|
export fn _nss_turbo_setgrent(_: c_int) void {
|
||||||
@ -239,9 +239,10 @@ export fn _nss_turbo_setgrent(_: c_int) void {
|
|||||||
|
|
||||||
export fn _nss_turbo_endgrent() void {
|
export fn _nss_turbo_endgrent() void {
|
||||||
var state = getState() orelse return;
|
var state = getState() orelse return;
|
||||||
|
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
defer state.getgrent_iterator_mu.unlock();
|
|
||||||
state.getgrent_iterator = null;
|
state.getgrent_iterator = null;
|
||||||
|
state.getgrent_iterator_mu.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_getgrent_r(
|
export fn _nss_turbo_getgrent_r(
|
||||||
@ -261,20 +262,80 @@ export fn _nss_turbo_getgrent_r(
|
|||||||
return c.NSS_STATUS_UNAVAIL;
|
return c.NSS_STATUS_UNAVAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
var group = it.next() orelse {
|
const group = it.next() orelse {
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state.file.db.getGroup(group, buffer[0..buflen])) |cgroup| {
|
const buf = buffer[0..buflen];
|
||||||
result.* = cgroup;
|
const cgroup = state.file.db.packCGroup(group, buf) catch |err| switch (err) {
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.BufferTooSmall => {
|
error.BufferTooSmall => {
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
return c.NSS_STATUS_TRYAGAIN;
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
result.* = cgroup;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn _nss_turbo_getpwent_r(
|
||||||
|
result: *CUser,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
|
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
|
||||||
|
state.getpwent_iterator_mu.lock();
|
||||||
|
defer state.getpwent_iterator_mu.unlock();
|
||||||
|
|
||||||
|
var it = state.getpwent_iterator orelse {
|
||||||
|
// logic from _nss_systemd_getgrent_r
|
||||||
|
errnop.* = @enumToInt(os.E.HOSTDOWN);
|
||||||
|
return c.NSS_STATUS_UNAVAIL;
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = it.next() orelse {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buf = buffer[0..buflen];
|
||||||
|
const cuser = state.file.db.writeUser(user, buf) catch |err| switch (err) {
|
||||||
|
error.BufferTooSmall => {
|
||||||
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result.* = cuser;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn _nss_turbo_initgroups_dyn(
|
||||||
|
user_name: [*:0]const u8,
|
||||||
|
_: u32,
|
||||||
|
start: *c_long,
|
||||||
|
size: *c_long,
|
||||||
|
groups: [*]u32,
|
||||||
|
limit: c_long,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
|
||||||
|
const user = db.getUser(mem.sliceTo(user_name, 0)) orelse {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = user;
|
||||||
|
_ = start;
|
||||||
|
_ = size;
|
||||||
|
_ = groups;
|
||||||
|
_ = limit;
|
||||||
|
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getState() ?State {
|
fn getState() ?State {
|
||||||
|
Loading…
Reference in New Issue
Block a user