Currently openais does not allow unprivileged users to use the various
libraries, which I think is quite a serious restriction.
This patch enables normal users to call IPC routines that are specified
in the openais_lib_handler structure (the default is still privileged only).
I've slightly changed the meaning of the meaning of the
conn_info->authorized flag. Previously it was both part of the stata
machine and a flag saying the connection was correctly authorized. Now
it simply informs the state machine and the ->privileged flag indicates
whether the connection can perform privileged operations.
Comments?
Patrick
Index: exec/service.h
===================================================================
--- exec/service.h (revision 1499)
+++ exec/service.h (working copy)
@@ -42,11 +42,17 @@
OPENAIS_FLOW_CONTROL_NOT_REQUIRED = 2
};
+enum openais_unprivileged_call {
+ OPENAIS_UNPRIVILEGED_CALL_NO = 0,
+ OPENAIS_UNPRIVILEGED_CALL_YES = 1,
+};
+
struct openais_lib_handler {
void (*lib_handler_fn) (void *conn, void *msg);
int response_size;
int response_id;
enum openais_flow_control flow_control;
+ enum openais_unprivileged_call unpriv_call;
};
struct openais_exec_handler {
Index: exec/cpg.c
===================================================================
--- exec/cpg.c (revision 1499)
+++ exec/cpg.c (working copy)
@@ -198,43 +198,50 @@
.lib_handler_fn = message_handler_req_lib_cpg_join,
.response_size = sizeof (struct res_lib_cpg_join),
.response_id = MESSAGE_RES_CPG_JOIN,
- .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES,
},
{ /* 1 */
.lib_handler_fn = message_handler_req_lib_cpg_leave,
.response_size = sizeof (struct res_lib_cpg_leave),
.response_id = MESSAGE_RES_CPG_LEAVE,
- .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES,
},
{ /* 2 */
.lib_handler_fn = message_handler_req_lib_cpg_mcast,
.response_size = sizeof (struct res_lib_cpg_mcast),
.response_id = MESSAGE_RES_CPG_MCAST,
- .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES,
},
{ /* 3 */
.lib_handler_fn = message_handler_req_lib_cpg_membership,
.response_size = sizeof (mar_res_header_t),
.response_id = MESSAGE_RES_CPG_MEMBERSHIP,
- .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES
},
{ /* 4 */
.lib_handler_fn = message_handler_req_lib_cpg_trackstart,
.response_size = sizeof (struct res_lib_cpg_trackstart),
.response_id = MESSAGE_RES_CPG_TRACKSTART,
- .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES
},
{ /* 5 */
.lib_handler_fn = message_handler_req_lib_cpg_trackstop,
.response_size = sizeof (struct res_lib_cpg_trackstart),
.response_id = MESSAGE_RES_CPG_TRACKSTOP,
- .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES
},
{ /* 6 */
.lib_handler_fn = message_handler_req_lib_cpg_local_get,
.response_size = sizeof (struct res_lib_cpg_local_get),
.response_id = MESSAGE_RES_CPG_LOCAL_GET,
- .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
+ .unpriv_call = OPENAIS_UNPRIVILEGED_CALL_YES
}
};
Index: exec/ipc.c
===================================================================
--- exec/ipc.c (revision 1499)
+++ exec/ipc.c (working copy)
@@ -140,7 +140,8 @@
struct queue outq; /* Circular queue for outgoing requests */
int byte_start; /* Byte to start sending from in head of queue */
enum service_types service;/* Type of service so dispatch knows how to route message */
- int authenticated; /* Is this connection authenticated? */
+ int authenticated; /* Has this this connection been authenticated? */
+ int privileged; /* Is this connection privileged? */
void *private_data; /* library connection private data */
struct conn_info *conn_info_partner; /* partner connection dispatch<->response */
unsigned int flow_control_handle; /* flow control identifier */
@@ -766,11 +767,9 @@
gid_t egid = -1;
if (getpeereid(conn_info->fd, &euid, &egid) != -1 &&
(euid == 0 || egid == g_gid_valid)) {
- conn_info->authenticated = 1;
+ conn_info->privileged = 1;
}
- if (conn_info->authenticated == 0) {
- log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", egid, g_gid_valid);
- }
+ con_info->authenticated = 1;
#endif
}
@@ -787,13 +786,11 @@
euid = ucred_geteuid(uc);
egid = ucred_getegid(uc);
if ((euid == 0) || (egid == g_gid_valid)) {
- conn_info->authenticated = 1;
+ conn_info->privileged = 1;
}
ucred_free(uc);
}
- if (conn_info->authenticated == 0) {
- log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", (int)egid, g_gid_valid);
- }
+ con_info->authenticated = 1;
#else
log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated "
"because platform does not support "
@@ -839,12 +836,10 @@
if (cred) {
if (cred->uid == 0 || cred->gid == g_gid_valid) {
setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on));
- conn_info->authenticated = 1;
+ conn_info->privileged = 1;
}
}
- if (conn_info->authenticated == 0) {
- log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", cred->gid, g_gid_valid);
- }
+ conn_info->authenticated = 1;
}
#endif
/*
@@ -879,40 +874,57 @@
}
/*
- * If flow control is required of the library handle, determine that
- * openais is not in synchronization and that totempg has room available
- * to queue a message, otherwise tell the library we are busy and to
- * try again later
+ * Check if this is a privileged call, and if we are allowed to use it
*/
- send_ok_joined_iovec.iov_base = (char *)header;
- send_ok_joined_iovec.iov_len = header->size;
- send_ok_joined = totempg_groups_send_ok_joined (openais_group_handle,
- &send_ok_joined_iovec, 1);
-
- send_ok =
- (sync_primary_designated() == 1) && (
- (ais_service[service]->lib_service[header->id].flow_control == OPENAIS_FLOW_CONTROL_NOT_REQUIRED) ||
- ((ais_service[service]->lib_service[header->id].flow_control == OPENAIS_FLOW_CONTROL_REQUIRED) &&
- (send_ok_joined) &&
- (sync_in_process() == 0)));
-
- if (send_ok) {
- ais_service[service]->lib_service[header->id].lib_handler_fn(conn_info, header);
- } else {
-
- /*
- * Overload, tell library to retry
- */
+ if ((ais_service[service]->lib_service[header->id].unpriv_call == OPENAIS_UNPRIVILEGED_CALL_NO) &&
+ !conn_info->privileged) {
res_overlay.header.size =
ais_service[service]->lib_service[header->id].response_size;
res_overlay.header.id =
ais_service[service]->lib_service[header->id].response_id;
- res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN;
+ res_overlay.header.error = SA_AIS_ERR_ACCESS;
openais_conn_send_response (
conn_info,
&res_overlay,
res_overlay.header.size);
}
+ else {
+ /*
+ * If flow control is required of the library handle, determine that
+ * openais is not in synchronization and that totempg has room available
+ * to queue a message, otherwise tell the library we are busy and to
+ * try again later
+ */
+ send_ok_joined_iovec.iov_base = (char *)header;
+ send_ok_joined_iovec.iov_len = header->size;
+ send_ok_joined = totempg_groups_send_ok_joined (openais_group_handle,
+ &send_ok_joined_iovec, 1);
+
+ send_ok =
+ (sync_primary_designated() == 1) && (
+ (ais_service[service]->lib_service[header->id].flow_control == OPENAIS_FLOW_CONTROL_NOT_REQUIRED) ||
+ ((ais_service[service]->lib_service[header->id].flow_control == OPENAIS_FLOW_CONTROL_REQUIRED) &&
+ (send_ok_joined) &&
+ (sync_in_process() == 0)));
+
+ if (send_ok) {
+ ais_service[service]->lib_service[header->id].lib_handler_fn(conn_info, header);
+ } else {
+
+ /*
+ * Overload, tell library to retry
+ */
+ res_overlay.header.size =
+ ais_service[service]->lib_service[header->id].response_size;
+ res_overlay.header.id =
+ ais_service[service]->lib_service[header->id].response_id;
+ res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN;
+ openais_conn_send_response (
+ conn_info,
+ &res_overlay,
+ res_overlay.header.size);
+ }
+ }
}
conn_info->inb_inuse -= header->size;
} /* while */
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais