Signed-off-by: Angus Salkeld <asalk...@redhat.com>
---
 exec/coroipcs.c |   50 +++++++++++++++++++++++++++++++-------------------
 exec/main.c     |    4 +++-
 exec/util.h     |   21 +++++++++++++++++++++
 lib/util.h      |    6 ++++++
 4 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/exec/coroipcs.c b/exec/coroipcs.c
index aca9053..c3cf566 100644
--- a/exec/coroipcs.c
+++ b/exec/coroipcs.c
@@ -85,6 +85,7 @@
 #else
 #include <sys/sem.h>
 #endif
+#include "util.h"
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -761,14 +762,14 @@ retry_send:
        return (0);
 }
 
-static int
+static cs_error_t
 req_setup_recv (
        struct conn_info *conn_info)
 {
        int res;
        struct msghdr msg_recv;
        struct iovec iov_recv;
-       int authenticated = 0;
+       cs_error_t auth_res = CS_ERR_LIBRARY;
 
 #ifdef COROSYNC_LINUX
        struct cmsghdr *cmsg;
@@ -804,7 +805,7 @@ retry_recv:
                goto retry_recv;
        } else
        if (res == -1 && errno != EAGAIN) {
-               return (0);
+               return (CS_ERR_LIBRARY);
        } else
        if (res == 0) {
 #if defined(COROSYNC_SOLARIS) || defined(COROSYNC_BSD) || 
defined(COROSYNC_DARWIN)
@@ -812,9 +813,9 @@ retry_recv:
                 * EOF is detected when recvmsg return 0.
                 */
                ipc_disconnect (conn_info);
-               return 0;
+               return (CS_ERR_LIBRARY);
 #else
-               return (-1);
+               return (CS_ERR_SECURITY);
 #endif
        }
        conn_info->setup_bytes_read += res;
@@ -837,7 +838,9 @@ retry_recv:
                        egid = ucred_getegid (uc);
                        conn_info->client_pid = ucred_getpid (uc);
                        if (api->security_valid (euid, egid)) {
-                               authenticated = 1;
+                               auth_res = CS_OK;
+                       } else {
+                               auth_res = hdb_error_to_cs(errno);
                        }
                        ucred_free(uc);
                }
@@ -859,7 +862,9 @@ retry_recv:
                egid = -1;
                if (getpeereid (conn_info->fd, &euid, &egid) == 0) {
                        if (api->security_valid (euid, egid)) {
-                               authenticated = 1;
+                               auth_res = CS_OK;
+                       } else {
+                               auth_res = hdb_error_to_cs(errno);
                        }
                }
        }
@@ -874,29 +879,36 @@ retry_recv:
        if (cred) {
                conn_info->client_pid = cred->pid;
                if (api->security_valid (cred->uid, cred->gid)) {
-                       authenticated = 1;
+                       auth_res = CS_OK;
+               } else {
+                       auth_res = hdb_error_to_cs(errno);
                }
        }
 
 #else /* no credentials */
-       authenticated = 1;
-       log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC 
authentication.  Using no authentication\n");
+       auth_res = CS_OK;
+       log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC 
authentication.  Using no authentication\n");
 #endif /* no credentials */
 
-       if (authenticated == 0) {
-               log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n");
+       if (auth_res != CS_OK) {
                ipc_disconnect (conn_info);
-               return (-1);
-       }
+               if (auth_res == CS_ERR_NO_RESOURCES) {
+                       log_printf (LOGSYS_LEVEL_ERROR,
+                               "Not enough file desciptors for IPC 
connection.\n");
+               } else {
+                       log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC 
credentials.\n");
+               }
+               return auth_res;
+       }
 
        if (conn_info->setup_bytes_read == sizeof (mar_req_setup_t)) {
 #ifdef COROSYNC_LINUX
                setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED,
                        &off, sizeof (off));
 #endif
-               return (1);
+               return (CS_OK);
        }
-       return (0);
+       return (CS_ERR_LIBRARY);
 }
 
 static void ipc_disconnect (struct conn_info *conn_info)
@@ -1576,10 +1588,10 @@ int coroipcs_handler_dispatch (
                 * send OK
                 */
                res = req_setup_recv (conn_info);
-               if (res == -1) {
-                       req_setup_send (conn_info, CS_ERR_SECURITY);
+               if (res != CS_OK && res != CS_ERR_LIBRARY) {
+                       req_setup_send (conn_info, res);
                }
-               if (res != 1) {
+               if (res != CS_OK) {
                        return (0);
                }
 
diff --git a/exec/main.c b/exec/main.c
index d5306a3..58a33a6 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -925,7 +925,8 @@ static int corosync_security_valid (int euid, int egid)
        struct list_head *iter;
 
        if (corosync_not_enough_fds_left) {
-               return 0;
+               errno = EMFILE;
+               return (0);
        }
 
        if (euid == 0 || egid == 0) {
@@ -942,6 +943,7 @@ static int corosync_security_valid (int euid, int egid)
                        return (1);
        }
 
+       errno = EACCES;
        return (0);
 }
 
diff --git a/exec/util.h b/exec/util.h
index 7b95536..a3c5ae8 100644
--- a/exec/util.h
+++ b/exec/util.h
@@ -63,6 +63,27 @@ enum e_ais_done {
        AIS_DONE_DIR_NOT_PRESENT = 16
 };
 
+static inline cs_error_t hdb_error_to_cs (int res)             \
+{                                                              \
+       if (res == 0) {                                         \
+               return (CS_OK);                                 \
+       } else {                                                \
+               if (errno == EBADF) {                           \
+                       return (CS_ERR_BAD_HANDLE);             \
+               } else                                          \
+               if (errno == ENOMEM) {                          \
+                       return (CS_ERR_NO_MEMORY);              \
+               } else                                          \
+               if (errno == EMFILE) {                          \
+                       return (CS_ERR_NO_RESOURCES);           \
+               } else                                          \
+               if (errno == EACCES) {                          \
+                       return (CS_ERR_SECURITY);               \
+               }                                               \
+               return (CS_ERR_LIBRARY);                        \
+       }                                                       \
+}
+
 /*
  * Compare two names.  returns non-zero on match.
  */
diff --git a/lib/util.h b/lib/util.h
index 4a44bba..c228b42 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -48,6 +48,12 @@ static inline cs_error_t hdb_error_to_cs (int res)           
\
                } else                                          \
                if (errno == ENOMEM) {                          \
                        return (CS_ERR_NO_MEMORY);              \
+               } else                                          \
+               if (errno == EMFILE) {                          \
+                       return (CS_ERR_NO_RESOURCES);           \
+               } else                                          \
+               if (errno == EACCES) {                          \
+                       return (CS_ERR_SECURITY);               \
                }                                               \
                return (CS_ERR_LIBRARY);                        \
        }                                                       \
-- 
1.7.1

_______________________________________________
Openais mailing list
Openais@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to