resolves: RHEL-146310 - Enable debug logs in cifs.upcall

Signed-off-by: Paulo Alcantara <paalcant@redhat.com>
This commit is contained in:
Paulo Alcantara 2026-02-04 11:52:29 -03:00
parent ff17c4260c
commit 82aba2541d
10 changed files with 156 additions and 589 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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

View 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

View 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

View File

@ -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

View 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

View File

@ -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

View File

@ -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;
}

View File

@ -1 +1 @@
SHA512 (cifs-utils-7.4.tar.bz2) = 36fb64ed531e983752be243be488392ba52c3797ac638147a75998b8965448009e95d7ccda187c7d50d753b0ddb87a464a83044064b099d49fffe03a0b6ba739
SHA512 (cifs-utils-7.5.tar.bz2) = d44b26ca3224160bcb4fc712eb6c6d09fcfee196197d46481e95333494eaae1a4851712fba9b922c203e3cd301c481b433ff49ec396428c12ff7db3c628ce9e9

View File

@ -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;
}