resolves: RHEL-146310 - Enable debug logs in cifs.upcall
Signed-off-by: Paulo Alcantara <paalcant@redhat.com>
This commit is contained in:
parent
ff17c4260c
commit
82aba2541d
1
.gitignore
vendored
1
.gitignore
vendored
@ -32,3 +32,4 @@ cifs-utils-4.6.tar.bz2
|
||||
/cifs-utils-7.1.tar.bz2
|
||||
/cifs-utils-7.2.tar.bz2
|
||||
/cifs-utils-7.4.tar.bz2
|
||||
/cifs-utils-7.5.tar.bz2
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
%global bash_completion_dir %(pkg-config --variable=completionsdir bash-completion || echo /etc/bash_completion.d)
|
||||
|
||||
Name: cifs-utils
|
||||
Version: 7.4
|
||||
Version: 7.5
|
||||
Release: %autorelease
|
||||
Summary: Utilities for mounting and managing CIFS mounts
|
||||
|
||||
@ -24,8 +24,9 @@ Recommends: %{name}-info%{?_isa} = %{version}-%{release}
|
||||
|
||||
Source0: https://download.samba.org/pub/linux-cifs/cifs-utils/%{name}-%{version}.tar.bz2
|
||||
|
||||
Patch0: cifscreds-fix-parsing-of-commands-and-parameters.patch
|
||||
Patch1: docs-update-echo_interval-description.patch
|
||||
Patch0: cifs.upcall-add-option-to-enable-debug-logs.patch
|
||||
Patch1: docs-Enable-debug-logs.patch
|
||||
Patch2: cifs.upcall-Adjust-log-level.patch
|
||||
|
||||
%description
|
||||
The SMB/CIFS protocol is a standard file sharing protocol widely deployed
|
||||
|
||||
41
cifs.upcall-Adjust-log-level.patch
Normal file
41
cifs.upcall-Adjust-log-level.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 927123ede36fab4a68aea6f6a3495ad909430ed1 Mon Sep 17 00:00:00 2001
|
||||
From: Pierguido Lambri <plambri@redhat.com>
|
||||
Date: Fri, 30 Jan 2026 14:11:28 +0000
|
||||
Subject: [PATCH 3/3] cifs.upcall: Adjust log level
|
||||
|
||||
Because now only error message are logged, let's switch some messages
|
||||
from DEBUG to ERROR level.
|
||||
This will help see when an error occurred with cifs.upcall and
|
||||
eventually turn on the debug mode.
|
||||
|
||||
Signed-off-by: Pierguido Lambri <plambri@redhat.com>
|
||||
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
---
|
||||
cifs.upcall.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cifs.upcall.c b/cifs.upcall.c
|
||||
index b57a48c743e4..9d0eecf3aa11 100644
|
||||
--- a/cifs.upcall.c
|
||||
+++ b/cifs.upcall.c
|
||||
@@ -1618,7 +1618,7 @@ int main(const int argc, char *const argv[])
|
||||
__func__);
|
||||
} else {
|
||||
if (!get_tgt_time(ccache)) {
|
||||
- syslog(LOG_DEBUG, "%s: valid TGT is not present in credential cache",
|
||||
+ syslog(LOG_ERR, "%s: valid TGT is not present in credential cache",
|
||||
__func__);
|
||||
krb5_cc_close(context, ccache);
|
||||
ccache = NULL;
|
||||
@@ -1721,7 +1721,7 @@ retry_new_hostname:
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
- syslog(LOG_DEBUG, "Unable to obtain service ticket");
|
||||
+ syslog(LOG_ERR, "Unable to obtain service ticket");
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
68
cifs.upcall-add-option-to-enable-debug-logs.patch
Normal file
68
cifs.upcall-add-option-to-enable-debug-logs.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From 3047b9ccefdcf6327bf060ebf0d40864c5b1a11e Mon Sep 17 00:00:00 2001
|
||||
From: Pierguido Lambri <plambri@redhat.com>
|
||||
Date: Fri, 30 Jan 2026 14:11:26 +0000
|
||||
Subject: [PATCH 1/3] cifs.upcall: add option to enable debug logs
|
||||
|
||||
cifs.upcall uses two levels of logs, DEBUG and ERR.
|
||||
However, when using systemd, these logs will always be recorded.
|
||||
When the system does a lot of upcalls, the journal could be filled
|
||||
with debug logs, which may not be useful at that time.
|
||||
Added then a new option '-d' to enable debug logs only when needed.
|
||||
This will set a logmask up to LOG_DEBUG instead of the default
|
||||
of LOG_ERR, thus reducing the amount of logs when no debug is needed.
|
||||
|
||||
Signed-off-by: Pierguido Lambri <plambri@redhat.com>
|
||||
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
---
|
||||
cifs.upcall.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cifs.upcall.c b/cifs.upcall.c
|
||||
index 69e27a34f637..b57a48c743e4 100644
|
||||
--- a/cifs.upcall.c
|
||||
+++ b/cifs.upcall.c
|
||||
@@ -1356,10 +1356,11 @@ lowercase_string(char *c)
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
- fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] [-e nsecs] key_serial\n", prog);
|
||||
+ fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-d] [-E] [-t] [-v] [-l] [-e nsecs] key_serial\n", prog);
|
||||
}
|
||||
|
||||
static const struct option long_options[] = {
|
||||
+ {"debug", 0, NULL, 'd'},
|
||||
{"no-env-probe", 0, NULL, 'E'},
|
||||
{"krb5conf", 1, NULL, 'k'},
|
||||
{"legacy-uid", 0, NULL, 'l'},
|
||||
@@ -1379,6 +1380,7 @@ int main(const int argc, char *const argv[])
|
||||
size_t datalen;
|
||||
long rc = 1;
|
||||
int c;
|
||||
+ int mask;
|
||||
bool try_dns = false, legacy_uid = false , env_probe = true;
|
||||
char *buf;
|
||||
char hostbuf[NI_MAXHOST], *host;
|
||||
@@ -1395,12 +1397,19 @@ int main(const int argc, char *const argv[])
|
||||
hostbuf[0] = '\0';
|
||||
|
||||
openlog(prog, 0, LOG_DAEMON);
|
||||
+ mask = LOG_UPTO(LOG_ERR);
|
||||
+ setlogmask(mask);
|
||||
|
||||
- while ((c = getopt_long(argc, argv, "cEk:K:ltve:", long_options, NULL)) != -1) {
|
||||
+ while ((c = getopt_long(argc, argv, "cdEk:K:ltve:", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
/* legacy option -- skip it */
|
||||
break;
|
||||
+ case 'd':
|
||||
+ /* enable debug logs */
|
||||
+ mask = LOG_UPTO(LOG_DEBUG);
|
||||
+ setlogmask(mask);
|
||||
+ break;
|
||||
case 'E':
|
||||
/* skip probing initiating process env */
|
||||
env_probe = false;
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
From 828cb25224cd88b3599d5ca79a7c9435491896db Mon Sep 17 00:00:00 2001
|
||||
From: Paulo Alcantara <pc@manguebit.org>
|
||||
Date: Tue, 25 Nov 2025 16:30:27 -0300
|
||||
Subject: [PATCH 1/2] cifscreds: fix parsing of commands and parameters
|
||||
|
||||
Fix the parsing of '--username' and '--timeout' options as both
|
||||
require an argument by fixing the value passed in @optstring when
|
||||
calling getopt_long(3).
|
||||
|
||||
Also fix the matching of commands by breaking the loop when an exact
|
||||
match is found. Otherwise `cifscreds clear ...` would return
|
||||
"Ambiguous command" due to "clearall" command.
|
||||
|
||||
* Before patch
|
||||
|
||||
$ ./cifscreds add -u testuser w22-root2.zelda.test
|
||||
error: Could not resolve address for testuser
|
||||
$ ./cifscreds add -u testuser -d ZELDA
|
||||
Password:
|
||||
$ grep 'cifs:[ad]' /proc/keys
|
||||
198de7a1 I--Q--- 1 perm 0d0d0000 0 0 logon cifs:d:testuser: 13
|
||||
^^ wrong desc
|
||||
$ ./cifscreds clear -u testuser w22-root2.zelda.test
|
||||
Ambiguous command
|
||||
$ ./cifscreds clear -u testuser -d ZELDA
|
||||
Ambiguous command
|
||||
|
||||
* After patch
|
||||
|
||||
$ ./cifscreds add -u testuser w22-root2.zelda.test
|
||||
Password:
|
||||
$ ./cifscreds add -u testuser -d ZELDA
|
||||
Password:
|
||||
$ grep 'cifs:[ad]' /proc/keys
|
||||
089183a9 I--Q--- 1 perm 0d0d0000 0 0 logon cifs:a:192.168.124.32: 17
|
||||
0ca5ed80 I--Q--- 1 perm 0d0d0000 0 0 logon cifs:d:ZELDA: 17
|
||||
$ ./cifscreds clear -u testuser w22-root2.zelda.test
|
||||
$ ./cifscreds clear -u testuser -d ZELDA
|
||||
|
||||
Reported-by: Xiaoli Feng <xifeng@redhat.com>
|
||||
Reported-by: Jay Shin <jaeshin@redhat.com>
|
||||
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
Cc: Steve French <smfrench@gmail.com>
|
||||
Cc: linux-cifs@vger.kernel.org
|
||||
---
|
||||
cifscreds.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cifscreds.c b/cifscreds.c
|
||||
index 295059f9683d..e8713be23d71 100644
|
||||
--- a/cifscreds.c
|
||||
+++ b/cifscreds.c
|
||||
@@ -71,7 +71,7 @@ static struct command commands[] = {
|
||||
static struct option longopts[] = {
|
||||
{"username", 1, NULL, 'u'},
|
||||
{"domain", 0, NULL, 'd' },
|
||||
- {"timeout", 0, NULL, 't' },
|
||||
+ {"timeout", 1, NULL, 't' },
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -477,7 +477,7 @@ int main(int argc, char **argv)
|
||||
if (argc == 1)
|
||||
return usage();
|
||||
|
||||
- while((n = getopt_long(argc, argv, "dut:", longopts, NULL)) != -1) {
|
||||
+ while((n = getopt_long(argc, argv, "du:t:", longopts, NULL)) != -1) {
|
||||
switch (n) {
|
||||
case 'd':
|
||||
arg.keytype = (char) n;
|
||||
@@ -507,7 +507,7 @@ int main(int argc, char **argv)
|
||||
if (cmd->name[n] == 0) {
|
||||
/* exact match */
|
||||
best = cmd;
|
||||
- continue;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* partial match */
|
||||
--
|
||||
2.51.1
|
||||
|
||||
41
docs-Enable-debug-logs.patch
Normal file
41
docs-Enable-debug-logs.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 224512b9e62c886fd8d9802bc50a7702c4fe4517 Mon Sep 17 00:00:00 2001
|
||||
From: Pierguido Lambri <plambri@redhat.com>
|
||||
Date: Fri, 30 Jan 2026 14:11:27 +0000
|
||||
Subject: [PATCH 2/3] docs: Enable debug logs
|
||||
|
||||
Documented a new option '-d' to enable debug logs.
|
||||
By default only error logs are enabled, with this new option
|
||||
debug logs can be enabled when needed.
|
||||
|
||||
Signed-off-by: Pierguido Lambri <plambri@redhat.com>
|
||||
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
---
|
||||
cifs.upcall.rst.in | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cifs.upcall.rst.in b/cifs.upcall.rst.in
|
||||
index 09d0503591d6..895efc53ef50 100644
|
||||
--- a/cifs.upcall.rst.in
|
||||
+++ b/cifs.upcall.rst.in
|
||||
@@ -11,7 +11,7 @@ Userspace upcall helper for Common Internet File System (CIFS)
|
||||
SYNOPSIS
|
||||
********
|
||||
|
||||
- cifs.upcall [--trust-dns|-t] [--version|-v] [--legacy-uid|-l]
|
||||
+ cifs.upcall [--trust-dns|-t] [--version|-v] [--legacy-uid|-l] [--debug|-d]
|
||||
[--krb5conf=/path/to/krb5.conf|-k /path/to/krb5.conf]
|
||||
[--keytab=/path/to/keytab|-K /path/to/keytab] [--expire|-e nsecs] {keyid}
|
||||
|
||||
@@ -38,6 +38,9 @@ OPTIONS
|
||||
-c
|
||||
This option is deprecated and is currently ignored.
|
||||
|
||||
+--debug|-d
|
||||
+ Enable debug logs. By default no debug messages are logged, only errors.
|
||||
+
|
||||
--no-env-probe|-E
|
||||
Normally, ``cifs.upcall`` will probe the environment variable space of
|
||||
the process that initiated the upcall in order to fetch the value of
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From b9680e868d4bdf9337e542b08a559e9ca5ea6cc0 Mon Sep 17 00:00:00 2001
|
||||
From: Paulo Alcantara <pc@manguebit.org>
|
||||
Date: Tue, 25 Nov 2025 17:54:04 -0300
|
||||
Subject: [PATCH 2/2] docs: update echo_interval description
|
||||
|
||||
It is '3 * echo_interval' since upstream commit f2caf901c1b7 ("cifs:
|
||||
Fix a race condition with cifs_echo_request").
|
||||
|
||||
Reported-by: Alexandros Panagiotou <apanagio@redhat.com>
|
||||
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
Cc: Steve French <smfrench@gmail.com>
|
||||
Cc: linux-cifs@vger.kernel.org
|
||||
---
|
||||
mount.cifs.rst | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/mount.cifs.rst b/mount.cifs.rst
|
||||
index d4890706a0fe..4b6d47447c0e 100644
|
||||
--- a/mount.cifs.rst
|
||||
+++ b/mount.cifs.rst
|
||||
@@ -483,8 +483,8 @@ echo_interval=n
|
||||
sets the interval at which echo requests are sent to the server on an
|
||||
idling connection. This setting also affects the time required for a
|
||||
connection to an unresponsive server to timeout. Here n is the echo
|
||||
- interval in seconds. The reconnection happens at twice the value of the
|
||||
- echo_interval set for an unresponsive server.
|
||||
+ interval in seconds. The reconnection happens at three times the
|
||||
+ value of the echo_interval set for an unresponsive server.
|
||||
If this option is not given then the default value of 60 seconds is used.
|
||||
The minimum tunable value is 1 second and maximum can go up to 600 seconds.
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
diff --git a/mount.cifs.c b/mount.cifs.c
|
||||
index 7f898bbd215a..84274c98ddf5 100644
|
||||
--- a/mount.cifs.c
|
||||
+++ b/mount.cifs.c
|
||||
@@ -1996,9 +1996,9 @@ acquire_mountpoint(char **mountpointp)
|
||||
*/
|
||||
realuid = getuid();
|
||||
if (realuid == 0) {
|
||||
- dacrc = toggle_dac_capability(0, 1);
|
||||
- if (dacrc)
|
||||
- return dacrc;
|
||||
+ rc = toggle_dac_capability(0, 1);
|
||||
+ if (rc)
|
||||
+ goto out;
|
||||
} else {
|
||||
oldfsuid = setfsuid(realuid);
|
||||
oldfsgid = setfsgid(getgid());
|
||||
@@ -2019,7 +2019,6 @@ acquire_mountpoint(char **mountpointp)
|
||||
rc = EX_SYSERR;
|
||||
}
|
||||
|
||||
- *mountpointp = mountpoint;
|
||||
restore_privs:
|
||||
if (realuid == 0) {
|
||||
dacrc = toggle_dac_capability(0, 0);
|
||||
@@ -2030,9 +2029,13 @@ restore_privs:
|
||||
gid_t __attribute__((unused)) gignore = setfsgid(oldfsgid);
|
||||
}
|
||||
|
||||
- if (rc)
|
||||
+out:
|
||||
+ if (rc) {
|
||||
free(mountpoint);
|
||||
+ mountpoint = NULL;
|
||||
+ }
|
||||
|
||||
+ *mountpointp = mountpoint;
|
||||
return rc;
|
||||
}
|
||||
|
||||
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (cifs-utils-7.4.tar.bz2) = 36fb64ed531e983752be243be488392ba52c3797ac638147a75998b8965448009e95d7ccda187c7d50d753b0ddb87a464a83044064b099d49fffe03a0b6ba739
|
||||
SHA512 (cifs-utils-7.5.tar.bz2) = d44b26ca3224160bcb4fc712eb6c6d09fcfee196197d46481e95333494eaae1a4851712fba9b922c203e3cd301c481b433ff49ec396428c12ff7db3c628ce9e9
|
||||
|
||||
429
upcall-fix.patch
429
upcall-fix.patch
@ -1,429 +0,0 @@
|
||||
diff --git a/cifs.upcall.c b/cifs.upcall.c
|
||||
index e4139349fea7..ad0430157958 100644
|
||||
--- a/cifs.upcall.c
|
||||
+++ b/cifs.upcall.c
|
||||
@@ -52,6 +52,9 @@
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
#include "data_blob.h"
|
||||
#include "spnego.h"
|
||||
@@ -787,6 +790,25 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+
|
||||
+
|
||||
+struct decoded_args {
|
||||
+ int ver;
|
||||
+ char hostname[NI_MAXHOST + 1];
|
||||
+ char ip[NI_MAXHOST + 1];
|
||||
+
|
||||
+/* Max user name length. */
|
||||
+#define MAX_USERNAME_SIZE 256
|
||||
+ char username[MAX_USERNAME_SIZE + 1];
|
||||
+
|
||||
+ uid_t uid;
|
||||
+ uid_t creduid;
|
||||
+ pid_t pid;
|
||||
+ sectype_t sec;
|
||||
+
|
||||
+/*
|
||||
+ * Flags to keep track of what was provided
|
||||
+ */
|
||||
#define DKD_HAVE_HOSTNAME 0x1
|
||||
#define DKD_HAVE_VERSION 0x2
|
||||
#define DKD_HAVE_SEC 0x4
|
||||
@@ -796,23 +818,13 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
|
||||
#define DKD_HAVE_CREDUID 0x40
|
||||
#define DKD_HAVE_USERNAME 0x80
|
||||
#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
|
||||
-
|
||||
-struct decoded_args {
|
||||
- int ver;
|
||||
- char *hostname;
|
||||
- char *ip;
|
||||
- char *username;
|
||||
- uid_t uid;
|
||||
- uid_t creduid;
|
||||
- pid_t pid;
|
||||
- sectype_t sec;
|
||||
+ int have;
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
-decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
+__decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
{
|
||||
- int len;
|
||||
- int retval = 0;
|
||||
+ size_t len;
|
||||
char *pos;
|
||||
const char *tkn = desc;
|
||||
|
||||
@@ -826,13 +838,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
len = pos - tkn;
|
||||
|
||||
len -= 5;
|
||||
- free(arg->hostname);
|
||||
- arg->hostname = strndup(tkn + 5, len);
|
||||
- if (arg->hostname == NULL) {
|
||||
- syslog(LOG_ERR, "Unable to allocate memory");
|
||||
+ if (len > sizeof(arg->hostname)-1) {
|
||||
+ syslog(LOG_ERR, "host= value too long for buffer");
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_HOSTNAME;
|
||||
+ memset(arg->hostname, 0, sizeof(arg->hostname));
|
||||
+ strncpy(arg->hostname, tkn + 5, len);
|
||||
+ arg->have |= DKD_HAVE_HOSTNAME;
|
||||
syslog(LOG_DEBUG, "host=%s", arg->hostname);
|
||||
} else if (!strncmp(tkn, "ip4=", 4) || !strncmp(tkn, "ip6=", 4)) {
|
||||
if (pos == NULL)
|
||||
@@ -841,13 +853,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
len = pos - tkn;
|
||||
|
||||
len -= 4;
|
||||
- free(arg->ip);
|
||||
- arg->ip = strndup(tkn + 4, len);
|
||||
- if (arg->ip == NULL) {
|
||||
- syslog(LOG_ERR, "Unable to allocate memory");
|
||||
+ if (len > sizeof(arg->ip)-1) {
|
||||
+ syslog(LOG_ERR, "ip[46]= value too long for buffer");
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_IP;
|
||||
+ memset(arg->ip, 0, sizeof(arg->ip));
|
||||
+ strncpy(arg->ip, tkn + 4, len);
|
||||
+ arg->have |= DKD_HAVE_IP;
|
||||
syslog(LOG_DEBUG, "ip=%s", arg->ip);
|
||||
} else if (strncmp(tkn, "user=", 5) == 0) {
|
||||
if (pos == NULL)
|
||||
@@ -856,13 +868,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
len = pos - tkn;
|
||||
|
||||
len -= 5;
|
||||
- free(arg->username);
|
||||
- arg->username = strndup(tkn + 5, len);
|
||||
- if (arg->username == NULL) {
|
||||
- syslog(LOG_ERR, "Unable to allocate memory");
|
||||
+ if (len > sizeof(arg->username)-1) {
|
||||
+ syslog(LOG_ERR, "user= value too long for buffer");
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_USERNAME;
|
||||
+ memset(arg->username, 0, sizeof(arg->username));
|
||||
+ strncpy(arg->username, tkn + 5, len);
|
||||
+ arg->have |= DKD_HAVE_USERNAME;
|
||||
syslog(LOG_DEBUG, "user=%s", arg->username);
|
||||
} else if (strncmp(tkn, "pid=", 4) == 0) {
|
||||
errno = 0;
|
||||
@@ -873,13 +885,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
return 1;
|
||||
}
|
||||
syslog(LOG_DEBUG, "pid=%u", arg->pid);
|
||||
- retval |= DKD_HAVE_PID;
|
||||
+ arg->have |= DKD_HAVE_PID;
|
||||
} else if (strncmp(tkn, "sec=", 4) == 0) {
|
||||
if (strncmp(tkn + 4, "krb5", 4) == 0) {
|
||||
- retval |= DKD_HAVE_SEC;
|
||||
+ arg->have |= DKD_HAVE_SEC;
|
||||
arg->sec = KRB5;
|
||||
} else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
|
||||
- retval |= DKD_HAVE_SEC;
|
||||
+ arg->have |= DKD_HAVE_SEC;
|
||||
arg->sec = MS_KRB5;
|
||||
}
|
||||
syslog(LOG_DEBUG, "sec=%d", arg->sec);
|
||||
@@ -891,7 +903,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_UID;
|
||||
+ arg->have |= DKD_HAVE_UID;
|
||||
syslog(LOG_DEBUG, "uid=%u", arg->uid);
|
||||
} else if (strncmp(tkn, "creduid=", 8) == 0) {
|
||||
errno = 0;
|
||||
@@ -901,7 +913,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_CREDUID;
|
||||
+ arg->have |= DKD_HAVE_CREDUID;
|
||||
syslog(LOG_DEBUG, "creduid=%u", arg->creduid);
|
||||
} else if (strncmp(tkn, "ver=", 4) == 0) { /* if version */
|
||||
errno = 0;
|
||||
@@ -911,14 +923,56 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
- retval |= DKD_HAVE_VERSION;
|
||||
+ arg->have |= DKD_HAVE_VERSION;
|
||||
syslog(LOG_DEBUG, "ver=%d", arg->ver);
|
||||
}
|
||||
if (pos == NULL)
|
||||
break;
|
||||
tkn = pos + 1;
|
||||
} while (tkn);
|
||||
- return retval;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+decode_key_description(const char *desc, struct decoded_args **arg)
|
||||
+{
|
||||
+ pid_t pid;
|
||||
+ pid_t rc;
|
||||
+ int status;
|
||||
+
|
||||
+ /*
|
||||
+ * Do all the decoding/string processing in a child process
|
||||
+ * with low privileges.
|
||||
+ */
|
||||
+
|
||||
+ *arg = mmap(NULL, sizeof(struct decoded_args), PROT_READ | PROT_WRITE,
|
||||
+ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
|
||||
+ if (*arg == MAP_FAILED) {
|
||||
+ syslog(LOG_ERR, "%s: mmap failed: %s", __func__, strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ pid = fork();
|
||||
+ if (pid < 0) {
|
||||
+ syslog(LOG_ERR, "%s: fork failed: %s", __func__, strerror(errno));
|
||||
+ munmap(*arg, sizeof(struct decoded_args));
|
||||
+ *arg = NULL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (pid == 0) {
|
||||
+ /* do the parsing in child */
|
||||
+ drop_all_capabilities();
|
||||
+ exit(__decode_key_description(desc, *arg));
|
||||
+ }
|
||||
+
|
||||
+ rc = waitpid(pid, &status, 0);
|
||||
+ if (rc < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
+ munmap(*arg, sizeof(struct decoded_args));
|
||||
+ *arg = NULL;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int setup_key(const key_serial_t key, const void *data, size_t datalen)
|
||||
@@ -1098,7 +1152,7 @@ int main(const int argc, char *const argv[])
|
||||
bool try_dns = false, legacy_uid = false , env_probe = true;
|
||||
char *buf;
|
||||
char hostbuf[NI_MAXHOST], *host;
|
||||
- struct decoded_args arg;
|
||||
+ struct decoded_args *arg = NULL;
|
||||
const char *oid;
|
||||
uid_t uid;
|
||||
char *keytab_name = NULL;
|
||||
@@ -1109,7 +1163,6 @@ int main(const int argc, char *const argv[])
|
||||
const char *key_descr = NULL;
|
||||
|
||||
hostbuf[0] = '\0';
|
||||
- memset(&arg, 0, sizeof(arg));
|
||||
|
||||
openlog(prog, 0, LOG_DAEMON);
|
||||
|
||||
@@ -1150,9 +1203,6 @@ int main(const int argc, char *const argv[])
|
||||
}
|
||||
}
|
||||
|
||||
- if (trim_capabilities(env_probe))
|
||||
- goto out;
|
||||
-
|
||||
/* is there a key? */
|
||||
if (argc <= optind) {
|
||||
usage();
|
||||
@@ -1178,6 +1228,10 @@ int main(const int argc, char *const argv[])
|
||||
|
||||
syslog(LOG_DEBUG, "key description: %s", buf);
|
||||
|
||||
+ /*
|
||||
+ * If we are requested a simple DNS query, do it and exit
|
||||
+ */
|
||||
+
|
||||
if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0)
|
||||
key_descr = ".cifs.resolver";
|
||||
else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)
|
||||
@@ -1187,33 +1241,42 @@ int main(const int argc, char *const argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
- have = decode_key_description(buf, &arg);
|
||||
+ /*
|
||||
+ * Otherwise, it's a spnego key request
|
||||
+ */
|
||||
+
|
||||
+ rc = decode_key_description(buf, &arg);
|
||||
free(buf);
|
||||
- if ((have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
|
||||
+ if (rc) {
|
||||
+ syslog(LOG_ERR, "failed to decode key description");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((arg->have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
|
||||
syslog(LOG_ERR, "unable to get necessary params from key "
|
||||
"description (0x%x)", have);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (arg.ver > CIFS_SPNEGO_UPCALL_VERSION) {
|
||||
+ if (arg->ver > CIFS_SPNEGO_UPCALL_VERSION) {
|
||||
syslog(LOG_ERR, "incompatible kernel upcall version: 0x%x",
|
||||
- arg.ver);
|
||||
+ arg->ver);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (strlen(arg.hostname) >= NI_MAXHOST) {
|
||||
+ if (strlen(arg->hostname) >= NI_MAXHOST) {
|
||||
syslog(LOG_ERR, "hostname provided by kernel is too long");
|
||||
rc = 1;
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
- if (!legacy_uid && (have & DKD_HAVE_CREDUID))
|
||||
- uid = arg.creduid;
|
||||
- else if (have & DKD_HAVE_UID)
|
||||
- uid = arg.uid;
|
||||
+ if (!legacy_uid && (arg->have & DKD_HAVE_CREDUID))
|
||||
+ uid = arg->creduid;
|
||||
+ else if (arg->have & DKD_HAVE_UID)
|
||||
+ uid = arg->uid;
|
||||
else {
|
||||
/* no uid= or creduid= parm -- something is wrong */
|
||||
syslog(LOG_ERR, "No uid= or creduid= parm specified");
|
||||
@@ -1221,6 +1284,21 @@ int main(const int argc, char *const argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Change to the process's namespace. This means that things will work
|
||||
+ * acceptably in containers, because we'll be looking at the correct
|
||||
+ * filesystem and have the correct network configuration.
|
||||
+ */
|
||||
+ rc = switch_to_process_ns(arg->pid);
|
||||
+ if (rc == -1) {
|
||||
+ syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno));
|
||||
+ rc = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (trim_capabilities(env_probe))
|
||||
+ goto out;
|
||||
+
|
||||
/*
|
||||
* The kernel doesn't pass down the gid, so we resort here to scraping
|
||||
* one out of the passwd nss db. Note that this might not reflect the
|
||||
@@ -1266,20 +1344,7 @@ int main(const int argc, char *const argv[])
|
||||
* look at the environ file.
|
||||
*/
|
||||
env_cachename =
|
||||
- get_cachename_from_process_env(env_probe ? arg.pid : 0);
|
||||
-
|
||||
- /*
|
||||
- * Change to the process's namespace. This means that things will work
|
||||
- * acceptably in containers, because we'll be looking at the correct
|
||||
- * filesystem and have the correct network configuration.
|
||||
- */
|
||||
- rc = switch_to_process_ns(arg.pid);
|
||||
- if (rc == -1) {
|
||||
- syslog(LOG_ERR, "unable to switch to process namespace: %s",
|
||||
- strerror(errno));
|
||||
- rc = 1;
|
||||
- goto out;
|
||||
- }
|
||||
+ get_cachename_from_process_env(env_probe ? arg->pid : 0);
|
||||
|
||||
rc = setuid(uid);
|
||||
if (rc == -1) {
|
||||
@@ -1301,18 +1366,18 @@ int main(const int argc, char *const argv[])
|
||||
|
||||
ccache = get_existing_cc(env_cachename);
|
||||
/* Couldn't find credcache? Try to use keytab */
|
||||
- if (ccache == NULL && arg.username != NULL)
|
||||
- ccache = init_cc_from_keytab(keytab_name, arg.username);
|
||||
+ if (ccache == NULL && arg->username[0] != '\0')
|
||||
+ ccache = init_cc_from_keytab(keytab_name, arg->username);
|
||||
|
||||
if (ccache == NULL) {
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- host = arg.hostname;
|
||||
+ host = arg->hostname;
|
||||
|
||||
// do mech specific authorization
|
||||
- switch (arg.sec) {
|
||||
+ switch (arg->sec) {
|
||||
case MS_KRB5:
|
||||
case KRB5:
|
||||
/*
|
||||
@@ -1328,7 +1393,7 @@ int main(const int argc, char *const argv[])
|
||||
* TRY only:
|
||||
* cifs/bar.example.com@REALM
|
||||
*/
|
||||
- if (arg.sec == MS_KRB5)
|
||||
+ if (arg->sec == MS_KRB5)
|
||||
oid = OID_KERBEROS5_OLD;
|
||||
else
|
||||
oid = OID_KERBEROS5;
|
||||
@@ -1385,10 +1450,10 @@ retry_new_hostname:
|
||||
break;
|
||||
}
|
||||
|
||||
- if (!try_dns || !(have & DKD_HAVE_IP))
|
||||
+ if (!try_dns || !(arg->have & DKD_HAVE_IP))
|
||||
break;
|
||||
|
||||
- rc = ip_to_fqdn(arg.ip, hostbuf, sizeof(hostbuf));
|
||||
+ rc = ip_to_fqdn(arg->ip, hostbuf, sizeof(hostbuf));
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
@@ -1396,7 +1461,7 @@ retry_new_hostname:
|
||||
host = hostbuf;
|
||||
goto retry_new_hostname;
|
||||
default:
|
||||
- syslog(LOG_ERR, "sectype: %d is not implemented", arg.sec);
|
||||
+ syslog(LOG_ERR, "sectype: %d is not implemented", arg->sec);
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
@@ -1414,7 +1479,7 @@ retry_new_hostname:
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
- keydata->version = arg.ver;
|
||||
+ keydata->version = arg->ver;
|
||||
keydata->flags = 0;
|
||||
keydata->sesskey_len = sess_key.length;
|
||||
keydata->secblob_len = secblob.length;
|
||||
@@ -1440,11 +1505,10 @@ out:
|
||||
krb5_cc_close(context, ccache);
|
||||
if (context)
|
||||
krb5_free_context(context);
|
||||
- free(arg.hostname);
|
||||
- free(arg.ip);
|
||||
- free(arg.username);
|
||||
free(keydata);
|
||||
free(env_cachename);
|
||||
+ if (arg)
|
||||
+ munmap(arg, sizeof(*arg));
|
||||
syslog(LOG_DEBUG, "Exit status %ld", rc);
|
||||
return rc;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user