libnss: fail early

This commit is contained in:
Motiejus Jakštys 2023-06-06 19:23:27 +03:00
parent 325c01b341
commit 65914ddcd6

View File

@ -201,12 +201,11 @@ export fn _nss_turbo_getgrgid_r(
errnop: *c_int, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return getgrgid_r(state, gid, gr, buffer, buflen, errnop);
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return c.NSS_STATUS_UNAVAIL; return c.NSS_STATUS_UNAVAIL;
} });
return getgrgid_r(state, gid, gr, buffer, buflen, errnop);
} }
fn getgrgid_r( fn getgrgid_r(
@ -228,12 +227,11 @@ fn getgrgid_r(
}, },
}; };
const got_cgroup = cgroup orelse { gr.* = cgroup orelse {
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; return c.NSS_STATUS_SUCCESS;
} }
@ -245,12 +243,11 @@ export fn _nss_turbo_getgrnam_r(
errnop: *c_int, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return getgrnam_r(state, name, group, buffer, buflen, errnop);
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return c.NSS_STATUS_UNAVAIL; return c.NSS_STATUS_UNAVAIL;
} });
return getgrnam_r(state, name, group, buffer, buflen, errnop);
} }
fn getgrnam_r( fn getgrnam_r(
@ -281,10 +278,8 @@ fn getgrnam_r(
export fn _nss_turbo_setpwent(_: c_int) c.enum_nss_status { export fn _nss_turbo_setpwent(_: c_int) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL);
return setpwent(state) return setpwent(state);
else
return c.NSS_STATUS_UNAVAIL;
} }
fn setpwent(state: *State) c.enum_nss_status { 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 { export fn _nss_turbo_endpwent() c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL);
return endpwent(state) return endpwent(state);
else
return c.NSS_STATUS_UNAVAIL;
} }
fn endpwent(state: *State) c.enum_nss_status { 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 { export fn _nss_turbo_setgrent(_: c_int) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL);
return setgrent(state) return setgrent(state);
else
return c.NSS_STATUS_UNAVAIL;
} }
fn setgrent(state: *State) c.enum_nss_status { 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 { export fn _nss_turbo_endgrent() c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| var state = &(global_state orelse return c.NSS_STATUS_UNAVAIL);
return endgrent(state) return endgrent(state);
else
return c.NSS_STATUS_UNAVAIL;
} }
fn endgrent(state: *State) c.enum_nss_status { fn endgrent(state: *State) c.enum_nss_status {
@ -355,12 +344,11 @@ export fn _nss_turbo_getgrent_r(
errnop: *c_int, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return getgrent_r(state, result, buffer, buflen, errnop);
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return c.NSS_STATUS_UNAVAIL; return c.NSS_STATUS_UNAVAIL;
} });
return getgrent_r(state, result, buffer, buflen, errnop);
} }
fn getgrent_r( fn getgrent_r(
@ -373,31 +361,31 @@ fn getgrent_r(
state.getgrent_iterator_mu.lock(); state.getgrent_iterator_mu.lock();
defer state.getgrent_iterator_mu.unlock(); defer state.getgrent_iterator_mu.unlock();
if (state.getgrent_iterator) |*it| { var it = &(state.getgrent_iterator orelse {
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 {
// logic from _nss_systemd_getgrent_r // logic from _nss_systemd_getgrent_r
errnop.* = @enumToInt(os.E.HOSTDOWN); errnop.* = @enumToInt(os.E.HOSTDOWN);
return c.NSS_STATUS_UNAVAIL; 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, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return getpwent_r(state, result, buffer, buflen, errnop);
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return c.NSS_STATUS_UNAVAIL; return c.NSS_STATUS_UNAVAIL;
} });
return getpwent_r(state, result, buffer, buflen, errnop);
} }
fn getpwent_r( fn getpwent_r(
@ -426,28 +414,28 @@ fn getpwent_r(
state.getpwent_iterator_mu.lock(); state.getpwent_iterator_mu.lock();
defer state.getpwent_iterator_mu.unlock(); defer state.getpwent_iterator_mu.unlock();
if (state.getpwent_iterator) |*it| { var it = &(state.getpwent_iterator orelse {
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 {
// logic from _nss_systemd_getgrent_r // logic from _nss_systemd_getgrent_r
errnop.* = @enumToInt(os.E.HOSTDOWN); errnop.* = @enumToInt(os.E.HOSTDOWN);
return c.NSS_STATUS_UNAVAIL; 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( export fn _nss_turbo_initgroups_dyn(
@ -460,12 +448,11 @@ export fn _nss_turbo_initgroups_dyn(
errnop: *c_int, errnop: *c_int,
) c.enum_nss_status { ) c.enum_nss_status {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop);
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return c.NSS_STATUS_UNAVAIL; return c.NSS_STATUS_UNAVAIL;
} });
return initgroups_dyn(state, user_name, gid, start, size, groupsp, limit, errnop);
} }
fn initgroups_dyn( fn initgroups_dyn(
@ -536,12 +523,11 @@ fn initgroups_dyn(
fn getDBErrno(errnop: *c_int) ?*const DB { fn getDBErrno(errnop: *c_int) ?*const DB {
global_init.call(); global_init.call();
if (global_state) |*state| { var state = &(global_state orelse {
return &state.file.db;
} else {
errnop.* = @enumToInt(os.E.AGAIN); errnop.* = @enumToInt(os.E.AGAIN);
return null; return null;
} });
return &state.file.db;
} }
// isId tells if this command is "id". Reads the cmdline // isId tells if this command is "id". Reads the cmdline
@ -718,7 +704,7 @@ test "libnss isId" {
defer os.close(fd); defer os.close(fd);
_ = try os.write(fd, tt.cmdline); _ = try os.write(fd, tt.cmdline);
try os.lseek_SET(fd, 0); try os.lseek_SET(fd, 0);
const got = isId(fd);
try testing.expectEqual(tt.want, got); try testing.expectEqual(tt.want, isId(fd));
} }
} }