summaryrefslogtreecommitdiffstats
path: root/src/sss_client/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sss_client/common.c')
-rw-r--r--src/sss_client/common.c81
1 files changed, 80 insertions, 1 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");
+}