diff options
author | Simo Sorce <ssorce@redhat.com> | 2010-11-22 09:12:27 -0500 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2010-11-22 12:18:27 -0500 |
commit | c89589fa349f38214c9cb8d9389c0fd557e5dca2 (patch) | |
tree | 0db51a68faa682708a75b0866b7da9a0f9d0f0c3 /src/sss_client/nss_group.c | |
parent | a2a695539c79316812fd9d7a1936331784d0e8c3 (diff) | |
download | sssd-c89589fa349f38214c9cb8d9389c0fd557e5dca2.tar.gz sssd-c89589fa349f38214c9cb8d9389c0fd557e5dca2.tar.xz sssd-c89589fa349f38214c9cb8d9389c0fd557e5dca2.zip |
sss_client: make code thread-safe
Add mutexes around nss operations and serialize them.
This is necessary because nss operations may have global state.
For pam it is sufficient to protect socket operations instead.
As pam functions use only the provided pam handler.
Fixes: https://fedorahosted.org/sssd/ticket/640
Diffstat (limited to 'src/sss_client/nss_group.c')
-rw-r--r-- | src/sss_client/nss_group.c | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c index 60b4611c..9e308c92 100644 --- a/src/sss_client/nss_group.c +++ b/src/sss_client/nss_group.c @@ -194,17 +194,20 @@ enum nss_status _nss_sss_initgroups_dyn(const char *user, gid_t group, rd.len = strlen(user) +1; rd.data = user; + sss_nss_lock(); + nret = sss_nss_make_request(SSS_NSS_INITGR, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { - return nret; + goto out; } /* no results if not found */ num_ret = ((uint32_t *)repbuf)[0]; if (num_ret == 0) { free(repbuf); - return NSS_STATUS_NOTFOUND; + nret = NSS_STATUS_NOTFOUND; + goto out; } max_ret = num_ret; @@ -223,7 +226,8 @@ enum nss_status _nss_sss_initgroups_dyn(const char *user, gid_t group, if (!newgroups) { *errnop = ENOMEM; free(repbuf); - return NSS_STATUS_TRYAGAIN; + nret = NSS_STATUS_TRYAGAIN; + goto out; } *groups = newgroups; *size = newsize; @@ -236,7 +240,11 @@ enum nss_status _nss_sss_initgroups_dyn(const char *user, gid_t group, } free(repbuf); - return NSS_STATUS_SUCCESS; + nret = NSS_STATUS_SUCCESS; + +out: + sss_nss_unlock(); + return nret; } @@ -256,10 +264,12 @@ enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, rd.len = strlen(name) + 1; rd.data = name; + sss_nss_lock(); + nret = sss_nss_make_request(SSS_NSS_GETGRNAM, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { - return nret; + goto out; } grrep.result = result; @@ -269,14 +279,16 @@ enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, /* no results if not found */ if (((uint32_t *)repbuf)[0] == 0) { free(repbuf); - return NSS_STATUS_NOTFOUND; + nret = NSS_STATUS_NOTFOUND; + goto out; } /* only 1 result is accepted for this function */ if (((uint32_t *)repbuf)[0] != 1) { *errnop = EBADMSG; free(repbuf); - return NSS_STATUS_TRYAGAIN; + nret = NSS_STATUS_TRYAGAIN; + goto out; } len = replen - 8; @@ -284,10 +296,15 @@ enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, free(repbuf); if (ret) { *errnop = ret; - return NSS_STATUS_TRYAGAIN; + nret = NSS_STATUS_TRYAGAIN; + goto out; } - return NSS_STATUS_SUCCESS; + nret = NSS_STATUS_SUCCESS; + +out: + sss_nss_unlock(); + return nret; } enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, @@ -308,10 +325,12 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, rd.len = sizeof(uint32_t); rd.data = &group_gid; + sss_nss_lock(); + nret = sss_nss_make_request(SSS_NSS_GETGRGID, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { - return nret; + goto out; } grrep.result = result; @@ -321,14 +340,16 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, /* no results if not found */ if (((uint32_t *)repbuf)[0] == 0) { free(repbuf); - return NSS_STATUS_NOTFOUND; + nret = NSS_STATUS_NOTFOUND; + goto out; } /* only 1 result is accepted for this function */ if (((uint32_t *)repbuf)[0] != 1) { *errnop = EBADMSG; free(repbuf); - return NSS_STATUS_TRYAGAIN; + nret = NSS_STATUS_TRYAGAIN; + goto out; } len = replen - 8; @@ -336,10 +357,15 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, free(repbuf); if (ret) { *errnop = ret; - return NSS_STATUS_TRYAGAIN; + nret = NSS_STATUS_TRYAGAIN; + goto out; } - return NSS_STATUS_SUCCESS; + nret = NSS_STATUS_SUCCESS; + +out: + sss_nss_unlock(); + return nret; } enum nss_status _nss_sss_setgrent(void) @@ -347,6 +373,8 @@ enum nss_status _nss_sss_setgrent(void) enum nss_status nret; int errnop; + sss_nss_lock(); + /* make sure we do not have leftovers, and release memory */ sss_nss_getgrent_data_clean(); @@ -354,14 +382,15 @@ enum nss_status _nss_sss_setgrent(void) NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; - return nret; } - return NSS_STATUS_SUCCESS; + sss_nss_unlock(); + return nret; } -enum nss_status _nss_sss_getgrent_r(struct group *result, - char *buffer, size_t buflen, int *errnop) +static enum nss_status internal_getgrent_r(struct group *result, + char *buffer, size_t buflen, + int *errnop) { struct sss_cli_req_data rd; struct sss_nss_gr_rep grrep; @@ -424,7 +453,19 @@ enum nss_status _nss_sss_getgrent_r(struct group *result, sss_nss_getgrent_data.ptr = 8; /* skip metadata fields */ /* call again ourselves, this will return the first result */ - return _nss_sss_getgrent_r(result, buffer, buflen, errnop); + return internal_getgrent_r(result, buffer, buflen, errnop); +} + +enum nss_status _nss_sss_getgrent_r(struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + enum nss_status nret; + + sss_nss_lock(); + nret = internal_getgrent_r(result, buffer, buflen, errnop); + sss_nss_unlock(); + + return nret; } enum nss_status _nss_sss_endgrent(void) @@ -432,6 +473,8 @@ enum nss_status _nss_sss_endgrent(void) enum nss_status nret; int errnop; + sss_nss_lock(); + /* make sure we do not have leftovers, and release memory */ sss_nss_getgrent_data_clean(); @@ -439,8 +482,8 @@ enum nss_status _nss_sss_endgrent(void) NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; - return nret; } - return NSS_STATUS_SUCCESS; + sss_nss_unlock(); + return nret; } |