From 8db43a537b017ac7fa567d944d95312cc6ee3a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Thu, 14 Jul 2022 18:39:30 +0300 Subject: [PATCH] setpw/endpw* now iterate --- src/libnss.zig | 171 +++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 77 deletions(-) diff --git a/src/libnss.zig b/src/libnss.zig index 5513bbb..3df6fc1 100644 --- a/src/libnss.zig +++ b/src/libnss.zig @@ -194,8 +194,13 @@ export fn _nss_turbo_getgrgid_r( buflen: usize, errnop: *c_int, ) c.enum_nss_status { - const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL; - return getgrgid_r(state, gid, gr, buffer, buflen, errnop); + global_init.call(); + if (global_state) |*state| { + return getgrgid_r(state, gid, gr, buffer, buflen, errnop); + } else { + errnop.* = @enumToInt(os.E.AGAIN); + return c.NSS_STATUS_UNAVAIL; + } } fn getgrgid_r( @@ -233,8 +238,13 @@ export fn _nss_turbo_getgrnam_r( buflen: usize, errnop: *c_int, ) c.enum_nss_status { - const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL; - return getgrnam_r(state, name, group, buffer, buflen, errnop); + global_init.call(); + if (global_state) |*state| { + return getgrnam_r(state, name, group, buffer, buflen, errnop); + } else { + errnop.* = @enumToInt(os.E.AGAIN); + return c.NSS_STATUS_UNAVAIL; + } } fn getgrnam_r( @@ -265,8 +275,10 @@ fn getgrnam_r( export fn _nss_turbo_setpwent(_: c_int) c.enum_nss_status { global_init.call(); - var state = global_state orelse return c.NSS_STATUS_UNAVAIL; - return setpwent(&state); + if (global_state) |*state| + return setpwent(state) + else + return c.NSS_STATUS_UNAVAIL; } fn setpwent(state: *State) c.enum_nss_status { @@ -279,20 +291,18 @@ fn setpwent(state: *State) c.enum_nss_status { db.header.num_users, db.shellReader(), ); - std.debug.print("state.getpwent_iterator: {*}\n", .{ - &state.getpwent_iterator.?, - }); return c.NSS_STATUS_SUCCESS; } export fn _nss_turbo_endpwent() c.enum_nss_status { global_init.call(); - var state = global_state orelse return c.NSS_STATUS_UNAVAIL; - return endpwent(&state); + if (global_state) |*state| + return endpwent(state) + else + return c.NSS_STATUS_UNAVAIL; } fn endpwent(state: *State) c.enum_nss_status { - std.debug.print("endpwent\n", .{}); state.getpwent_iterator_mu.lock(); state.getpwent_iterator = null; state.getpwent_iterator_mu.unlock(); @@ -300,8 +310,11 @@ fn endpwent(state: *State) c.enum_nss_status { } export fn _nss_turbo_setgrent(_: c_int) c.enum_nss_status { - var state = getState() orelse return c.NSS_STATUS_UNAVAIL; - return setgrent(&state); + global_init.call(); + if (global_state) |*state| + return setgrent(state) + else + return c.NSS_STATUS_UNAVAIL; } fn setgrent(state: *State) c.enum_nss_status { @@ -315,8 +328,11 @@ fn setgrent(state: *State) c.enum_nss_status { } export fn _nss_turbo_endgrent() c.enum_nss_status { - var state = getState() orelse return c.NSS_STATUS_UNAVAIL; - return endgrent(&state); + global_init.call(); + if (global_state) |*state| + return endgrent(state) + else + return c.NSS_STATUS_UNAVAIL; } fn endgrent(state: *State) c.enum_nss_status { @@ -332,8 +348,13 @@ export fn _nss_turbo_getgrent_r( buflen: usize, errnop: *c_int, ) c.enum_nss_status { - var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL; - return getgrent_r(state, result, buffer, buflen, errnop); + global_init.call(); + if (global_state) |*state| { + return getgrent_r(state, result, buffer, buflen, errnop); + } else { + errnop.* = @enumToInt(os.E.AGAIN); + return c.NSS_STATUS_UNAVAIL; + } } fn getgrent_r( @@ -346,30 +367,30 @@ fn getgrent_r( state.getgrent_iterator_mu.lock(); defer state.getgrent_iterator_mu.unlock(); - var it = state.getgrent_iterator orelse { + if (state.getgrent_iterator) |*it| { + const group = it.next() orelse { + errnop.* = 0; + return c.NSS_STATUS_NOTFOUND; + }; + + const cgroup1 = if (state.omit_members) + DB.packCGroupNoMembers(&group, buffer[0..buflen]) + else + state.file.db.packCGroup(&group, buffer[0..buflen]); + + if (cgroup1) |cgroup| { + result.* = cgroup; + return c.NSS_STATUS_SUCCESS; + } else |err| switch (err) { + error.BufferTooSmall => { + errnop.* = @enumToInt(os.E.RANGE); + return c.NSS_STATUS_TRYAGAIN; + }, + } + } else { // logic from _nss_systemd_getgrent_r errnop.* = @enumToInt(os.E.HOSTDOWN); return c.NSS_STATUS_UNAVAIL; - }; - - const group = it.next() orelse { - errnop.* = 0; - return c.NSS_STATUS_NOTFOUND; - }; - - const cgroup1 = if (state.omit_members) - DB.packCGroupNoMembers(&group, buffer[0..buflen]) - else - state.file.db.packCGroup(&group, buffer[0..buflen]); - - if (cgroup1) |cgroup| { - result.* = cgroup; - return c.NSS_STATUS_SUCCESS; - } else |err| switch (err) { - error.BufferTooSmall => { - errnop.* = @enumToInt(os.E.RANGE); - return c.NSS_STATUS_TRYAGAIN; - }, } } @@ -379,8 +400,13 @@ export fn _nss_turbo_getpwent_r( buflen: usize, errnop: *c_int, ) c.enum_nss_status { - var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL; - return getpwent_r(state, result, buffer, buflen, errnop); + global_init.call(); + if (global_state) |*state| { + return getpwent_r(state, result, buffer, buflen, errnop); + } else { + errnop.* = @enumToInt(os.E.AGAIN); + return c.NSS_STATUS_UNAVAIL; + } } fn getpwent_r( @@ -393,30 +419,27 @@ fn getpwent_r( state.getpwent_iterator_mu.lock(); defer state.getpwent_iterator_mu.unlock(); - std.debug.print("starting getpwent_r\n", .{}); - var it = state.getpwent_iterator orelse { + if (state.getpwent_iterator) |*it| { + const user = it.next() orelse { + errnop.* = 0; + 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; + } else { // logic from _nss_systemd_getgrent_r - std.debug.print("no iterator, bailing\n", .{}); errnop.* = @enumToInt(os.E.HOSTDOWN); return c.NSS_STATUS_UNAVAIL; - }; - - const user = it.next() orelse { - std.debug.print("end of iteration, returning 0\n", .{}); - errnop.* = 0; - 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( @@ -428,8 +451,13 @@ export fn _nss_turbo_initgroups_dyn( limit: c_long, errnop: *c_int, ) c.enum_nss_status { - const state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL; - return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop); + global_init.call(); + if (global_state) |*state| { + return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop); + } else { + errnop.* = @enumToInt(os.E.AGAIN); + return c.NSS_STATUS_UNAVAIL; + } } fn initgroups_dyn( @@ -488,27 +516,16 @@ fn initgroups_dyn( return if (added > 0) c.NSS_STATUS_SUCCESS else c.NSS_STATUS_NOTFOUND; } -fn getState() ?State { - global_init.call(); - return global_state; -} - -fn getStateErrno(errnop: *c_int) ?*State { +fn getDBErrno(errnop: *c_int) ?*const DB { global_init.call(); if (global_state) |*state| { - return state; + return &state.file.db; } else { errnop.* = @enumToInt(os.E.AGAIN); return null; } } -fn getDBErrno(errnop: *c_int) ?*const DB { - if (getStateErrno(errnop)) |state| { - return &state.file.db; - } else return null; -} - const testing = std.testing; test "libnss getpwuid_r and getpwnam_r" {