pam-module.c revision c36eecdfcb4afa09850002fbb81a95a24ffde599
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <endian.h>
#include <sys/capability.h>
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_modutil.h>
#include <security/pam_misc.h>
#include "util.h"
#include "macro.h"
#include "sd-daemon.h"
#include "strv.h"
#include "dbus-common.h"
#include "def.h"
#include "socket-util.h"
char ***controllers,
char ***reset_controllers,
bool *kill_processes,
char ***kill_only_users,
char ***kill_exclude_users,
bool *debug) {
unsigned i;
for (i = 0; i < (unsigned) argc; i++) {
int k;
return k;
}
if (kill_processes)
*kill_processes = k;
/* As compatibility for old versions */
return k;
}
if (kill_processes)
*kill_processes = k;
if (controllers) {
char **l;
return -ENOMEM;
}
*controllers = l;
}
if (reset_controllers) {
char **l;
return -ENOMEM;
}
*reset_controllers = l;
}
if (kill_only_users) {
char **l;
return -ENOMEM;
}
*kill_only_users = l;
}
if (kill_exclude_users) {
char **l;
return -ENOMEM;
}
*kill_exclude_users = l;
}
return k;
}
if (debug)
*debug = k;
} else {
return -EINVAL;
}
}
return 0;
}
static int get_user_data(
const char **ret_username,
int r;
bool have_loginuid = false;
char *s;
if (have_effective_cap(CAP_AUDIT_CONTROL) > 0) {
/* Only use audit login uid if we are executed with
* sufficient capabilities so that pam_loginuid could
* do its job. If we are lacking the CAP_AUDIT_CONTROL
* capabality we most likely are being run in a
* it probably contains a uid of the host system. */
if (read_one_line_file("/proc/self/loginuid", &s) >= 0) {
uint32_t u;
r = safe_atou32(s, &u);
free(s);
if (r >= 0 && u != (uint32_t) -1 && u > 0) {
have_loginuid = true;
}
}
}
if (!have_loginuid) {
return r;
}
return PAM_AUTH_ERR;
}
}
if (!pw) {
return PAM_USER_UNKNOWN;
}
return PAM_SUCCESS;
}
static bool check_user_lists(
char **kill_only_users,
char **kill_exclude_users) {
char **l;
if (uid == 0)
else {
if (pw)
}
if (safe_atou32(*l, &id) >= 0)
return false;
return false;
}
if (strv_isempty(kill_only_users))
return true;
STRV_FOREACH(l, kill_only_users) {
if (safe_atou32(*l, &id) >= 0)
return true;
return true;
}
return false;
}
char *p = NULL;
int r;
int fd;
union sockaddr_union sa;
socklen_t l;
char *tty;
int v;
/* We deduce the X11 socket from the display name, then use
* SO_PEERCRED to determine the X11 server process, ask for
* the controlling tty of that and if it's a VC then we know
* the seat and the virtual terminal. Sounds ugly, is only
* semi-ugly. */
r = socket_from_display(display, &p);
if (r < 0)
return r;
if (fd < 0) {
free(p);
return -errno;
}
free(p);
return -errno;
}
l = sizeof(ucred);
if (r < 0)
return -errno;
if (r < 0)
return r;
v = vtnr_from_tty(tty);
if (v < 0)
return v;
else if (v == 0)
return -ENOENT;
*seat = "seat0";
return 0;
}
int flags,
bool kill_processes = false, debug = false;
const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type, *cvtnr = NULL;
char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL;
int session_fd = -1;
int r;
/* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */
/* Make this a NOP on non-systemd systems */
if (sd_booted() <= 0)
return PAM_SUCCESS;
if (parse_argv(handle,
&debug) < 0) {
r = PAM_SESSION_ERR;
goto finish;
}
if (r != PAM_SUCCESS)
goto finish;
if (kill_processes)
if (!bus) {
r = PAM_SESSION_ERR;
goto finish;
}
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"CreateSession");
if (!m) {
r = PAM_BUF_ERR;
goto finish;
}
/* A tty with a colon is usually an X11 display, place
* there to show up in utmp. We rearrange things and
* don't pretend that an X display was a tty */
tty = "";
}
remote = !isempty(remote_host) && !streq(remote_host, "localhost") && !streq(remote_host, "localhost.localdomain");
if (!dbus_message_append_args(m,
r = PAM_BUF_ERR;
goto finish;
}
if (r < 0) {
r = PAM_BUF_ERR;
goto finish;
}
if (r < 0) {
r = PAM_BUF_ERR;
goto finish;
}
kp = kill_processes;
r = PAM_BUF_ERR;
goto finish;
}
if (!reply) {
r = PAM_SESSION_ERR;
goto finish;
}
r = PAM_SESSION_ERR;
goto finish;
}
if (r != PAM_SUCCESS) {
goto finish;
}
if (r != PAM_SUCCESS) {
goto finish;
}
if (session_fd >= 0) {
if (r != PAM_SUCCESS) {
return r;
}
}
session_fd = -1;
r = PAM_SUCCESS;
if (bus) {
}
if (m)
if (reply)
if (session_fd >= 0)
return r;
}
int flags,
const void *p = NULL;
if (p)
return PAM_SUCCESS;
}