libnetconf2 CHANGE QNX compatibility (#220)
fixes #217
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad7880a..f43ef03 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -251,8 +251,13 @@
include_directories(${LIBSSH_INCLUDE_DIRS})
# crypt
- target_link_libraries(netconf2 -lcrypt)
- list(APPEND CMAKE_REQUIRED_LIBRARIES crypt)
+ if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX")
+ target_link_libraries(netconf2 -lcrypt)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES crypt)
+ else()
+ target_link_libraries(netconf2 -llogin)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES login)
+ endif()
endif()
# dependencies - libval
@@ -268,6 +273,20 @@
target_link_libraries(netconf2 ${LIBYANG_LIBRARIES})
include_directories(${LIBYANG_INCLUDE_DIRS})
+# header file compatibility - shadow.h and crypt.h
+check_include_file("shadow.h" HAVE_SHADOW)
+check_include_file("crypt.h" HAVE_CRYPT)
+
+# function compatibility - getpeereid on QNX
+if(${CMAKE_SYSTEM_NAME} MATCHES "QNX")
+ target_link_libraries(netconf2 -lsocket)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES socket)
+ list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES pthread)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_QNX_SOURCE)
+ check_symbol_exists(getpeereid "sys/types.h;unistd.h" HAVE_GETPEEREID)
+ list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_QNX_SOURCE)
+endif()
+
# generate doxygen documentation for libnetconf2 API
find_package(Doxygen)
if(DOXYGEN_FOUND)
diff --git a/src/config.h.in b/src/config.h.in
index b69c8bd..0f0bbcc 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -48,6 +48,21 @@
#cmakedefine HAVE_PTHREAD_MUTEX_TIMEDLOCK
/*
+ * Support for getpeereid
+ */
+#cmakedefine HAVE_GETPEEREID
+
+/*
+ * Support for shadow file manipulation
+ */
+#cmakedefine HAVE_SHADOW
+
+/*
+ * Support for crypt.h
+ */
+#cmakedefine HAVE_CRYPT
+
+/*
* Location of installed basic YIN/YANG schemas
*/
#define NC_SCHEMAS_DIR "@SCHEMAS_DIR@"
diff --git a/src/session_server.c b/src/session_server.c
index 030ccf0..264a34c 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -11,6 +11,7 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
+#define _QNX_SOURCE /* getpeereid */
#define _GNU_SOURCE /* signals, threads, SO_PEERCRED */
#include <stdint.h>
@@ -1718,26 +1719,47 @@
#if defined(NC_ENABLED_SSH) || defined(NC_ENABLED_TLS)
static int
+nc_get_uid(int sock, uid_t *uid)
+{
+ #ifdef SO_PEERCRED
+ struct ucred ucred;
+ socklen_t len;
+ len = sizeof(ucred);
+ if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
+ ERR("Failed to get credentials from unix socket (%s).",
+ strerror(errno));
+ close(sock);
+ return -1;
+ }
+ *uid = ucred.uid;
+ #else
+ if (getpeereid(sock, uid, NULL) < 0) {
+ ERR("Failed to get credentials from unix socket (%s).",
+ strerror(errno));
+ close(sock);
+ return -1;
+ }
+ #endif
+
+ return 0;
+}
+
+static int
nc_accept_unix(struct nc_session *session, int sock)
{
-#ifdef SO_PEERCRED
+#if defined(SO_PEERCRED) || defined(HAVE_GETPEEREID)
const struct passwd *pw;
- struct ucred ucred;
char *username;
- socklen_t len;
session->ti_type = NC_TI_UNIX;
+ uid_t uid;
- len = sizeof(ucred);
- if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
- ERR("Failed to get credentials from unix socket (%s).",
- strerror(errno));
- close(sock);
+ if (nc_get_uid(sock, &uid) < 0) {
return -1;
}
- pw = getpwuid(ucred.uid);
+ pw = getpwuid(uid);
if (pw == NULL) {
- ERR("Failed to find username for uid=%u (%s).\n", ucred.uid,
+ ERR("Failed to find username for uid=%u (%s).\n", uid,
strerror(errno));
close(sock);
return -1;
diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c
index 412fbac..215d2c6 100644
--- a/src/session_server_ssh.c
+++ b/src/session_server_ssh.c
@@ -14,21 +14,25 @@
#define _GNU_SOURCE
+#include "config.h" /* Expose HAVE_SHADOW and HAVE_CRYPT */
+
+#ifdef HAVE_SHADOW
+ #include <shadow.h>
+#endif
+#ifdef HAVE_CRYPT
+ #include <crypt.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
-#ifndef __APPLE__
-#include <shadow.h>
-#include <crypt.h>
-#endif
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
-#include "config.h"
#include "session_server.h"
#include "session_server_ch.h"
#include "libnetconf.h"
@@ -664,7 +668,7 @@
static char *
auth_password_get_pwd_hash(const char *username)
{
-#ifndef __APPLE__
+#ifdef HAVE_SHADOW
struct passwd *pwd, pwd_buf;
struct spwd *spwd, spwd_buf;
char *pass_hash = NULL, buf[256];
@@ -676,7 +680,11 @@
}
if (!strcmp(pwd->pw_passwd, "x")) {
- getspnam_r(username, &spwd_buf, buf, 256, &spwd);
+ #ifndef __QNXNTO__
+ getspnam_r(username, &spwd_buf, buf, 256, &spwd);
+ #else
+ spwd = getspnam_r(username, &spwd_buf, buf, 256);
+ #endif
if (!spwd) {
VRB("Failed to retrieve the shadow entry for \"%s\".", username);
return NULL;