For simplicity, I will explain the getgrent case below. The getpwent case
is exactly the same; simply substitute 'pw' for 'gr' and you'll understand
it perfectly. I'm new to the code base; I apologize for anything I've
In winbindd_group.c, winbindd_getgrent() checks that state->getgrent_state
is not NULL before proceeding:
if (!(ent = state->getgrent_state))
There are four conditions under which state->getgrent_state will be NULL:
1) winbindd_setgrent() has not been called
2) The end of the group list has been reached, and
state->getgrent_state has been set to NULL.
3) winbindd_endgrent() has been called.
4) The associated client connection has been closed
Condition #1 is breaks user/group enumeration and 'supplementary' groups
on FreeBSD; setgrent() is not called (by libc or otherwise) prior to
getgrent(),and so winbindd_getgrent() immediately returns WINBINDD_ERROR.
In my patch, I have added two additional variables to the winbindd_cli_state
With the patch:
winbindd_setgrent() sets state->getgrent_initialized to True;
winbindd_endgrent() sets state->getgrent_initialized to False;
In winbindd_getgrent(), if state->getgrent_initialized is False,
winbindd_setgrent() is called;
Since getgrent_state signifies end-of-list with NULL, it can not also be
used to signify that the list has not been initialized.
With attached patch, user and group enumeration works on FreeBSD 5.2.1
Created attachment 461 [details]
Patch to fix getgrent and getpwent on FreeBSD
Looks good. Will test and then check in for 3.0.3.
sorry for the same, cleaning up the database to prevent unecessary reopens of bugs.