mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r25406: Make the Linux nss client code thread-safe.
Fix originally inspired from code from boyang <yyyeer.bo@gmail.com>. Jeremy.
This commit is contained in:
parent
45fa393358
commit
cc19c0ace4
@ -1489,7 +1489,7 @@ bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@
|
||||
@WINBIND_NSS@: $(BINARY_PREREQS) $(WINBIND_NSS_OBJ)
|
||||
@echo "Linking $@"
|
||||
@$(SHLD) $(WINBIND_NSS_LDSHFLAGS) -o $@ $(WINBIND_NSS_OBJ) \
|
||||
@WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@
|
||||
@WINBIND_NSS_EXTRA_LIBS@ @WINBIND_NSS_PTHREAD@ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@
|
||||
|
||||
@WINBIND_WINS_NSS@: $(BINARY_PREREQS) $(WINBIND_WINS_NSS_OBJ)
|
||||
@echo "Linking $@"
|
||||
|
@ -991,7 +991,7 @@ LIBS="${LIBS} ${LIBDL}"
|
||||
|
||||
AC_CHECK_HEADERS(aio.h arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
|
||||
AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h memory.h alloca.h)
|
||||
AC_CHECK_HEADERS(limits.h float.h)
|
||||
AC_CHECK_HEADERS(limits.h float.h pthread.h)
|
||||
AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
|
||||
AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
|
||||
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
|
||||
@ -5984,6 +5984,7 @@ WINBIND_NSS="nsswitch/libnss_winbind.$SHLIBEXT"
|
||||
WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
|
||||
WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
|
||||
NSSSONAMEVERSIONSUFFIX=""
|
||||
WINBIND_NSS_PTHREAD=""
|
||||
|
||||
case "$host_os" in
|
||||
linux*-gnu* | gnu* | k*bsd*-gnu)
|
||||
@ -6047,6 +6048,9 @@ case "$host_os" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_LIB(pthread, pthread_mutex_lock, [WINBIND_NSS_PTHREAD="-lpthread"
|
||||
AC_DEFINE(HAVE_PTHREAD, 1, [whether pthread exists])])
|
||||
AC_SUBST(WINBIND_NSS_PTHREAD)
|
||||
AC_SUBST(WINBIND_NSS)
|
||||
AC_SUBST(WINBIND_WINS_NSS)
|
||||
AC_SUBST(WINBIND_NSS_LDSHFLAGS)
|
||||
|
@ -21,6 +21,14 @@
|
||||
|
||||
#include "winbind_client.h"
|
||||
|
||||
#if HAVE_PTHREAD_H
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
static pthread_mutex_t winbind_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
/* Maximum number of users to pass back over the unix domain socket
|
||||
per call. This is not a static limit on the total number of users
|
||||
or groups returned in total. */
|
||||
@ -332,6 +340,10 @@ _nss_winbind_setpwent(void)
|
||||
fprintf(stderr, "[%5d]: setpwent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
if (num_pw_cache > 0) {
|
||||
ndx_pw_cache = num_pw_cache = 0;
|
||||
winbindd_free_response(&getpwent_response);
|
||||
@ -342,6 +354,10 @@ _nss_winbind_setpwent(void)
|
||||
fprintf(stderr, "[%5d]: setpwent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -355,6 +371,10 @@ _nss_winbind_endpwent(void)
|
||||
fprintf(stderr, "[%5d]: endpwent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
if (num_pw_cache > 0) {
|
||||
ndx_pw_cache = num_pw_cache = 0;
|
||||
winbindd_free_response(&getpwent_response);
|
||||
@ -365,6 +385,11 @@ _nss_winbind_endpwent(void)
|
||||
fprintf(stderr, "[%5d]: endpwent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -382,6 +407,10 @@ _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
|
||||
fprintf(stderr, "[%5d]: getpwent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
/* Return an entry from the cache if we have one, or if we are
|
||||
called again because we exceeded our static buffer. */
|
||||
|
||||
@ -452,6 +481,10 @@ _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
|
||||
fprintf(stderr, "[%5d]: getpwent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -464,14 +497,18 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
|
||||
NSS_STATUS ret;
|
||||
static struct winbindd_response response;
|
||||
struct winbindd_request request;
|
||||
static int keep_response=0;
|
||||
static int keep_response;
|
||||
|
||||
#ifdef DEBUG_NSS
|
||||
fprintf(stderr, "[%5d]: getpwuid %d\n", getpid(), (unsigned int)uid);
|
||||
fprintf(stderr, "[%5d]: getpwuid_r %d\n", getpid(), (unsigned int)uid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
/* If our static buffer needs to be expanded we are called again */
|
||||
if (!keep_response) {
|
||||
if (!keep_response || uid != response.data.pw.pw_uid) {
|
||||
|
||||
/* Call for the first time */
|
||||
|
||||
@ -500,7 +537,6 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
|
||||
ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
|
||||
|
||||
if (ret == NSS_STATUS_TRYAGAIN) {
|
||||
keep_response = true;
|
||||
*errnop = errno = ERANGE;
|
||||
goto done;
|
||||
}
|
||||
@ -510,12 +546,18 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
|
||||
}
|
||||
|
||||
winbindd_free_response(&response);
|
||||
|
||||
done:
|
||||
|
||||
#ifdef DEBUG_NSS
|
||||
fprintf(stderr, "[%5d]: getpwuid %d returns %s (%d)\n", getpid(),
|
||||
(unsigned int)uid, nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -530,12 +572,16 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
|
||||
static int keep_response;
|
||||
|
||||
#ifdef DEBUG_NSS
|
||||
fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name);
|
||||
fprintf(stderr, "[%5d]: getpwnam_r %s\n", getpid(), name);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
/* If our static buffer needs to be expanded we are called again */
|
||||
|
||||
if (!keep_response) {
|
||||
if (!keep_response || strcmp(name,response.data.pw.pw_name) != 0) {
|
||||
|
||||
/* Call for the first time */
|
||||
|
||||
@ -582,6 +628,11 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
|
||||
fprintf(stderr, "[%5d]: getpwnam %s returns %s (%d)\n", getpid(),
|
||||
name, nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -604,6 +655,10 @@ _nss_winbind_setgrent(void)
|
||||
fprintf(stderr, "[%5d]: setgrent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
if (num_gr_cache > 0) {
|
||||
ndx_gr_cache = num_gr_cache = 0;
|
||||
winbindd_free_response(&getgrent_response);
|
||||
@ -614,6 +669,11 @@ _nss_winbind_setgrent(void)
|
||||
fprintf(stderr, "[%5d]: setgrent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -627,6 +687,10 @@ _nss_winbind_endgrent(void)
|
||||
fprintf(stderr, "[%5d]: endgrent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
if (num_gr_cache > 0) {
|
||||
ndx_gr_cache = num_gr_cache = 0;
|
||||
winbindd_free_response(&getgrent_response);
|
||||
@ -637,6 +701,11 @@ _nss_winbind_endgrent(void)
|
||||
fprintf(stderr, "[%5d]: endgrent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -656,6 +725,10 @@ winbind_getgrent(enum winbindd_cmd cmd,
|
||||
fprintf(stderr, "[%5d]: getgrent\n", getpid());
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
/* Return an entry from the cache if we have one, or if we are
|
||||
called again because we exceeded our static buffer. */
|
||||
|
||||
@ -735,6 +808,11 @@ winbind_getgrent(enum winbindd_cmd cmd,
|
||||
fprintf(stderr, "[%5d]: getgrent returns %s (%d)\n", getpid(),
|
||||
nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -769,9 +847,14 @@ _nss_winbind_getgrnam_r(const char *name,
|
||||
fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
/* If our static buffer needs to be expanded we are called again */
|
||||
|
||||
if (!keep_response) {
|
||||
/* Or if the stored response group name differs from the request. */
|
||||
|
||||
if (!keep_response || strcmp(name,response.data.gr.gr_name) != 0) {
|
||||
|
||||
/* Call for the first time */
|
||||
|
||||
@ -798,13 +881,13 @@ _nss_winbind_getgrnam_r(const char *name,
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
/* We've been called again */
|
||||
|
||||
|
||||
ret = fill_grent(result, &response.data.gr,
|
||||
(char *)response.extra_data.data, &buffer,
|
||||
&buflen);
|
||||
|
||||
|
||||
if (ret == NSS_STATUS_TRYAGAIN) {
|
||||
keep_response = true;
|
||||
*errnop = errno = ERANGE;
|
||||
@ -821,6 +904,11 @@ _nss_winbind_getgrnam_r(const char *name,
|
||||
fprintf(stderr, "[%5d]: getgrnam %s returns %s (%d)\n", getpid(),
|
||||
name, nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -840,9 +928,14 @@ _nss_winbind_getgrgid_r(gid_t gid,
|
||||
fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid);
|
||||
#endif
|
||||
|
||||
/* If our static buffer needs to be expanded we are called again */
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
if (!keep_response) {
|
||||
/* If our static buffer needs to be expanded we are called again */
|
||||
/* Or if the stored response group name differs from the request. */
|
||||
|
||||
if (!keep_response || gid != response.data.gr.gr_gid) {
|
||||
|
||||
/* Call for the first time */
|
||||
|
||||
@ -890,6 +983,10 @@ _nss_winbind_getgrgid_r(gid_t gid,
|
||||
fprintf(stderr, "[%5d]: getgrgid %d returns %s (%d)\n", getpid(),
|
||||
(unsigned int)gid, nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -910,6 +1007,10 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
|
||||
user, group);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
@ -990,6 +1091,11 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
|
||||
fprintf(stderr, "[%5d]: initgroups %s returns %s (%d)\n", getpid(),
|
||||
user, nss_err_str(ret), ret);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1008,6 +1114,10 @@ _nss_winbind_getusersids(const char *user_sid, char **group_sids,
|
||||
fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
@ -1033,6 +1143,11 @@ _nss_winbind_getusersids(const char *user_sid, char **group_sids,
|
||||
|
||||
done:
|
||||
winbindd_free_response(&response);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1050,6 +1165,10 @@ _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
|
||||
fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(response);
|
||||
ZERO_STRUCT(request);
|
||||
|
||||
@ -1075,6 +1194,11 @@ _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
|
||||
|
||||
failed:
|
||||
winbindd_free_response(&response);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1093,6 +1217,10 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
|
||||
fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(response);
|
||||
ZERO_STRUCT(request);
|
||||
|
||||
@ -1139,6 +1267,11 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
|
||||
|
||||
failed:
|
||||
winbindd_free_response(&response);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1154,6 +1287,10 @@ _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop)
|
||||
fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
@ -1169,6 +1306,11 @@ _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop)
|
||||
*uid = response.data.uid;
|
||||
|
||||
failed:
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1184,6 +1326,10 @@ _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop)
|
||||
fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
@ -1199,6 +1345,11 @@ _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop)
|
||||
*gid = response.data.gid;
|
||||
|
||||
failed:
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1215,6 +1366,10 @@ _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
|
||||
fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(response);
|
||||
ZERO_STRUCT(request);
|
||||
|
||||
@ -1238,6 +1393,11 @@ _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
|
||||
|
||||
failed:
|
||||
winbindd_free_response(&response);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1254,6 +1414,10 @@ _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
|
||||
fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid);
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_lock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(response);
|
||||
ZERO_STRUCT(request);
|
||||
|
||||
@ -1277,5 +1441,10 @@ _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
|
||||
|
||||
failed:
|
||||
winbindd_free_response(&response);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&winbind_nss_mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user