Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

12 changed files with 1131 additions and 105 deletions

View File

@ -1 +1 @@
9df055a73d89ed3d536828d0cea304c9e04139d4 SOURCES/cifs-utils-7.0.tar.bz2
9df055a73d89ed3d536828d0cea304c9e04139d4 cifs-utils-7.0.tar.bz2

30
.gitignore vendored
View File

@ -1 +1,29 @@
SOURCES/cifs-utils-7.0.tar.bz2
cifs-utils-4.5.tar.bz2
cifs-utils-4.6.tar.bz2
/cifs-utils-4.7.tar.bz2
/cifs-utils-4.8.tar.bz2
/cifs-utils-4.8.1.tar.bz2
/cifs-utils-4.9.tar.bz2
/cifs-utils-5.0.tar.bz2
/cifs-utils-5.1.tar.bz2
/cifs-utils-5.2.tar.bz2
/cifs-utils-5.3.tar.bz2
/cifs-utils-5.4.tar.bz2
/cifs-utils-5.5.tar.bz2
/cifs-utils-5.6.tar.bz2
/cifs-utils-5.7.tar.bz2
/cifs-utils-5.8.tar.bz2
/cifs-utils-5.9.tar.bz2
/cifs-utils-6.0.tar.bz2
/cifs-utils-6.1.tar.bz2
/cifs-utils-6.2.tar.bz2
/cifs-utils-6.3.tar.bz2
/cifs-utils-6.4.tar.bz2
/cifs-utils-6.5.tar.bz2
/cifs-utils-6.6.tar.bz2
/cifs-utils-6.7.tar.bz2
/cifs-utils-6.8.tar.bz2
/cifs-utils-6.9.tar.bz2
/cifs-utils-6.11.tar.bz2
/cifs-utils-6.14.tar.bz2
/cifs-utils-7.0.tar.bz2

View File

@ -0,0 +1,781 @@
From 770e891a8b7ad53d4d700e08cf8d3154028b4588 Mon Sep 17 00:00:00 2001
From: David Voit <david.voit@gmail.com>
Date: Wed, 3 Apr 2024 07:24:48 +0200
Subject: [PATCH] Implement CLDAP Ping to find the closest site
For domain based DFS we always need to contact the domain controllers.
On setups, which are using bigger AD installations you could get random dc on the other side of the world,
if you don't have site support. This can lead to network timeouts and other problems.
CLDAP-Ping uses ASN.1 + UDP (CLDAP) and custom-DCE encoding including DName compressions without
field separation. Finally after finding the sitename we now need to do a DNS SRV lookups to find
the correct IPs to our closest site and fill up the remaining IPs from the global list.
Signed-off-by: David Voit <david.voit@gmail.com>
---
Makefile.am | 15 ++-
cldap_ping.c | 345 +++++++++++++++++++++++++++++++++++++++++++++++++
cldap_ping.h | 14 ++
mount.cifs.c | 5 +-
resolve_host.c | 256 ++++++++++++++++++++++++++++++++----
resolve_host.h | 6 +-
6 files changed, 604 insertions(+), 37 deletions(-)
create mode 100644 cldap_ping.c
create mode 100644 cldap_ping.h
Index: cifs-utils/Makefile.am
===================================================================
--- cifs-utils.orig/Makefile.am
+++ cifs-utils/Makefile.am
@@ -3,8 +3,8 @@ ACLOCAL_AMFLAGS = -I aclocal
root_sbindir = $(ROOTSBINDIR)
root_sbin_PROGRAMS = mount.cifs
-mount_cifs_SOURCES = mount.cifs.c mtab.c resolve_host.c util.c
-mount_cifs_LDADD = $(LIBCAP) $(CAPNG_LDADD) $(RT_LDADD)
+mount_cifs_SOURCES = mount.cifs.c mtab.c $(resolve_hosts_SOURCES) util.c
+mount_cifs_LDADD = $(LIBCAP) $(CAPNG_LDADD) $(RT_LDADD) $(resolve_hosts_LDADD)
include_HEADERS = cifsidmap.h
rst_man_pages = mount.cifs.8
@@ -28,6 +28,9 @@ bin_PROGRAMS =
bin_SCRIPTS =
sbin_PROGRAMS =
+resolve_hosts_SOURCES = data_blob.c asn1.c cldap_ping.c resolve_host.c
+resolve_hosts_LDADD = -ltalloc -lresolv
+
if CONFIG_CIFSUPCALL
sbin_PROGRAMS += cifs.upcall
cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c
@@ -43,8 +46,8 @@ endif
if CONFIG_CIFSCREDS
bin_PROGRAMS += cifscreds
-cifscreds_SOURCES = cifscreds.c cifskey.c resolve_host.c util.c
-cifscreds_LDADD = -lkeyutils
+cifscreds_SOURCES = cifscreds.c cifskey.c $(resolve_hosts_SOURCES) util.c
+cifscreds_LDADD = -lkeyutils $(resolve_hosts_LDADD)
rst_man_pages += cifscreds.1
@@ -105,8 +108,8 @@ endif
if CONFIG_PAM
pam_PROGRAMS = pam_cifscreds.so
rst_man_pages += pam_cifscreds.8
-pam_cifscreds.so: pam_cifscreds.c cifskey.c resolve_host.c util.c
- $(CC) $(DEFS) $(CFLAGS) $(AM_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ -lpam -lkeyutils
+pam_cifscreds.so: pam_cifscreds.c cifskey.c $(resolve_hosts_SOURCES) util.c
+ $(CC) $(DEFS) $(CFLAGS) $(AM_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ -lpam -lkeyutils $(resolve_hosts_LDADD)
endif
Index: cifs-utils/cldap_ping.c
===================================================================
--- /dev/null
+++ cifs-utils/cldap_ping.c
@@ -0,0 +1,345 @@
+/*
+ * CLDAP Ping to find closest ClientSiteName
+ *
+ * Copyright (C) 2024 David Voit (david.voit@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <talloc.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <resolv.h>
+#include <stdbool.h>
+#include "data_blob.h"
+#include "asn1.h"
+#include "cldap_ping.h"
+
+#define LDAP_DNS_DOMAIN "DnsDomain"
+#define LDAP_DNS_DOMAIN_LEN strlen(LDAP_DNS_DOMAIN)
+#define LDAP_NT_VERSION "NtVer"
+#define LDAP_NT_VERSION_LEN strlen(LDAP_NT_VERSION)
+#define LDAP_ATTRIBUTE_NETLOGON "NetLogon"
+#define LDAP_ATTRIBUTE_NETLOGON_LEN strlen(LDAP_ATTRIBUTE_NETLOGON)
+
+
+// Parse a ASN.1 BER tag size-field, returns start of payload of tag
+char *parse_ber_size(char *buf, size_t *tag_size) {
+ size_t size = *buf & 0xff;
+ char *ret = (buf + 1);
+ if (size >= 0x81) {
+ switch (size) {
+ case 0x81:
+ size = *ret & 0xff;
+ ret += 1;
+ break;
+ case 0x82:
+ size = (*ret << 8) | (*(ret + 1) & 0xff);
+ ret += 2;
+ break;
+ case 0x83:
+ size = (*ret << 16) | (*(ret + 1) << 8) | (*(ret + 2) & 0xff);
+ ret += 3;
+ break;
+ case 0x84:
+ size = (*ret << 24) | (*(ret + 1) << 16) | (*(ret + 2) << 8) | (*(ret + 3) & 0xff);
+ ret += 4;
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ *tag_size = size;
+ return ret;
+}
+
+// simple wrapper over dn_expand which also calculates the new offset for the next compressed dn
+int read_dns_string(char *buf, size_t buf_size, char *dest, size_t dest_size, size_t *offset) {
+ int compressed_length = dn_expand((u_char *)buf, (u_char *)buf+buf_size, (u_char *)buf + *offset, dest, (int)dest_size);
+ if (compressed_length < 0) {
+ return -1;
+ }
+
+ *offset = *offset+compressed_length;
+
+ return 0;
+}
+
+// LDAP request for: (&(DnsDomain=DOMAIN_HERE)(NtVer=\\06\\00\\00\\00))
+ASN1_DATA *generate_cldap_query(char *domain) {
+ ASN1_DATA *data;
+ TALLOC_CTX *mem_ctx = talloc_init("cldap");
+
+ data = asn1_init(mem_ctx);
+ asn1_push_tag(data, ASN1_SEQUENCE(0));
+
+ // Message id
+ asn1_push_tag(data, ASN1_INTEGER);
+ asn1_write_uint8(data, 1);
+ asn1_pop_tag(data);
+
+ // SearchRequest
+ asn1_push_tag(data, ASN1_APPLICATION(3));
+
+ // empty baseObject
+ asn1_push_tag(data, ASN1_OCTET_STRING);
+ asn1_pop_tag(data);
+
+ // scope 0 = baseObject
+ asn1_push_tag(data, ASN1_ENUMERATED);
+ asn1_write_uint8(data, 0);
+ asn1_pop_tag(data);
+
+ // derefAliasses 0=neverDerefAlias
+ asn1_push_tag(data, ASN1_ENUMERATED);
+ asn1_write_uint8(data, 0);
+ asn1_pop_tag(data);
+
+ // sizeLimit
+ asn1_push_tag(data, ASN1_INTEGER);
+ asn1_write_uint8(data, 0);
+ asn1_pop_tag(data);
+
+ // timeLimit
+ asn1_push_tag(data, ASN1_INTEGER);
+ asn1_write_uint8(data, 0);
+ asn1_pop_tag(data);
+
+ // typesOnly
+ asn1_push_tag(data, ASN1_BOOLEAN);
+ asn1_write_uint8(data, 0);
+ asn1_pop_tag(data);
+
+ // AND
+ asn1_push_tag(data, ASN1_CONTEXT(0));
+ // equalityMatch
+ asn1_push_tag(data, ASN1_CONTEXT(3));
+ asn1_write_OctetString(data, LDAP_DNS_DOMAIN, LDAP_DNS_DOMAIN_LEN);
+ asn1_write_OctetString(data, domain, strlen(domain));
+ asn1_pop_tag(data);
+
+ // equalityMatch
+ asn1_push_tag(data, ASN1_CONTEXT(3));
+ asn1_write_OctetString(data, LDAP_NT_VERSION, LDAP_NT_VERSION_LEN);
+ // Bitmask NETLOGON_NT_VERSION_5 & NETLOGON_NT_VERSION_5EX -> To get NETLOGON_SAM_LOGON_RESPONSE_EX as response
+ asn1_write_OctetString(data, "\x06\x00\x00\x00", 4);
+ asn1_pop_tag(data);
+
+ // End AND
+ asn1_pop_tag(data);
+
+ asn1_push_tag(data, ASN1_SEQUENCE(0));
+ asn1_write_OctetString(data, LDAP_ATTRIBUTE_NETLOGON, LDAP_ATTRIBUTE_NETLOGON_LEN);
+ asn1_pop_tag(data);
+
+ // End SearchRequest
+ asn1_pop_tag(data);
+ // End Sequence
+ asn1_pop_tag(data);
+
+ return data;
+}
+
+// Input is a cldap response, output is a pointer to the NETLOGON_SAM_LOGON_RESPONSE_EX payload
+ssize_t extract_netlogon_section(char *buffer, size_t buffer_size, char **netlogon_payload) {
+ size_t ber_size;
+ size_t netlogon_payload_size;
+ // Not enough space to read initial sequence - not an correct cldap response
+ if (buffer_size < 7) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ // Sequence tag
+ if (*buffer != 0x30) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *message_id_tag = parse_ber_size(buffer + 1, &ber_size);
+
+ if (ber_size > buffer_size) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ if (*message_id_tag != 0x02) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *message_id = parse_ber_size(message_id_tag + 1, &ber_size);
+
+ if (ber_size != 1 || *message_id != 1) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ // SearchResultEntry
+ if (*(message_id+1) != 0x64) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *object_name_tag = parse_ber_size(message_id+2, &ber_size);
+ if (object_name_tag == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *object_name = parse_ber_size(object_name_tag+1, &ber_size);
+ if (object_name == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ if (*object_name_tag != 4 || ber_size != 0) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *partial_attribute_list_tag = parse_ber_size(object_name+1, &ber_size);
+ if (partial_attribute_list_tag == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ if (*partial_attribute_list_tag != 0x30) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+
+ char *partial_attribute_tag = parse_ber_size(partial_attribute_list_tag+1, &ber_size);
+ if (partial_attribute_tag == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *attribute_name = parse_ber_size(partial_attribute_tag+1, &ber_size);
+ if (attribute_name == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ if (ber_size != LDAP_ATTRIBUTE_NETLOGON_LEN) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ if (strncasecmp(LDAP_ATTRIBUTE_NETLOGON, attribute_name, LDAP_ATTRIBUTE_NETLOGON_LEN) != 0) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ // SET
+ if (*(attribute_name+LDAP_ATTRIBUTE_NETLOGON_LEN) != 0x31) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ char *start_of_data = parse_ber_size(attribute_name+LDAP_ATTRIBUTE_NETLOGON_LEN+1, &ber_size);
+ if (start_of_data == NULL) {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ // octat-string of NetLogon data
+ if (*start_of_data != '\x04') {
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ *netlogon_payload = parse_ber_size(start_of_data + 1, &netlogon_payload_size);
+
+ if (*netlogon_payload == NULL) {
+ *netlogon_payload = NULL;
+ return CLDAP_PING_PARSE_ERROR_LDAP;
+ }
+
+ return (ssize_t)netlogon_payload_size;
+}
+
+int netlogon_get_client_site(char *netlogon_response, size_t netlogon_size, char *sitename) {
+ // 24 mandatory bytes
+ if (netlogon_size < 25) {
+ return CLDAP_PING_PARSE_ERROR_NETLOGON;
+ }
+
+ // LOGON_SAM_PAUSE_RESPONSE_EX -> Netlogon service is not in-sync try next dc instead
+ if (*netlogon_response == 0x18 && *(netlogon_response + 1) == 0x00) {
+ return CLDAP_PING_TRYNEXT;
+ }
+
+ // NETLOGON_SAM_LOGON_RESPONSE_EX Opcode: 0x17
+ if (*netlogon_response != 0x17 || *(netlogon_response + 1) != 0x00) {
+ return CLDAP_PING_PARSE_ERROR_NETLOGON;
+ }
+
+ // skip over sbz, ds_flags and domain_guid
+ // and start directly at variable string portion of NETLOGON_SAM_LOGON_RESPONSE_EX
+ size_t offset = 24;
+
+ for (int i=0; i < 8; i++) {
+ // iterate over DnsForestName, DnsDomainName, NetbiosDomainName, NetbiosComputerName, UserName, DcSiteName
+ // to finally get to our desired ClientSiteName field
+ if (read_dns_string(netlogon_response, netlogon_size, sitename, MAXCDNAME, &offset) < 0) {
+ return CLDAP_PING_PARSE_ERROR_NETLOGON;
+ }
+ }
+
+ return 0;
+}
+
+int cldap_ping(char *domain, sa_family_t family, void *addr, char *site_name) {
+ char buffer[8196];
+ ssize_t response_size;
+ char *netlogon_response;
+ ssize_t netlogon_size;
+ struct sockaddr_storage socketaddr;
+ size_t addr_size;
+ int sock = socket(family, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ return CLDAP_PING_NETWORK_ERROR;
+ }
+
+ ASN1_DATA *data = generate_cldap_query(domain);
+
+ if (family == AF_INET6) {
+ addr_size = sizeof(struct sockaddr_in6);
+ bzero((void *) &socketaddr, addr_size);
+ socketaddr.ss_family = AF_INET6;
+ ((struct sockaddr_in6 *)&socketaddr)->sin6_addr = *((struct in6_addr*)addr);
+ ((struct sockaddr_in6 *)&socketaddr)->sin6_port = htons(389);
+ } else {
+ addr_size = sizeof(struct sockaddr_in);
+ bzero((void *) &socketaddr, addr_size);
+ socketaddr.ss_family = AF_INET;
+ ((struct sockaddr_in *)&socketaddr)->sin_addr = *((struct in_addr*)addr);
+ ((struct sockaddr_in *)&socketaddr)->sin_port = htons(389);
+ }
+
+ struct timeval timeout = {.tv_sec = 2, .tv_usec = 0};
+ if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
+ return CLDAP_PING_NETWORK_ERROR;
+ }
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
+ return CLDAP_PING_NETWORK_ERROR;
+ }
+
+ if (sendto(sock, data->data, data->length, 0, (struct sockaddr *)&socketaddr, addr_size) < 0) {
+ close(sock);
+ return CLDAP_PING_TRYNEXT;
+ }
+
+ asn1_free(data);
+ response_size = recv(sock, buffer, sizeof(buffer), 0);
+ close(sock);
+
+ if (response_size < 0) {
+ return CLDAP_PING_TRYNEXT;
+ }
+
+ netlogon_size = extract_netlogon_section(buffer, response_size, &netlogon_response);
+ if (netlogon_size < 0) {
+ return (int)netlogon_size;
+ }
+
+ return netlogon_get_client_site(netlogon_response, netlogon_size, site_name);
+}
Index: cifs-utils/cldap_ping.h
===================================================================
--- /dev/null
+++ cifs-utils/cldap_ping.h
@@ -0,0 +1,14 @@
+#ifndef _CLDAP_PING_H_
+#define _CLDAP_PING_H_
+
+#define CLDAP_PING_NETWORK_ERROR -1
+#define CLDAP_PING_TRYNEXT -2
+#define CLDAP_PING_PARSE_ERROR_LDAP -3
+#define CLDAP_PING_PARSE_ERROR_NETLOGON -4
+
+// returns CLDAP_PING_TRYNEXT if you should use another dc
+// any other error code < 0 is a fatal error
+// site_name must be of MAXCDNAME size!
+int cldap_ping(char *domain, sa_family_t family, void *addr, char *site_name);
+
+#endif /* _CLDAP_PING_H_ */
Index: cifs-utils/mount.cifs.c
===================================================================
--- cifs-utils.orig/mount.cifs.c
+++ cifs-utils/mount.cifs.c
@@ -1889,8 +1889,11 @@ assemble_mountinfo(struct parsed_mount_i
if (rc)
goto assemble_exit;
- if (parsed_info->addrlist[0] == '\0')
+ if (parsed_info->addrlist[0] == '\0') {
rc = resolve_host(parsed_info->host, parsed_info->addrlist);
+ if (rc == 0 && parsed_info->verboseflag)
+ fprintf(stderr, "Host \"%s\" resolved to the following IP addresses: %s\n", parsed_info->host, parsed_info->addrlist);
+ }
switch (rc) {
case EX_USAGE:
Index: cifs-utils/resolve_host.c
===================================================================
--- cifs-utils.orig/resolve_host.c
+++ cifs-utils/resolve_host.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2010 Jeff Layton (jlayton@samba.org)
* Copyright (C) 2010 Igor Druzhinin (jaxbrigs@gmail.com)
+ * Copyright (C) 2024 David Voit (david.voit@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,15 +28,16 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <resolv.h>
#include "mount.h"
#include "util.h"
+#include "cldap_ping.h"
#include "resolve_host.h"
/*
* resolve hostname to comma-separated list of address(es)
*/
-int resolve_host(const char *host, char *addrstr)
-{
+int resolve_host(const char *host, char *addrstr) {
int rc;
/* 10 for max width of decimal scopeid */
char tmpbuf[NI_MAXHOST + 1 + 10 + 1];
@@ -44,6 +46,7 @@ int resolve_host(const char *host, char
struct addrinfo *addrlist, *addr;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
+ size_t count_v4 = 0, count_v6 = 0;
rc = getaddrinfo(host, NULL, NULL, &addrlist);
if (rc != 0)
@@ -59,34 +62,45 @@ int resolve_host(const char *host, char
}
switch (addr->ai_addr->sa_family) {
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *)addr->ai_addr;
- ipaddr = inet_ntop(AF_INET6, &sin6->sin6_addr, tmpbuf,
- sizeof(tmpbuf));
- if (!ipaddr) {
- rc = EX_SYSERR;
- goto resolve_host_out;
- }
-
- if (sin6->sin6_scope_id) {
- len = strnlen(tmpbuf, sizeof(tmpbuf));
- snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%%%u",
- sin6->sin6_scope_id);
- }
- break;
- case AF_INET:
- sin = (struct sockaddr_in *)addr->ai_addr;
- ipaddr = inet_ntop(AF_INET, &sin->sin_addr, tmpbuf,
- sizeof(tmpbuf));
- if (!ipaddr) {
- rc = EX_SYSERR;
- goto resolve_host_out;
- }
-
- break;
- default:
- addr = addr->ai_next;
- continue;
+ case AF_INET6:
+ count_v6++;
+ if (count_v6 + count_v4 > MAX_ADDRESSES) {
+ addr = addr->ai_next;
+ continue;
+ }
+
+ sin6 = (struct sockaddr_in6 *) addr->ai_addr;
+ ipaddr = inet_ntop(AF_INET6, &sin6->sin6_addr, tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+
+
+ if (sin6->sin6_scope_id) {
+ len = strnlen(tmpbuf, sizeof(tmpbuf));
+ snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%%%u",
+ sin6->sin6_scope_id);
+ }
+ break;
+ case AF_INET:
+ count_v4++;
+ if (count_v6 + count_v4 > MAX_ADDRESSES) {
+ addr = addr->ai_next;
+ continue;
+ }
+ sin = (struct sockaddr_in *) addr->ai_addr;
+ ipaddr = inet_ntop(AF_INET, &sin->sin_addr, tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+ break;
+ default:
+ addr = addr->ai_next;
+ continue;
}
if (addr == addrlist)
@@ -98,6 +112,192 @@ int resolve_host(const char *host, char
addr = addr->ai_next;
}
+
+ // Is this a DFS domain where we need to do a cldap ping to find the closest node?
+ if (count_v4 > 1 || count_v6 > 1) {
+ int res;
+ ns_msg global_domain_handle;
+ unsigned char global_domain_lookup[4096];
+ ns_msg site_domain_handle;
+ unsigned char site_domain_lookup[4096];
+ char dname[MAXCDNAME];
+ int srv_cnt;
+
+ res = res_init();
+ if (res != 0)
+ goto resolve_host_out;
+
+ res = snprintf(dname, MAXCDNAME, "_ldap._tcp.dc._msdcs.%s", host);
+ if (res < 0)
+ goto resolve_host_out;
+
+ res = res_query(dname, C_IN, ns_t_srv, global_domain_lookup, sizeof(global_domain_lookup));
+ if (res < 0)
+ goto resolve_host_out;
+
+ // res is also the size of the response_buffer
+ res = ns_initparse(global_domain_lookup, res, &global_domain_handle);
+ if (res < 0)
+ goto resolve_host_out;
+
+ srv_cnt = ns_msg_count (global_domain_handle, ns_s_an);
+
+ // No or just one DC we are done
+ if (srv_cnt < 2)
+ goto resolve_host_out;
+
+ char site_name[MAXCDNAME];
+ // We assume that AD always sends the ip addresses in the addtional data block
+ for (int i = 0; i < ns_msg_count(global_domain_handle, ns_s_ar); i++) {
+ ns_rr rr;
+ res = ns_parserr(&global_domain_handle, ns_s_ar, i, &rr);
+ if (res < 0)
+ goto resolve_host_out;
+
+ switch (ns_rr_type(rr)) {
+ case ns_t_aaaa:
+ if (ns_rr_rdlen(rr) != NS_IN6ADDRSZ)
+ continue;
+ res = cldap_ping((char *) host, AF_INET6, (void *)ns_rr_rdata(rr), site_name);
+ break;
+ case ns_t_a:
+ if (ns_rr_rdlen(rr) != NS_INADDRSZ)
+ continue;
+ res = cldap_ping((char *) host, AF_INET, (void *)ns_rr_rdata(rr), site_name);
+ break;
+ default:
+ continue;
+ }
+
+ if (res == CLDAP_PING_TRYNEXT) {
+ continue;
+ }
+
+ if (res < 0) {
+ goto resolve_host_out;
+ }
+
+ if (site_name[0] == '\0') {
+ goto resolve_host_out;
+ } else {
+ // site found - leave loop
+ break;
+ }
+ }
+
+ res = snprintf(dname, MAXCDNAME, "_ldap._tcp.%s._sites.dc._msdcs.%s", site_name, host);
+ if (res < 0) {
+ goto resolve_host_out;
+ }
+
+ res = res_query(dname, C_IN, ns_t_srv, site_domain_lookup, sizeof(site_domain_lookup));
+ if (res < 0)
+ goto resolve_host_out;
+
+ // res is also the size of the response_buffer
+ res = ns_initparse(site_domain_lookup, res, &site_domain_handle);
+ if (res < 0)
+ goto resolve_host_out;
+
+ int number_addresses = 0;
+ for (int i = 0; i < ns_msg_count(site_domain_handle, ns_s_ar); i++) {
+ if (i > MAX_ADDRESSES)
+ break;
+
+ ns_rr rr;
+ res = ns_parserr(&site_domain_handle, ns_s_ar, i, &rr);
+ if (res < 0)
+ goto resolve_host_out;
+
+ switch (ns_rr_type(rr)) {
+ case ns_t_aaaa:
+ if (ns_rr_rdlen(rr) != NS_IN6ADDRSZ)
+ continue;
+ ipaddr = inet_ntop(AF_INET6, ns_rr_rdata(rr), tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+ break;
+ case ns_t_a:
+ if (ns_rr_rdlen(rr) != NS_INADDRSZ)
+ continue;
+ ipaddr = inet_ntop(AF_INET, ns_rr_rdata(rr), tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+ break;
+ default:
+ continue;
+ }
+
+ number_addresses++;
+
+ if (i == 0)
+ *addrstr = '\0';
+ else
+ strlcat(addrstr, ",", MAX_ADDR_LIST_LEN);
+
+ strlcat(addrstr, tmpbuf, MAX_ADDR_LIST_LEN);
+ }
+
+ // Preferred site ips is now the first entry in addrstr, fill up with other sites till MAX_ADDRESS
+ for (int i = 0; i < ns_msg_count(global_domain_handle, ns_s_ar); i++) {
+ if (number_addresses > MAX_ADDRESSES)
+ break;
+
+ ns_rr rr;
+ res = ns_parserr(&global_domain_handle, ns_s_ar, i, &rr);
+ if (res < 0)
+ goto resolve_host_out;
+
+ switch (ns_rr_type(rr)) {
+ case ns_t_aaaa:
+ if (ns_rr_rdlen(rr) != NS_IN6ADDRSZ)
+ continue;
+ ipaddr = inet_ntop(AF_INET6, ns_rr_rdata(rr), tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+ break;
+ case ns_t_a:
+ if (ns_rr_rdlen(rr) != NS_INADDRSZ)
+ continue;
+ ipaddr = inet_ntop(AF_INET, ns_rr_rdata(rr), tmpbuf,
+ sizeof(tmpbuf));
+ if (!ipaddr) {
+ rc = EX_SYSERR;
+ goto resolve_host_out;
+ }
+ break;
+ default:
+ continue;
+ }
+
+ char *found = strstr(addrstr, tmpbuf);
+
+ if (found) {
+ // We only have a real match if the substring is between ',' or it's the last/first entry in the list
+ char previous_seperator = found > addrstr ? *(found-1) : '\0';
+ char next_seperator = *(found+strlen(tmpbuf));
+
+ if ((next_seperator == ',' || next_seperator == '\0')
+ && (previous_seperator == ',' || previous_seperator == '\0')) {
+ continue;
+ }
+ }
+
+ number_addresses++;
+ strlcat(addrstr, ",", MAX_ADDR_LIST_LEN);
+ strlcat(addrstr, tmpbuf, MAX_ADDR_LIST_LEN);
+ }
+ }
+
resolve_host_out:
freeaddrinfo(addrlist);
return rc;
Index: cifs-utils/resolve_host.h
===================================================================
--- cifs-utils.orig/resolve_host.h
+++ cifs-utils/resolve_host.h
@@ -26,8 +26,10 @@
/* currently maximum length of IPv6 address string */
#define MAX_ADDRESS_LEN INET6_ADDRSTRLEN
-/* limit list of addresses to 16 max-size addrs */
-#define MAX_ADDR_LIST_LEN ((MAX_ADDRESS_LEN + 1) * 16)
+#define MAX_ADDRESSES 16
+
+/* limit list of addresses to MAX_ADDRESSES max-size addrs */
+#define MAX_ADDR_LIST_LEN ((MAX_ADDRESS_LEN + 1) * MAX_ADDRESSES)
extern int resolve_host(const char *host, char *addrstr);

View File

@ -1,55 +0,0 @@
From 17162396d9ace9396c27826f1c62719186e29ae9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipensky@samba.org>
Date: Fri, 20 Jan 2023 20:53:44 +0100
Subject: [PATCH] Use explicit #!/usr/bin/python3
---
checkopts | 2 +-
smb2-quota | 2 +-
smb2-secdesc | 2 +-
smbinfo | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/checkopts b/checkopts
index 88e70b1..00c4cfd 100755
--- a/checkopts
+++ b/checkopts
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/python3
#
# Script to check for inconsistencies between documented mount options
# and implemented kernel options.
diff --git a/smb2-quota b/smb2-quota
index 6d0b8a3..49207c7 100755
--- a/smb2-quota
+++ b/smb2-quota
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
# coding: utf-8
#
# smb2-quota is a cmdline tool to display quota information for the
diff --git a/smb2-secdesc b/smb2-secdesc
index 5886091..534dd92 100755
--- a/smb2-secdesc
+++ b/smb2-secdesc
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
# coding: utf-8
import array
diff --git a/smbinfo b/smbinfo
index 73c5bb3..766024e 100755
--- a/smbinfo
+++ b/smbinfo
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# smbinfo is a cmdline tool to query SMB-specific file and fs
--
2.38.1

19
cifs-utils-destdir.patch Normal file
View File

@ -0,0 +1,19 @@
diff -up cifs-utils-6.11/Makefile.am.orig cifs-utils-6.11/Makefile.am
--- cifs-utils-6.11/Makefile.am.orig 2020-11-02 10:12:50.076702518 +0200
+++ cifs-utils-6.11/Makefile.am 2020-11-02 10:13:41.966420633 +0200
@@ -119,11 +119,11 @@ endif
SUBDIRS = contrib
install-exec-hook:
- (cd $(ROOTSBINDIR) && ln -sf mount.cifs mount.smb3)
+ (cd $(DESTDIR)$(ROOTSBINDIR) && ln -sf mount.cifs mount.smb3)
install-data-hook:
- (cd $(man8dir) && ln -sf mount.cifs.8 mount.smb3.8)
+ (cd $(DESTDIR)$(man8dir) && ln -sf mount.cifs.8 mount.smb3.8)
uninstall-hook:
- (cd $(ROOTSBINDIR) && rm -f $(ROOTSBINDIR)/mount.smb3)
- (cd $(man8dir) && rm -f $(man8dir)/mount.smb3.8)
+ (cd $(DESTDIR)$(ROOTSBINDIR) && rm -f $(DESTDIR)$(ROOTSBINDIR)/mount.smb3)
+ (cd $(DESTDIR)$(man8dir) && rm -f $(DESTDIR)$(man8dir)/mount.smb3.8)

View File

@ -3,22 +3,29 @@
Name: cifs-utils
Version: 7.0
Release: 1%{pre_release}%{?dist}
Release: 5%{pre_release}%{?dist}
Summary: Utilities for mounting and managing CIFS mounts
Group: System Environment/Daemons
License: GPLv3
URL: http://linux-cifs.samba.org/cifs-utils/
BuildRequires: libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel pam-devel
BuildRequires: python3-docutils
BuildRequires: gcc
BuildRequires: libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel pam-devel
BuildRequires: python3-docutils
BuildRequires: make
Requires: keyutils
Requires(post): /usr/sbin/alternatives
Requires(preun): /usr/sbin/alternatives
Recommends: %{name}-info%{?_isa} = %{version}-%{release}
Source0: https://download.samba.org/pub/linux-cifs/cifs-utils/%{name}-%{version}.tar.bz2
Patch1: 0001-Use-explicit-usr-bin-python3.patch
Patch0: cifs.upcall-fix-UAF-in-get_cachename_from_process_en.patch
Patch1: pam_cifscreds-fix-warning-on-NULL-arg-passed-to-s-in.patch
Patch2: mount.cifs.rst-add-missing-reference-for-sssd.patch
Patch3: mount.cifs.rst-update-section-about-xattr-acl-suppor.patch
Patch4: Implement-CLDAP-Ping-to-find-the-closest-site.patch
%description
The SMB/CIFS protocol is a standard file sharing protocol widely deployed
@ -30,7 +37,6 @@ file system.
%package devel
Summary: Files needed for building plugins for cifs-utils
Group: Development/Libraries
%description devel
The SMB/CIFS protocol is a standard file sharing protocol widely deployed
@ -39,7 +45,6 @@ necessary for building ID mapping plugins for cifs-utils.
%package -n pam_cifscreds
Summary: PAM module to manage NTLM credentials in kernel keyring
Group: System Environment/Base
%description -n pam_cifscreds
The pam_cifscreds PAM module is a tool for automatically adding
@ -53,9 +58,14 @@ provide these credentials to the kernel automatically at login.
%prep
%setup -q -n %{name}-%{version}%{pre_release}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
fgrep -r -l '/usr/bin/env python' | xargs -n1 sed -i 's@/usr/bin/env python.*@%python3@g'
autoreconf -i
%configure --prefix=/usr ROOTSBINDIR=%{_sbindir}
make %{?_smp_mflags}
@ -69,29 +79,24 @@ install -m 644 contrib/request-key.d/cifs.idmap.conf %{buildroot}%{_sysconfdir}/
install -m 644 contrib/request-key.d/cifs.spnego.conf %{buildroot}%{_sysconfdir}/request-key.d
%files
%defattr(-,root,root,-)
%doc
%{_bindir}/getcifsacl
%{_bindir}/setcifsacl
%{_bindir}/cifscreds
%{_bindir}/smbinfo
%{_bindir}/smb2-quota
%{_sbindir}/mount.cifs
%{_sbindir}/mount.smb3
%{_sbindir}/cifs.upcall
%{_sbindir}/cifs.idmap
%dir %{_libdir}/%{name}
%{_libdir}/%{name}/idmapwb.so
%{_mandir}/man1/getcifsacl.1.gz
%{_mandir}/man1/setcifsacl.1.gz
%{_mandir}/man1/cifscreds.1.gz
%{_mandir}/man1/smbinfo.1.gz
%{_mandir}/man1/smb2-quota.1.gz
%{_mandir}/man8/cifs.upcall.8.gz
%{_mandir}/man8/cifs.idmap.8.gz
%{_mandir}/man8/mount.cifs.8.gz
%{_mandir}/man8/mount.smb3.8.gz
%{_mandir}/man8/idmapwb.8.gz
%{_mandir}/man1/getcifsacl.*
%{_mandir}/man1/setcifsacl.*
%{_mandir}/man1/cifscreds.*
%{_mandir}/man8/cifs.upcall.*
%{_mandir}/man8/cifs.idmap.*
%{_mandir}/man8/mount.cifs.*
%{_mandir}/man8/mount.smb3.*
%{_mandir}/man8/idmapwb.*
%dir %{_sysconfdir}/cifs-utils
%ghost %{_sysconfdir}/cifs-utils/idmap-plugin
%config(noreplace) %{_sysconfdir}/request-key.d/cifs.idmap.conf
@ -112,39 +117,86 @@ fi
%{_libdir}/security/pam_cifscreds.so
%{_mandir}/man8/pam_cifscreds.8.gz
# This subpackage also serves the purpose of avoiding a Python dependency on
# the main package: https://bugzilla.redhat.com/show_bug.cgi?id=1909288.
%package info
Summary: Additional tools for querying information about CIFS mount
Requires: %{name}%{?_isa} = %{version}-%{release}
%description info
This subpackage includes additional tools for querying information
about CIFS mount.
%files info
%{_bindir}/smb2-quota
%{_bindir}/smbinfo
%{_mandir}/man1/smb2-quota.*
%{_mandir}/man1/smbinfo.*
%changelog
* Mon Apr 22 2024 Paulo Alcantara <paalcant@redhat.com> - 7.0-5
- Implement CLDAP Ping to find the closest site
- Resolves: RHELPLAN-17597
* Tue Apr 16 2024 Paulo Alcantara <paalcant@redhat.com> - 7.0-4
- mount.cifs.rst: add missing reference for sssd
- mount.cifs.rst: update section about xattr/acl support
- Resolves: RHEL-22495
* Fri Apr 12 2024 Paulo Alcantara <paalcant@redhat.com> - 7.0-3
- pam_cifscreds: fix NULL arg warning passed to pam_syslog()
- Resolves: RHEL-28050
* Fri Apr 12 2024 Paulo Alcantara <paalcant@redhat.com> - 7.0-2
- cifs.upcall: fix UAF in get_cachename_from_process_env()
- Resolves: RHEL-28047
* Mon Jan 30 2023 Pavel Filipenský <pfilipen@redhat.com> - 7.0-1
- Update to cifs-utils-7.0
- Resolves: rhbz#2163373
- Resolves: rhbz#2163303
* Thu Dec 12 2019 Sachin Prabhu <sprabhu@redhat.com> - 6.8-3
- Add manual gating tests
- docs: cleanup rst formating
- mount.cifs.rst: document new (no)handlecache mount option
- manpage: update mount.cifs manpage with info about rdma option
- checkopts: add python script to cross check mount options
- mount.cifs.rst: document missing options, correct wrong ones
- checkopts: report duplicated options in man page
- mount.cifs.rst: more cleanups
- mount.cifs.rst: document vers=3 mount option
- mount.cifs.rst: document vers=3.02 mount option
- cifs: Allow DNS resolver key to expire
- mount.cifs: be more verbose and helpful regarding mount errors
- Update mount.cifs with vers=default mount option and SMBv3.0.2
- mount.cifs.rst: update vers=3.1.1 option description
- getcifsacl: Do not go to parse_sec_desc if getxattr fails.
- getcifsacl: Improve help usage and add -h option.
- setcifsacl: fix adding ACE when owner sid in unexpected location
- cifs.upcall: fix a compiler warning
- mount.cifs Add various missing parms from the help text
- mount.cifs: add more options to help message
- mount.cifs: detect GMT format of snapshot version
- Update man page for mount.cifs to add new options
- mount.cifs.rst: mention kernel version for snapshots
- Fix authors and maintainers
* Wed Feb 02 2022 Alexander Bokovoy <abokovoy@redhat.com> - 6.14
- Update to v6.14 release
- Resolves: rhbz#1925956
* Tue Jul 17 2018 Alexander Bokovoy <abokovoy@redhat.com> - 6.8-2
- Use Python 3 version of rst2man utility for generating man pages
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 6.11-5
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 6.11-4
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 6.11-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Dec 18 2020 Jonathan Lebon <jonathan@jlebon.com> - 6.11-2
- Split out -info subpackage for smb2-quota and smbinfo
https://bugzilla.redhat.com/show_bug.cgi?id=1909288
* Mon Nov 02 2020 Alexander Bokovoy <abokovoy@redhat.com> - 6.11-1
- Update to v6.11 release
- Resolves: rhbz#1876400 - CVE-2020-14342 - cifs-utils: shell command injection
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 6.9-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 6.9-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 6.9-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Apr 21 2019 Jeff Layton <jlayton@redhat.com>- 6.9-1
- Update to v6.9 release
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 6.8-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Tue Jul 17 2018 Alexander Bokovoy <abokovoy@redhat.com> - 6.8-3
- Use Python 3 version of rst2man
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 6.8-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Apr 10 2018 Fedora Release Engineering <releng@fedoraproject.org> - 6.8-1
- update to 6.8 release

View File

@ -0,0 +1,46 @@
From 73146385da0945c78af0fbdc08d2bf260db709d5 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <pc@manguebit.com>
Date: Fri, 8 Mar 2024 12:06:15 -0300
Subject: [PATCH] cifs.upcall: fix UAF in get_cachename_from_process_env()
Whether lseek(2) fails or @bufsize * 2 > ENV_BUF_MAX, then @buf would
end up being freed twice. For instance:
cifs-utils-7.0/cifs.upcall.c:501: freed_arg: "free" frees "buf".
cifs-utils-7.0/cifs.upcall.c:524: double_free: Calling "free" frees
pointer "buf" which has already been freed.
522| }
523| out_close:
524|-> free(buf);
525| close(fd);
526| return cachename;
Fix this by setting @buf to NULL after freeing it to prevent UAF.
Fixes: ed97e4ecab4e ("cifs.upcall: allow scraping of KRB5CCNAME out of initiating task's /proc/<pid>/environ file")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
---
cifs.upcall.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/cifs.upcall.c b/cifs.upcall.c
index 52c03280dbe0..ff6f2bd271bc 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -498,10 +498,11 @@ retry:
/* We read to the end of the buffer. Double and try again */
syslog(LOG_DEBUG, "%s: read to end of buffer (%zu bytes)\n",
__func__, bufsize);
- free(buf);
- bufsize *= 2;
if (lseek(fd, 0, SEEK_SET) < 0)
goto out_close;
+ free(buf);
+ buf = NULL;
+ bufsize *= 2;
goto retry;
}
--
2.44.0

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: manual.sst_filesystems.cifs-utils.buildbot}

View File

@ -0,0 +1,49 @@
From e7ec0032898d855be144c0cdc9d9e3f78ae01bf2 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <pc@manguebit.com>
Date: Sun, 10 Mar 2024 22:24:24 -0300
Subject: [PATCH 1/2] mount.cifs.rst: add missing reference for sssd
Reference sssd in mount.cifs(8) as it can be used instead of winbind
via cifs.idmap utility. It's also enabled by default in most systems.
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
---
mount.cifs.rst | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/mount.cifs.rst b/mount.cifs.rst
index 3becf200e038..64127b23cf17 100644
--- a/mount.cifs.rst
+++ b/mount.cifs.rst
@@ -773,10 +773,10 @@ specified in the following Microsoft TechNet document:
In order to map SIDs to/from UIDs and GIDs, the following is required:
- a kernel upcall to the ``cifs.idmap`` utility set up via request-key.conf(5)
-- winbind support configured via nsswitch.conf(5) and smb.conf(5)
+- winbind or sssd support configured via nsswitch.conf(5)
-Please refer to the respective manpages of cifs.idmap(8) and
-winbindd(8) for more information.
+Please refer to the respective manpages of cifs.idmap(8), winbindd(8)
+and sssd(8) for more information.
Security descriptors for a file object can be retrieved and set
directly using extended attribute named ``system.cifs_acl``. The
@@ -792,10 +792,10 @@ Some of the things to consider while using this mount option:
- The mapping between a CIFS/NTFS ACL and POSIX file permission bits
is imperfect and some ACL information may be lost in the
translation.
-- If either upcall to cifs.idmap is not setup correctly or winbind is
- not configured and running, ID mapping will fail. In that case uid
- and gid will default to either to those values of the share or to
- the values of uid and/or gid mount options if specified.
+- If either upcall to cifs.idmap is not setup correctly or winbind or
+ sssd is not configured and running, ID mapping will fail. In that
+ case uid and gid will default to either to those values of the share
+ or to the values of uid and/or gid mount options if specified.
**********************************
ACCESSING FILES WITH BACKUP INTENT
--
2.44.0

View File

@ -0,0 +1,59 @@
From 4718e09e4b15b957bf9d729793bc3de7caad8134 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <pc@manguebit.com>
Date: Sun, 10 Mar 2024 22:24:25 -0300
Subject: [PATCH 2/2] mount.cifs.rst: update section about xattr/acl support
Update section about required xattr/acl support for UID/GID mapping.
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
---
mount.cifs.rst | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/mount.cifs.rst b/mount.cifs.rst
index 64127b23cf17..d82a13c932b3 100644
--- a/mount.cifs.rst
+++ b/mount.cifs.rst
@@ -321,11 +321,12 @@ soft
noacl
Do not allow POSIX ACL operations even if server would support them.
- The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to Samba
- servers version 3.0.10 and later. Setting POSIX ACLs requires enabling
- both ``CIFS_XATTR`` and then ``CIFS_POSIX`` support in the CIFS
- configuration options when building the cifs module. POSIX ACL support
- can be disabled on a per mount basis by specifying ``noacl`` on mount.
+ The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to
+ Samba servers version 3.0.10 and later. Setting POSIX ACLs requires
+ enabling both ``CONFIG_CIFS_XATTR`` and then ``CONFIG_CIFS_POSIX``
+ support in the CIFS configuration options when building the cifs
+ module. POSIX ACL support can be disabled on a per mount basis by
+ specifying ``noacl`` on mount.
cifsacl
This option is used to map CIFS/NTFS ACLs to/from Linux permission
@@ -762,8 +763,19 @@ bits, and POSIX ACL as user authentication model. This is the most
common authentication model for CIFS servers and is the one used by
Windows.
-Support for this requires both CIFS_XATTR and CIFS_ACL support in the
-CIFS configuration options when building the cifs module.
+Support for this requires cifs kernel module built with both
+``CONFIG_CIFS_XATTR`` and ``CONFIG_CIFS_ACL`` options enabled. Since
+Linux 5.3, ``CONFIG_CIFS_ACL`` option no longer exists as CIFS/NTFS
+ACL support is always built into cifs kernel module.
+
+Most distribution kernels will already have those options enabled by
+default, but you can still check if they are enabled with::
+
+ cat /lib/modules/$(uname -r)/build/.config
+
+Alternatively, if kernel is configured with ``CONFIG_IKCONFIG_PROC``::
+
+ zcat /proc/config.gz
A CIFS/NTFS ACL is mapped to file permission bits using an algorithm
specified in the following Microsoft TechNet document:
--
2.44.0

View File

@ -0,0 +1,40 @@
From dac330136368a9b8d9ccf8227f56ea35de57a4d2 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <pc@manguebit.com>
Date: Fri, 8 Mar 2024 13:25:22 -0300
Subject: [PATCH] pam_cifscreds: fix warning on NULL arg passed to %s in
pam_syslog()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix the following compiler warning with -Wformat-overflow in
cifscreds_pam_update():
pam_cifscreds.c: In function cifscreds_pam_update:
pam_cifscreds.c:340:83: warning: %s directive argument is null
[-Wformat-overflow=]
340 | pam_syslog(ph, LOG_ERR, "error: Update credential key for %s: %s",
| ^~
Fixes: cbbcd6e71c0a ("cifscreds: create PAM module to insert credentials at login")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
---
pam_cifscreds.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pam_cifscreds.c b/pam_cifscreds.c
index 5d99c2db3038..eb9851d52a7d 100644
--- a/pam_cifscreds.c
+++ b/pam_cifscreds.c
@@ -338,7 +338,7 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
key_serial_t key = key_add(currentaddress, user, password, keytype);
if (key <= 0) {
pam_syslog(ph, LOG_ERR, "error: Update credential key for %s: %s",
- currentaddress, strerror(errno));
+ (currentaddress ?: "(null)"), strerror(errno));
}
}
--
2.44.0

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (cifs-utils-7.0.tar.bz2) = 4c57741af0c4567a78f352c73caca998881666a5ed36536275cfa775efd66ff1a44ebe539a8ed96c409c5b08a1378266964ce667a27e9fc7f2d43999c63dd0eb