Fix DC discovery after Windows netlogon hardening.
resolves: RHEL-101761
This commit is contained in:
parent
5b2dff86bd
commit
db39c1920a
491
redhat-4.22.patch
Normal file
491
redhat-4.22.patch
Normal file
@ -0,0 +1,491 @@
|
||||
From 798d2f75bfe344256a2cb720694ed13750542bdf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
|
||||
Date: Wed, 2 Jul 2025 21:59:48 +0200
|
||||
Subject: [PATCH 1/2] s3-winbindd: Fix internal winbind dsgetdcname calls
|
||||
w.r.t. domain name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
when winbind calls to dsgetdcname internally, make sure to
|
||||
prefer the DNS domain name if we have it. Makes DNS lookups much more
|
||||
likely to succeed.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
|
||||
|
||||
Guenther
|
||||
|
||||
Signed-off-by: Guenther Deschner <gd@samba.org>
|
||||
Reviewed-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Ralph Boehme <slow@samba.org>
|
||||
|
||||
Autobuild-User(master): Ralph Böhme <slow@samba.org>
|
||||
Autobuild-Date(master): Mon Jul 7 10:44:37 UTC 2025 on atb-devel-224
|
||||
|
||||
(cherry picked from commit 2560c9b3224816ffd371a62103f65b3aca301ad5)
|
||||
---
|
||||
source3/winbindd/wb_queryuser.c | 17 +++++++++++++----
|
||||
source3/winbindd/wb_sids2xids.c | 17 +++++++++++++----
|
||||
source3/winbindd/wb_xids2sids.c | 12 +++++++++---
|
||||
source3/winbindd/winbindd_dual.c | 6 +++++-
|
||||
source3/winbindd/winbindd_proto.h | 1 +
|
||||
source3/winbindd/winbindd_util.c | 19 +++++++++++++++++++
|
||||
6 files changed, 60 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c
|
||||
index c2758f1b76a..db8e946ba71 100644
|
||||
--- a/source3/winbindd/wb_queryuser.c
|
||||
+++ b/source3/winbindd/wb_queryuser.c
|
||||
@@ -289,10 +289,19 @@ static void wb_queryuser_done(struct tevent_req *subreq)
|
||||
|
||||
if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
|
||||
!state->tried_dclookup) {
|
||||
- D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling wb_dsgetdcname_send()\n");
|
||||
- subreq = wb_dsgetdcname_send(
|
||||
- state, state->ev, state->info->domain_name, NULL, NULL,
|
||||
- DS_RETURN_DNS_NAME);
|
||||
+ const char *domain_name = find_dns_domain_name(
|
||||
+ state->info->domain_name);
|
||||
+
|
||||
+ D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling "
|
||||
+ "wb_dsgetdcname_send(%s)\n",
|
||||
+ domain_name);
|
||||
+
|
||||
+ subreq = wb_dsgetdcname_send(state,
|
||||
+ state->ev,
|
||||
+ domain_name,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ DS_RETURN_DNS_NAME);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
|
||||
index f0f6c23fc20..03e5e7e0258 100644
|
||||
--- a/source3/winbindd/wb_sids2xids.c
|
||||
+++ b/source3/winbindd/wb_sids2xids.c
|
||||
@@ -612,13 +612,22 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
|
||||
!state->tried_dclookup) {
|
||||
|
||||
struct lsa_DomainInfo *d;
|
||||
+ const char *domain_name = NULL;
|
||||
|
||||
- D_DEBUG("Domain controller not found. Calling wb_dsgetdcname_send() to get it.\n");
|
||||
d = &state->idmap_doms.domains[state->dom_index];
|
||||
|
||||
- subreq = wb_dsgetdcname_send(
|
||||
- state, state->ev, d->name.string, NULL, NULL,
|
||||
- DS_RETURN_DNS_NAME);
|
||||
+ domain_name = find_dns_domain_name(d->name.string);
|
||||
+
|
||||
+ D_DEBUG("Domain controller not found. Calling "
|
||||
+ "wb_dsgetdcname_send(%s) to get it.\n",
|
||||
+ domain_name);
|
||||
+
|
||||
+ subreq = wb_dsgetdcname_send(state,
|
||||
+ state->ev,
|
||||
+ domain_name,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ DS_RETURN_DNS_NAME);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
|
||||
index 86bd7f9deab..6fcf524d94f 100644
|
||||
--- a/source3/winbindd/wb_xids2sids.c
|
||||
+++ b/source3/winbindd/wb_xids2sids.c
|
||||
@@ -143,9 +143,15 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
|
||||
if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
|
||||
!state->tried_dclookup) {
|
||||
|
||||
- subreq = wb_dsgetdcname_send(
|
||||
- state, state->ev, state->dom_map->name, NULL, NULL,
|
||||
- DS_RETURN_DNS_NAME);
|
||||
+ const char *domain_name = find_dns_domain_name(
|
||||
+ state->dom_map->name);
|
||||
+
|
||||
+ subreq = wb_dsgetdcname_send(state,
|
||||
+ state->ev,
|
||||
+ domain_name,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ DS_RETURN_DNS_NAME);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
|
||||
index 614727aceb9..622d50c2b91 100644
|
||||
--- a/source3/winbindd/winbindd_dual.c
|
||||
+++ b/source3/winbindd/winbindd_dual.c
|
||||
@@ -532,6 +532,7 @@ static void wb_domain_request_trigger(struct tevent_req *req,
|
||||
struct wb_domain_request_state *state = tevent_req_data(
|
||||
req, struct wb_domain_request_state);
|
||||
struct winbindd_domain *domain = state->domain;
|
||||
+ const char *domain_name = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
size_t shortest_queue_length;
|
||||
|
||||
@@ -604,8 +605,11 @@ static void wb_domain_request_trigger(struct tevent_req *req,
|
||||
* which is indicated by DS_RETURN_DNS_NAME.
|
||||
* For NT4 domains we still get the netbios name.
|
||||
*/
|
||||
+
|
||||
+ domain_name = find_dns_domain_name(state->domain->name);
|
||||
+
|
||||
subreq = wb_dsgetdcname_send(state, state->ev,
|
||||
- state->domain->name,
|
||||
+ domain_name,
|
||||
NULL, /* domain_guid */
|
||||
NULL, /* site_name */
|
||||
DS_RETURN_DNS_NAME); /* flags */
|
||||
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
|
||||
index 5d428ef2845..08e1c11f29b 100644
|
||||
--- a/source3/winbindd/winbindd_proto.h
|
||||
+++ b/source3/winbindd/winbindd_proto.h
|
||||
@@ -608,6 +608,7 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
|
||||
struct dom_sid **sids, uint32_t *num_sids);
|
||||
bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
|
||||
struct unixid **pxids, uint32_t *pnum_xids);
|
||||
+const char *find_dns_domain_name(const char *domain_name);
|
||||
|
||||
/* The following definitions come from winbindd/winbindd_wins.c */
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
|
||||
index 48f4c9a67cb..ceb6a3136fb 100644
|
||||
--- a/source3/winbindd/winbindd_util.c
|
||||
+++ b/source3/winbindd/winbindd_util.c
|
||||
@@ -2230,3 +2230,22 @@ fail:
|
||||
TALLOC_FREE(xids);
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * Helper to extract the DNS Domain Name from a struct winbindd_domain
|
||||
+ */
|
||||
+const char *find_dns_domain_name(const char *domain_name)
|
||||
+{
|
||||
+ struct winbindd_domain *wbdom = NULL;
|
||||
+
|
||||
+ wbdom = find_domain_from_name(domain_name);
|
||||
+ if (wbdom == NULL) {
|
||||
+ return domain_name;
|
||||
+ }
|
||||
+
|
||||
+ if (wbdom->active_directory && wbdom->alt_name != NULL) {
|
||||
+ return wbdom->alt_name;
|
||||
+ }
|
||||
+
|
||||
+ return wbdom->name;
|
||||
+}
|
||||
--
|
||||
2.50.0
|
||||
|
||||
|
||||
From 482194ec43c575d957b1bdb419283ec6490a1a09 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 9 May 2025 09:38:41 +0200
|
||||
Subject: [PATCH 2/2] s3:winbindd: avoid using any netlogon call to get a dc
|
||||
name
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Guenther Deschner <gd@samba.org>
|
||||
Reviewed-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Ralph Boehme <slow@samba.org>
|
||||
(cherry picked from commit f86a4bf6848ade2db7229d182576db3320c3ece7)
|
||||
---
|
||||
source3/winbindd/winbindd_cm.c | 150 ---------------------------
|
||||
source3/winbindd/winbindd_dual_srv.c | 105 +------------------
|
||||
2 files changed, 5 insertions(+), 250 deletions(-)
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
|
||||
index 420ea961876..741761f606b 100644
|
||||
--- a/source3/winbindd/winbindd_cm.c
|
||||
+++ b/source3/winbindd/winbindd_cm.c
|
||||
@@ -475,140 +475,6 @@ static bool cm_is_ipc_credentials(struct cli_credentials *creds)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
|
||||
- fstring dcname,
|
||||
- struct sockaddr_storage *dc_ss,
|
||||
- uint32_t request_flags)
|
||||
-{
|
||||
- struct winbindd_domain *our_domain = NULL;
|
||||
- struct rpc_pipe_client *netlogon_pipe = NULL;
|
||||
- NTSTATUS result;
|
||||
- WERROR werr;
|
||||
- TALLOC_CTX *mem_ctx;
|
||||
- unsigned int orig_timeout;
|
||||
- const char *tmp = NULL;
|
||||
- const char *p;
|
||||
- struct dcerpc_binding_handle *b;
|
||||
-
|
||||
- /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
|
||||
- * moment.... */
|
||||
-
|
||||
- if (IS_DC) {
|
||||
- return False;
|
||||
- }
|
||||
-
|
||||
- if (domain->primary) {
|
||||
- return False;
|
||||
- }
|
||||
-
|
||||
- our_domain = find_our_domain();
|
||||
-
|
||||
- if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
|
||||
- return False;
|
||||
- }
|
||||
-
|
||||
- result = cm_connect_netlogon(our_domain, &netlogon_pipe);
|
||||
- if (!NT_STATUS_IS_OK(result)) {
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return False;
|
||||
- }
|
||||
-
|
||||
- b = netlogon_pipe->binding_handle;
|
||||
-
|
||||
- /* This call can take a long time - allow the server to time out.
|
||||
- 35 seconds should do it. */
|
||||
-
|
||||
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
|
||||
-
|
||||
- if (our_domain->active_directory) {
|
||||
- struct netr_DsRGetDCNameInfo *domain_info = NULL;
|
||||
-
|
||||
- /*
|
||||
- * TODO request flags are not respected in the server
|
||||
- * (and in some cases, like REQUIRE_PDC, causes an error)
|
||||
- */
|
||||
- result = dcerpc_netr_DsRGetDCName(b,
|
||||
- mem_ctx,
|
||||
- our_domain->dcname,
|
||||
- domain->name,
|
||||
- NULL,
|
||||
- NULL,
|
||||
- request_flags|DS_RETURN_DNS_NAME,
|
||||
- &domain_info,
|
||||
- &werr);
|
||||
- if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
|
||||
- tmp = talloc_strdup(
|
||||
- mem_ctx, domain_info->dc_unc);
|
||||
- if (tmp == NULL) {
|
||||
- DBG_ERR("talloc_strdup failed for dc_unc[%s]\n",
|
||||
- domain_info->dc_unc);
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return false;
|
||||
- }
|
||||
- if (domain->alt_name == NULL) {
|
||||
- domain->alt_name = talloc_strdup(domain,
|
||||
- domain_info->domain_name);
|
||||
- if (domain->alt_name == NULL) {
|
||||
- DBG_ERR("talloc_strdup failed for "
|
||||
- "domain_info->domain_name[%s]\n",
|
||||
- domain_info->domain_name);
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return false;
|
||||
- }
|
||||
- }
|
||||
- if (domain->forest_name == NULL) {
|
||||
- domain->forest_name = talloc_strdup(domain,
|
||||
- domain_info->forest_name);
|
||||
- if (domain->forest_name == NULL) {
|
||||
- DBG_ERR("talloc_strdup failed for "
|
||||
- "domain_info->forest_name[%s]\n",
|
||||
- domain_info->forest_name);
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return false;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- } else {
|
||||
- result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
|
||||
- our_domain->dcname,
|
||||
- domain->name,
|
||||
- &tmp,
|
||||
- &werr);
|
||||
- }
|
||||
-
|
||||
- /* And restore our original timeout. */
|
||||
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
|
||||
-
|
||||
- if (!NT_STATUS_IS_OK(result)) {
|
||||
- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
|
||||
- nt_errstr(result)));
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
|
||||
- win_errstr(werr)));
|
||||
- talloc_destroy(mem_ctx);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
|
||||
- p = strip_hostname(tmp);
|
||||
-
|
||||
- fstrcpy(dcname, p);
|
||||
-
|
||||
- talloc_destroy(mem_ctx);
|
||||
-
|
||||
- DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
|
||||
-
|
||||
- if (!resolve_name(dcname, dc_ss, 0x20, true)) {
|
||||
- return False;
|
||||
- }
|
||||
-
|
||||
- return True;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* Helper function to assemble trust password and account name
|
||||
*/
|
||||
@@ -1307,24 +1173,8 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
|
||||
struct samba_sockaddr *sa_list = NULL;
|
||||
size_t salist_size = 0;
|
||||
size_t i;
|
||||
- bool is_our_domain;
|
||||
enum security_types sec = (enum security_types)lp_security();
|
||||
|
||||
- is_our_domain = strequal(domain->name, lp_workgroup());
|
||||
-
|
||||
- /* If not our domain, get the preferred DC, by asking our primary DC */
|
||||
- if ( !is_our_domain
|
||||
- && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
|
||||
- && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
|
||||
- num_dcs) )
|
||||
- {
|
||||
- char addr[INET6_ADDRSTRLEN];
|
||||
- print_sockaddr(addr, sizeof(addr), &ss);
|
||||
- DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
|
||||
- dcname, addr));
|
||||
- return True;
|
||||
- }
|
||||
-
|
||||
if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
|
||||
char *sitename = NULL;
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
|
||||
index 2572588f6d1..e59c42dbcda 100644
|
||||
--- a/source3/winbindd/winbindd_dual_srv.c
|
||||
+++ b/source3/winbindd/winbindd_dual_srv.c
|
||||
@@ -660,106 +660,11 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p,
|
||||
|
||||
NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)
|
||||
{
|
||||
- struct winbindd_domain *domain = wb_child_domain();
|
||||
- struct rpc_pipe_client *netlogon_pipe;
|
||||
- struct netr_DsRGetDCNameInfo *dc_info;
|
||||
- NTSTATUS status;
|
||||
- WERROR werr;
|
||||
- unsigned int orig_timeout;
|
||||
- struct dcerpc_binding_handle *b;
|
||||
- bool retry = false;
|
||||
- bool try_dsrgetdcname = false;
|
||||
-
|
||||
- if (domain == NULL) {
|
||||
- return dsgetdcname(p->mem_ctx, global_messaging_context(),
|
||||
- r->in.domain_name, r->in.domain_guid,
|
||||
- r->in.site_name ? r->in.site_name : "",
|
||||
- r->in.flags,
|
||||
- r->out.dc_info);
|
||||
- }
|
||||
-
|
||||
- if (domain->active_directory) {
|
||||
- try_dsrgetdcname = true;
|
||||
- }
|
||||
-
|
||||
-reconnect:
|
||||
- status = cm_connect_netlogon(domain, &netlogon_pipe);
|
||||
-
|
||||
- reset_cm_connection_on_error(domain, NULL, status);
|
||||
- if (!NT_STATUS_IS_OK(status)) {
|
||||
- DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
|
||||
- return status;
|
||||
- }
|
||||
-
|
||||
- b = netlogon_pipe->binding_handle;
|
||||
-
|
||||
- /* This call can take a long time - allow the server to time out.
|
||||
- 35 seconds should do it. */
|
||||
-
|
||||
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
|
||||
-
|
||||
- if (try_dsrgetdcname) {
|
||||
- status = dcerpc_netr_DsRGetDCName(b,
|
||||
- p->mem_ctx, domain->dcname,
|
||||
- r->in.domain_name, NULL, r->in.domain_guid,
|
||||
- r->in.flags, r->out.dc_info, &werr);
|
||||
- if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
|
||||
- goto done;
|
||||
- }
|
||||
- if (!retry &&
|
||||
- reset_cm_connection_on_error(domain, NULL, status))
|
||||
- {
|
||||
- retry = true;
|
||||
- goto reconnect;
|
||||
- }
|
||||
- try_dsrgetdcname = false;
|
||||
- retry = false;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Fallback to less capable methods
|
||||
- */
|
||||
-
|
||||
- dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo);
|
||||
- if (dc_info == NULL) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (r->in.flags & DS_PDC_REQUIRED) {
|
||||
- status = dcerpc_netr_GetDcName(b,
|
||||
- p->mem_ctx, domain->dcname,
|
||||
- r->in.domain_name, &dc_info->dc_unc, &werr);
|
||||
- } else {
|
||||
- status = dcerpc_netr_GetAnyDCName(b,
|
||||
- p->mem_ctx, domain->dcname,
|
||||
- r->in.domain_name, &dc_info->dc_unc, &werr);
|
||||
- }
|
||||
-
|
||||
- if (!retry && reset_cm_connection_on_error(domain, b, status)) {
|
||||
- retry = true;
|
||||
- goto reconnect;
|
||||
- }
|
||||
- if (!NT_STATUS_IS_OK(status)) {
|
||||
- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
|
||||
- nt_errstr(status)));
|
||||
- goto done;
|
||||
- }
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
|
||||
- win_errstr(werr)));
|
||||
- status = werror_to_ntstatus(werr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- *r->out.dc_info = dc_info;
|
||||
- status = NT_STATUS_OK;
|
||||
-
|
||||
-done:
|
||||
- /* And restore our original timeout. */
|
||||
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
|
||||
-
|
||||
- return status;
|
||||
+ return dsgetdcname(p->mem_ctx, global_messaging_context(),
|
||||
+ r->in.domain_name, r->in.domain_guid,
|
||||
+ r->in.site_name ? r->in.site_name : "",
|
||||
+ r->in.flags,
|
||||
+ r->out.dc_info);
|
||||
}
|
||||
|
||||
NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)
|
||||
--
|
||||
2.50.0
|
||||
|
||||
@ -223,7 +223,7 @@ Source202: samba.abignore
|
||||
# git format-patch --stdout -l1 --no-renames -N > redhat-4.22.patch
|
||||
# where N is number of commits
|
||||
|
||||
# Patch0: redhat-4.22.patch
|
||||
Patch0: redhat-4.22.patch
|
||||
|
||||
Requires(pre): %{name}-common = %{samba_depver}
|
||||
Requires: %{name}-common = %{samba_depver}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user