summaryrefslogtreecommitdiffstats
path: root/src/responder
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-03-29 10:13:55 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-04-16 15:15:34 -0400
commitea0173fe8ba915960621454168651c62301833cb (patch)
tree433f6ecbd937d5fc4d7f9b03b98d03fb3ea47fcb /src/responder
parentb9923919909cb976ddf42002c56a42b1893e3547 (diff)
downloadsssd-ea0173fe8ba915960621454168651c62301833cb.tar.gz
sssd-ea0173fe8ba915960621454168651c62301833cb.tar.xz
sssd-ea0173fe8ba915960621454168651c62301833cb.zip
Use SO_PEERCRED on the PAM socket
This is the second attempt to let the PAM client and the PAM responder exchange their credentials, i.e. uid, gid and pid. Because this approach does not require any message interchange between the client and the server the protocol version number is not changed. On the client side the connection is terminated it the responder is not run by root. On the server side the effective uid and gid and the pid of the client are available for future use. The following additional changes are made by this patch: - the checks of the ownership and the permissions on the PAM sockets are enhanced - internal error codes are introduced on the client side to generate more specific log messages if an error occurs
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/common/responder.h3
-rw-r--r--src/responder/common/responder_common.c53
2 files changed, 55 insertions, 1 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index ea6ba5831..deb1e5a3c 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -101,6 +101,9 @@ struct cli_ctx {
struct cli_request *creq;
struct cli_protocol_version *cli_protocol_version;
int priv;
+ int32_t client_euid;
+ int32_t client_egid;
+ int32_t client_pid;
};
struct sss_cmd_table {
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index ff27f62cf..54d6c49e1 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -19,6 +19,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* for struct ucred */
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
@@ -29,7 +32,8 @@
#include <string.h>
#include <sys/time.h>
#include <errno.h>
-#include "popt.h"
+#include <popt.h>
+#include "config.h"
#include "util/util.h"
#include "db/sysdb.h"
#include "confdb/confdb.h"
@@ -61,6 +65,40 @@ static int client_destructor(struct cli_ctx *ctx)
return 0;
}
+static errno_t get_client_cred(struct cli_ctx *cctx)
+{
+#ifdef HAVE_UCRED
+ int ret;
+ struct ucred client_cred;
+ socklen_t client_cred_len = sizeof(client_cred);
+
+ cctx->client_euid = -1;
+ cctx->client_egid = -1;
+ cctx->client_pid = -1;
+
+ ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &client_cred,
+ &client_cred_len);
+ if (ret != EOK) {
+ ret = errno;
+ DEBUG(1, ("getsock failed [%d][%s].\n", ret, strerror(ret)));
+ return ret;
+ }
+ if (client_cred_len != sizeof(struct ucred)) {
+ DEBUG(1, ("getsockopt returned unexpected message size.\n"));
+ return ENOMSG;
+ }
+
+ cctx->client_euid = client_cred.uid;
+ cctx->client_egid = client_cred.gid;
+ cctx->client_pid = client_cred.pid;
+
+ DEBUG(9, ("Client creds: euid[%d] egid[%d] pid[%d].\n",
+ cctx->client_euid, cctx->client_egid, cctx->client_pid));
+#endif
+
+ return EOK;
+}
+
static void client_send(struct cli_ctx *cctx)
{
int ret;
@@ -214,6 +252,12 @@ static void accept_priv_fd_handler(struct tevent_context *ev,
cctx->priv = 1;
+ ret = get_client_cred(cctx);
+ if (ret != EOK) {
+ DEBUG(2, ("get_client_cred failed, "
+ "client cred may not be available.\n"));
+ }
+
cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
TEVENT_FD_READ, client_fd_handler, cctx);
if (!cctx->cfde) {
@@ -240,6 +284,7 @@ static void accept_fd_handler(struct tevent_context *ev,
struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);
struct cli_ctx *cctx;
socklen_t len;
+ int ret;
cctx = talloc_zero(rctx, struct cli_ctx);
if (!cctx) {
@@ -265,6 +310,12 @@ static void accept_fd_handler(struct tevent_context *ev,
return;
}
+ ret = get_client_cred(cctx);
+ if (ret != EOK) {
+ DEBUG(2, ("get_client_cred failed, "
+ "client cred may not be available.\n"));
+ }
+
cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
TEVENT_FD_READ, client_fd_handler, cctx);
if (!cctx->cfde) {