From 65914ddcd6298fb6a6ecfd343ad261d8cc08fcfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Tue, 6 Jun 2023 19:23:27 +0300 Subject: [PATCH] libnss: fail early --- src/libnss.zig | 156 ++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 85 deletions(-) diff --git a/src/libnss.zig b/src/libnss.zig index d5cfdb3..e1011a3 100644 --- a/src/libnss.zig +++ b/src/libnss.zig @@ -201,12 +201,11 @@ export fn _nss_turbo_getgrgid_r( errnop: *c_int, ) c.enum_nss_status { global_init.call(); - if (global_state) |*state| { - return getgrgid_r(state, gid, gr, buffer, buflen, errnop); - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return c.NSS_STATUS_UNAVAIL; - } + }); + return getgrgid_r(state, gid, gr, buffer, buflen, errnop); } fn getgrgid_r( @@ -228,12 +227,11 @@ fn getgrgid_r( }, }; - const got_cgroup = cgroup orelse { + gr.* = cgroup orelse { errnop.* = @enumToInt(os.E.NOENT); return c.NSS_STATUS_NOTFOUND; }; - gr.* = got_cgroup; return c.NSS_STATUS_SUCCESS; } @@ -245,12 +243,11 @@ export fn _nss_turbo_getgrnam_r( errnop: *c_int, ) c.enum_nss_status { global_init.call(); - if (global_state) |*state| { - return getgrnam_r(state, name, group, buffer, buflen, errnop); - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return c.NSS_STATUS_UNAVAIL; - } + }); + return getgrnam_r(state, name, group, buffer, buflen, errnop); } fn getgrnam_r( @@ -281,10 +278,8 @@ fn getgrnam_r( export fn _nss_turbo_setpwent(_: c_int) c.enum_nss_status { global_init.call(); - if (global_state) |*state| - return setpwent(state) - else - return c.NSS_STATUS_UNAVAIL; + var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL); + return setpwent(state); } fn setpwent(state: *State) c.enum_nss_status { @@ -302,10 +297,8 @@ fn setpwent(state: *State) c.enum_nss_status { export fn _nss_turbo_endpwent() c.enum_nss_status { global_init.call(); - if (global_state) |*state| - return endpwent(state) - else - return c.NSS_STATUS_UNAVAIL; + var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL); + return endpwent(state); } fn endpwent(state: *State) c.enum_nss_status { @@ -317,10 +310,8 @@ fn endpwent(state: *State) c.enum_nss_status { export fn _nss_turbo_setgrent(_: c_int) c.enum_nss_status { global_init.call(); - if (global_state) |*state| - return setgrent(state) - else - return c.NSS_STATUS_UNAVAIL; + var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL); + return setgrent(state); } fn setgrent(state: *State) c.enum_nss_status { @@ -335,10 +326,8 @@ fn setgrent(state: *State) c.enum_nss_status { export fn _nss_turbo_endgrent() c.enum_nss_status { global_init.call(); - if (global_state) |*state| - return endgrent(state) - else - return c.NSS_STATUS_UNAVAIL; + var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL); + return endgrent(state); } fn endgrent(state: *State) c.enum_nss_status { @@ -355,12 +344,11 @@ export fn _nss_turbo_getgrent_r( errnop: *c_int, ) c.enum_nss_status { global_init.call(); - if (global_state) |*state| { - return getgrent_r(state, result, buffer, buflen, errnop); - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return c.NSS_STATUS_UNAVAIL; - } + }); + return getgrent_r(state, result, buffer, buflen, errnop); } fn getgrent_r( @@ -373,31 +361,31 @@ fn getgrent_r( state.getgrent_iterator_mu.lock(); defer state.getgrent_iterator_mu.unlock(); - 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 => { - it.rollback(); - errnop.* = @enumToInt(os.E.RANGE); - return c.NSS_STATUS_TRYAGAIN; - }, - } - } else { + var it = &(state.getgrent_iterator orelse { // 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 => { + it.rollback(); + errnop.* = @enumToInt(os.E.RANGE); + return c.NSS_STATUS_TRYAGAIN; + }, } } @@ -408,12 +396,12 @@ export fn _nss_turbo_getpwent_r( errnop: *c_int, ) c.enum_nss_status { global_init.call(); - if (global_state) |*state| { - return getpwent_r(state, result, buffer, buflen, errnop); - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return c.NSS_STATUS_UNAVAIL; - } + }); + + return getpwent_r(state, result, buffer, buflen, errnop); } fn getpwent_r( @@ -426,28 +414,28 @@ fn getpwent_r( state.getpwent_iterator_mu.lock(); defer state.getpwent_iterator_mu.unlock(); - 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 => { - it.rollback(); - errnop.* = @enumToInt(os.E.RANGE); - return c.NSS_STATUS_TRYAGAIN; - }, - }; - - result.* = cuser; - return c.NSS_STATUS_SUCCESS; - } else { + 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.* = 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 => { + it.rollback(); + errnop.* = @enumToInt(os.E.RANGE); + return c.NSS_STATUS_TRYAGAIN; + }, + }; + + result.* = cuser; + return c.NSS_STATUS_SUCCESS; } export fn _nss_turbo_initgroups_dyn( @@ -460,12 +448,11 @@ export fn _nss_turbo_initgroups_dyn( errnop: *c_int, ) c.enum_nss_status { global_init.call(); - if (global_state) |*state| { - return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop); - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return c.NSS_STATUS_UNAVAIL; - } + }); + return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop); } fn initgroups_dyn( @@ -536,12 +523,11 @@ fn initgroups_dyn( fn getDBErrno(errnop: *c_int) ?*const DB { global_init.call(); - if (global_state) |*state| { - return &state.file.db; - } else { + var state = &(global_state orelse { errnop.* = @enumToInt(os.E.AGAIN); return null; - } + }); + return &state.file.db; } // isId tells if this command is "id". Reads the cmdline @@ -718,7 +704,7 @@ test "libnss isId" { defer os.close(fd); _ = try os.write(fd, tt.cmdline); try os.lseek_SET(fd, 0); - const got = isId(fd); - try testing.expectEqual(tt.want, got); + + try testing.expectEqual(tt.want, isId(fd)); } }