1
Fork 0

libnss: fail early

main
Motiejus Jakštys 2023-06-06 19:23:27 +03:00
parent 325c01b341
commit 65914ddcd6
1 changed files with 71 additions and 85 deletions

View File

@ -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));
}
}