diff options
Diffstat (limited to 'src/sss_client')
-rw-r--r-- | src/sss_client/common.c | 81 | ||||
-rw-r--r-- | src/sss_client/pam_sss.c | 5 | ||||
-rw-r--r-- | src/sss_client/sss_cli.h | 11 |
3 files changed, 95 insertions, 2 deletions
diff --git a/src/sss_client/common.c b/src/sss_client/common.c index 6732c24fc..237b90aba 100644 --- a/src/sss_client/common.c +++ b/src/sss_client/common.c @@ -23,6 +23,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* for struct ucred */ +#define _GNU_SOURCE + #include <nss.h> #include <security/pam_modules.h> #include <errno.h> @@ -36,6 +39,10 @@ #include <string.h> #include <fcntl.h> #include <poll.h> + +#include <libintl.h> +#define _(STRING) dgettext (PACKAGE, STRING) +#include "config.h" #include "sss_cli.h" /* common functions */ @@ -632,6 +639,29 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd, return sss_nss_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } +errno_t check_server_cred(int sockfd) +{ +#ifdef HAVE_UCRED + int ret; + struct ucred server_cred; + socklen_t server_cred_len = sizeof(server_cred); + + ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &server_cred, + &server_cred_len); + if (ret != 0) { + return errno; + } + + if (server_cred_len != sizeof(struct ucred)) { + return ESSS_BAD_CRED_MSG; + } + + if (server_cred.uid != 0 || server_cred.gid != 0) { + return ESSS_SERVER_NOT_TRUSTED; + } +#endif + return 0; +} int sss_pam_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, @@ -653,17 +683,66 @@ int sss_pam_make_request(enum sss_cli_command cmd, if (ret != 0) return PAM_SERVICE_ERR; if ( ! (stat_buf.st_uid == 0 && stat_buf.st_gid == 0 && - (stat_buf.st_mode&(S_IFSOCK|S_IRUSR|S_IWUSR)) == stat_buf.st_mode)) { + S_ISSOCK(stat_buf.st_mode) && + (stat_buf.st_mode & ~S_IFMT) == 0600 )) { + *errnop = ESSS_BAD_PRIV_SOCKET; return PAM_SERVICE_ERR; } ret = sss_cli_check_socket(errnop, SSS_PAM_PRIV_SOCKET_NAME); } else { + ret = stat(SSS_PAM_SOCKET_NAME, &stat_buf); + if (ret != 0) return PAM_SERVICE_ERR; + if ( ! (stat_buf.st_uid == 0 && + stat_buf.st_gid == 0 && + S_ISSOCK(stat_buf.st_mode) && + (stat_buf.st_mode & ~S_IFMT) == 0666 )) { + *errnop = ESSS_BAD_PUB_SOCKET; + return PAM_SERVICE_ERR; + } + ret = sss_cli_check_socket(errnop, SSS_PAM_SOCKET_NAME); } if (ret != NSS_STATUS_SUCCESS) { return PAM_SERVICE_ERR; } + ret = check_server_cred(sss_cli_sd); + if (ret != 0) { + sss_cli_close_socket(); + *errnop = ret; + return PAM_SERVICE_ERR; + } + return sss_nss_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } + + +const char *ssscli_err2string(int err) +{ + const char *m; + + switch(err) { + case ESSS_BAD_PRIV_SOCKET: + return _("Privileged socket has wrong ownership or permissions."); + break; + case ESSS_BAD_PUB_SOCKET: + return _("Public socket has wrong ownership or permissions."); + break; + case ESSS_BAD_CRED_MSG: + return _("Unexpected format of the server credential message."); + break; + case ESSS_SERVER_NOT_TRUSTED: + return _("SSSD is not run by root."); + break; + default: + m = strerror(err); + if (m == NULL) { + return _("An error occurred, but no description can be found."); + } + return m; + break; + } + + return _("Unexpected error while looking for an error description"); +} diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 6059dfaa1..4208faa62 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -877,10 +877,13 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, } rd.data = buf; + errnop = 0; ret = sss_pam_make_request(task, &rd, &repbuf, &replen, &errnop); if (ret != NSS_STATUS_SUCCESS) { - logger(pamh, LOG_ERR, "Request to sssd failed."); + if (errnop != 0) { + logger(pamh, LOG_ERR, "Request to sssd failed. %s", ssscli_err2string(errnop)); + } pam_status = PAM_SYSTEM_ERR; goto done; } diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index f38726579..f7e58fe93 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -406,6 +406,17 @@ enum user_info_type { * @} */ /* end of group sss_pam_cli */ +enum sss_cli_error_codes { + ESSS_SSS_CLI_ERROR_START = 0x1000, + ESSS_BAD_PRIV_SOCKET, + ESSS_BAD_PUB_SOCKET, + ESSS_BAD_CRED_MSG, + ESSS_SERVER_NOT_TRUSTED, + + ESS_SSS_CLI_ERROR_MAX +}; + +const char *ssscli_err2string(int err); enum nss_status sss_nss_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, |