[Patches] The way to remove gensec_update_ev()
Stefan Metzmacher
metze at samba.org
Sun Jun 25 18:51:00 UTC 2017
Hi,
here're some preparation patches which passed autobuild twice.
Please review and push:-)
metze
Am 17.06.2017 um 12:29 schrieb Stefan Metzmacher via samba-technical:
> Am 17.06.2017 um 02:05 schrieb Andrew Bartlett:
>> On Sat, 2017-06-17 at 01:23 +0200, Stefan Metzmacher wrote:
>>> Am 15.06.2017 um 05:11 schrieb Andrew Bartlett:
>>>> On Wed, 2017-06-14 at 17:39 +0200, Stefan Metzmacher wrote:
>>>>> Hi,
>>>>>
>>>>> just for the record:
>>>>> https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/
>>>>> master3-gensec
>>>
>>> Here have basic support for NTLMSSP for trusts.
>>
>> Very interesting! I'm a bit nervous about it only supporting NETLOGON
>> and not LDAP et al, but I know this is WIP and am assuming this is just
>> a part-way point.
>
> It's not only netlogon, see
> https://git.samba.org/?p=metze/samba/wip.git;a=commitdiff;h=7ef9b3c5ebf3
> and
> https://git.samba.org/?p=metze/samba/wip.git;a=commitdiff;h=576792b6baad
>
> So the auth stack is implemented, we just need:
> - the correct routing in winbind
> - sid filtering (for kerberos and NTLMSSP)
> - lsa_lookup_sids/names passing to winbindd
>
>
>> Done!
>>
>> Reviewed-by: Andrew Bartlett <abartlet at samba.org>
>
> Thanks!
>
> metze
>
>
-------------- next part --------------
From 93a79cd2b4241861220c995389f9d690b0fc459e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sun, 18 Jun 2017 12:06:10 +0200
Subject: [PATCH 01/10] s3:smbd: only set user_info->auth_description on
success
Otherwise we'll derefence a NULL pointer.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/smbd/sesssetup.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index a44af7f..80dc77a 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -937,9 +937,8 @@ void reply_sesssetup_and_X(struct smb_request *req)
nt_status = NT_STATUS_NO_MEMORY;
}
- user_info->auth_description = "plaintext";
-
if (NT_STATUS_IS_OK(nt_status)) {
+ user_info->auth_description = "plaintext";
nt_status = auth_check_password_session_info(plaintext_auth_context,
req, user_info, &session_info);
}
--
1.9.1
From af079afd577070fb161daba21c7f1ce2d59da48d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sun, 18 Jun 2017 12:08:58 +0200
Subject: [PATCH 02/10] s3:smbd: inline check_guest_password() into
reply_sesssetup_and_X()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/smbd/sesssetup.c | 67 ++++++++++++++++++------------------------------
1 file changed, 25 insertions(+), 42 deletions(-)
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 80dc77a..8a5041b 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -75,45 +75,6 @@ static int push_signature(uint8_t **outbuf)
}
/****************************************************************************
- Do a 'guest' logon, getting back the
-****************************************************************************/
-
-static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
- const struct tsocket_address *local_address,
- TALLOC_CTX *mem_ctx,
- struct auth_session_info **session_info)
-{
- struct auth4_context *auth_context;
- struct auth_usersupplied_info *user_info = NULL;
- uint8_t chal[8];
- NTSTATUS nt_status;
-
- DEBUG(3,("Got anonymous request\n"));
-
- nt_status = make_auth4_context(talloc_tos(), &auth_context);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- auth_context->get_ntlm_challenge(auth_context,
- chal);
-
- if (!make_user_info_guest(talloc_tos(), remote_address, local_address,
- "SMB", &user_info)) {
- TALLOC_FREE(auth_context);
- return NT_STATUS_NO_MEMORY;
- }
-
- user_info->auth_description = "guest";
-
- nt_status = auth_check_password_session_info(auth_context,
- mem_ctx, user_info, session_info);
- TALLOC_FREE(user_info);
- TALLOC_FREE(auth_context);
- return nt_status;
-}
-
-/****************************************************************************
Reply to a session setup command.
conn POINTER CAN BE NULL HERE !
****************************************************************************/
@@ -885,11 +846,33 @@ void reply_sesssetup_and_X(struct smb_request *req)
reload_services(sconn, conn_snum_used, true);
if (!*user) {
+ struct auth4_context *auth_context = NULL;
- nt_status = check_guest_password(sconn->remote_address,
- sconn->local_address,
- req, &session_info);
+ DEBUG(3,("Got anonymous request\n"));
+
+ nt_status = make_auth4_context(talloc_tos(), &auth_context);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ uint8_t chal[8];
+ auth_context->get_ntlm_challenge(auth_context,
+ chal);
+
+ if (!make_user_info_guest(talloc_tos(),
+ sconn->remote_address,
+ sconn->local_address,
+ "SMB", &user_info)) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ }
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ user_info->auth_description = "guest";
+ nt_status = auth_check_password_session_info(
+ auth_context,
+ req, user_info,
+ &session_info);
+ }
+ TALLOC_FREE(auth_context);
+ }
} else if (doencrypt) {
struct auth4_context *negprot_auth_context = NULL;
negprot_auth_context = xconn->smb1.negprot.auth_context;
--
1.9.1
From 8b434473f9a27dae34bac739196c8f543d6621cb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sun, 18 Jun 2017 12:48:11 +0200
Subject: [PATCH 03/10] s3:smbd: introduce a reply_sesssetup_and_X_state
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/smbd/sesssetup.c | 131 +++++++++++++++++++++++++----------------------
1 file changed, 69 insertions(+), 62 deletions(-)
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 8a5041b..1ace34e 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -555,17 +555,31 @@ static void setup_new_vc_session(struct smbd_server_connection *sconn)
Reply to a session setup command.
****************************************************************************/
+struct reply_sesssetup_and_X_state {
+ struct smb_request *req;
+ const char *user;
+ const char *domain;
+ DATA_BLOB lm_resp;
+ DATA_BLOB nt_resp;
+ DATA_BLOB plaintext_password;
+};
+
+static int reply_sesssetup_and_X_state_destructor(
+ struct reply_sesssetup_and_X_state *state)
+{
+ data_blob_clear_free(&state->nt_resp);
+ data_blob_clear_free(&state->lm_resp);
+ data_blob_clear_free(&state->plaintext_password);
+ return 0;
+}
+
void reply_sesssetup_and_X(struct smb_request *req)
{
+ struct reply_sesssetup_and_X_state *state = NULL;
uint64_t sess_vuid;
uint16_t smb_bufsize;
- DATA_BLOB lm_resp;
- DATA_BLOB nt_resp;
- DATA_BLOB plaintext_password;
char *tmp;
- const char *user;
fstring sub_user; /* Sanitised username for substituion */
- const char *domain;
const char *native_os;
const char *native_lanman;
const char *primary_domain;
@@ -586,12 +600,17 @@ void reply_sesssetup_and_X(struct smb_request *req)
START_PROFILE(SMBsesssetupX);
- ZERO_STRUCT(lm_resp);
- ZERO_STRUCT(nt_resp);
- ZERO_STRUCT(plaintext_password);
-
DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
+ state = talloc_zero(req, struct reply_sesssetup_and_X_state);
+ if (state == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBsesssetupX);
+ return;
+ }
+ state->req = req;
+ talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
+
if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
signing_allowed = true;
}
@@ -649,18 +668,22 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
if (doencrypt) {
- lm_resp = data_blob(req->buf, passlen1);
+ state->lm_resp = data_blob_talloc(state,
+ req->buf,
+ passlen1);
} else {
- plaintext_password = data_blob(req->buf, passlen1+1);
+ state->plaintext_password = data_blob_talloc(state,
+ req->buf,
+ passlen1+1);
/* Ensure null termination */
- plaintext_password.data[passlen1] = 0;
+ state->plaintext_password.data[passlen1] = 0;
}
- srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
+ srvstr_pull_req_talloc(state, req, &tmp,
req->buf + passlen1, STR_TERMINATE);
- user = tmp ? tmp : "";
+ state->user = tmp ? tmp : "";
- domain = "";
+ state->domain = "";
} else {
uint16_t passlen1 = SVAL(req->vwv+7, 0);
@@ -735,15 +758,15 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
if (doencrypt) {
- lm_resp = data_blob(p, passlen1);
- nt_resp = data_blob(p+passlen1, passlen2);
+ state->lm_resp = data_blob_talloc(state, p, passlen1);
+ state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
} else {
char *pass = NULL;
bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
if (unic && (passlen2 == 0) && passlen1) {
/* Only a ascii plaintext password was sent. */
- (void)srvstr_pull_talloc(talloc_tos(),
+ (void)srvstr_pull_talloc(state,
req->inbuf,
req->flags2,
&pass,
@@ -751,7 +774,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
passlen1,
STR_TERMINATE|STR_ASCII);
} else {
- (void)srvstr_pull_talloc(talloc_tos(),
+ (void)srvstr_pull_talloc(state,
req->inbuf,
req->flags2,
&pass,
@@ -765,18 +788,20 @@ void reply_sesssetup_and_X(struct smb_request *req)
END_PROFILE(SMBsesssetupX);
return;
}
- plaintext_password = data_blob(pass, strlen(pass)+1);
+ state->plaintext_password = data_blob_talloc(state,
+ pass,
+ strlen(pass)+1);
}
p += passlen1 + passlen2;
- p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ p += srvstr_pull_req_talloc(state, req, &tmp, p,
STR_TERMINATE);
- user = tmp ? tmp : "";
+ state->user = tmp ? tmp : "";
- p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ p += srvstr_pull_req_talloc(state, req, &tmp, p,
STR_TERMINATE);
- domain = tmp ? tmp : "";
+ state->domain = tmp ? tmp : "";
p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
STR_TERMINATE);
@@ -804,7 +829,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
"PrimaryDomain=[%s]\n",
- domain, native_os, native_lanman, primary_domain));
+ state->domain, native_os, native_lanman, primary_domain));
if ( ra_type == RA_WIN2K ) {
if ( strlen(native_lanman) == 0 )
@@ -820,9 +845,9 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
- domain, user, get_remote_machine_name()));
+ state->domain, state->user, get_remote_machine_name()));
- if (*user) {
+ if (*state->user) {
if (xconn->smb1.negprot.spnego) {
/* This has to be here, because this is a perfectly
@@ -836,7 +861,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
END_PROFILE(SMBsesssetupX);
return;
}
- fstrcpy(sub_user, user);
+ fstrcpy(sub_user, state->user);
} else {
fstrcpy(sub_user, "");
}
@@ -845,19 +870,19 @@ void reply_sesssetup_and_X(struct smb_request *req)
reload_services(sconn, conn_snum_used, true);
- if (!*user) {
+ if (!*state->user) {
struct auth4_context *auth_context = NULL;
DEBUG(3,("Got anonymous request\n"));
- nt_status = make_auth4_context(talloc_tos(), &auth_context);
+ nt_status = make_auth4_context(state, &auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
uint8_t chal[8];
auth_context->get_ntlm_challenge(auth_context,
chal);
- if (!make_user_info_guest(talloc_tos(),
+ if (!make_user_info_guest(state,
sconn->remote_address,
sconn->local_address,
"SMB", &user_info)) {
@@ -884,13 +909,15 @@ void reply_sesssetup_and_X(struct smb_request *req)
END_PROFILE(SMBsesssetupX);
return;
}
- nt_status = make_user_info_for_reply_enc(talloc_tos(),
- &user_info, user,
- domain,
+ nt_status = make_user_info_for_reply_enc(state,
+ &user_info,
+ state->user,
+ state->domain,
sconn->remote_address,
sconn->local_address,
"SMB",
- lm_resp, nt_resp);
+ state->lm_resp,
+ state->nt_resp);
if (NT_STATUS_IS_OK(nt_status)) {
user_info->auth_description = "bare-NTLM";
@@ -901,7 +928,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
struct auth4_context *plaintext_auth_context = NULL;
nt_status = make_auth4_context(
- talloc_tos(), &plaintext_auth_context);
+ state, &plaintext_auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
uint8_t chal[8];
@@ -909,14 +936,15 @@ void reply_sesssetup_and_X(struct smb_request *req)
plaintext_auth_context->get_ntlm_challenge(
plaintext_auth_context, chal);
- if (!make_user_info_for_reply(talloc_tos(),
+ if (!make_user_info_for_reply(state,
&user_info,
- user, domain,
+ state->user,
+ state->domain,
sconn->remote_address,
sconn->local_address,
"SMB",
chal,
- plaintext_password)) {
+ state->plaintext_password)) {
nt_status = NT_STATUS_NO_MEMORY;
}
@@ -932,16 +960,11 @@ void reply_sesssetup_and_X(struct smb_request *req)
TALLOC_FREE(user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
- data_blob_clear_free(&plaintext_password);
reply_nterror(req, nt_status_squash(nt_status));
END_PROFILE(SMBsesssetupX);
return;
}
- data_blob_clear_free(&plaintext_password);
-
/* it's ok - setup a reply */
reply_outbuf(req, 3, 0);
SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
@@ -962,8 +985,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
nt_status = smbXsrv_session_create(xconn,
now, &session);
if (!NT_STATUS_IS_OK(nt_status)) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
reply_nterror(req, nt_status_squash(nt_status));
END_PROFILE(SMBsesssetupX);
return;
@@ -979,8 +1000,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
data_blob_dup_talloc(session->global,
session_info->session_key);
if (session->global->signing_key.data == NULL) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsesssetupX);
@@ -1000,8 +1019,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
sizeof(session_key));
ZERO_STRUCT(session_key);
if (session->global->application_key.data == NULL) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsesssetupX);
@@ -1015,8 +1032,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
session_info->session_key = data_blob_dup_talloc(session_info,
session->global->application_key);
if (session_info->session_key.data == NULL) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsesssetupX);
@@ -1026,8 +1041,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
session->compat = talloc_zero(session, struct user_struct);
if (session->compat == NULL) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsesssetupX);
@@ -1057,7 +1070,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
*/
srv_set_signing(xconn,
session->global->signing_key,
- nt_resp.data ? nt_resp : lm_resp);
+ state->nt_resp.data ? state->nt_resp : state->lm_resp);
}
set_current_user_info(session_info->unix_info->sanitized_username,
@@ -1078,8 +1091,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
(unsigned long long)session->compat->vuid,
nt_errstr(nt_status)));
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, nt_status_squash(nt_status));
END_PROFILE(SMBsesssetupX);
@@ -1089,8 +1100,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
if (!session_claim(session)) {
DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
(unsigned long long)session->compat->vuid));
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
TALLOC_FREE(session);
reply_nterror(req, NT_STATUS_LOGON_FAILURE);
END_PROFILE(SMBsesssetupX);
@@ -1102,9 +1111,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
sess_vuid = session->global->session_wire_id;
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
-
SSVAL(req->outbuf,smb_vwv2,action);
SSVAL(req->outbuf,smb_uid,sess_vuid);
SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
@@ -1120,5 +1126,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
xconn->smb1.sessions.done_sesssetup = true;
}
+ TALLOC_FREE(state);
END_PROFILE(SMBsesssetupX);
}
--
1.9.1
From 643fc377100ae7f531a64b0d69146d164980306a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sun, 18 Jun 2017 12:53:05 +0200
Subject: [PATCH 04/10] s3:smbd: call auth_check_password_session_info() only
in one central place
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/smbd/sesssetup.c | 58 +++++++++++++++++++++---------------------------
1 file changed, 25 insertions(+), 33 deletions(-)
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 1ace34e..e1fc7fd 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -557,6 +557,8 @@ static void setup_new_vc_session(struct smbd_server_connection *sconn)
struct reply_sesssetup_and_X_state {
struct smb_request *req;
+ struct auth4_context *auth_context;
+ struct auth_usersupplied_info *user_info;
const char *user;
const char *domain;
DATA_BLOB lm_resp;
@@ -583,7 +585,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
const char *native_os;
const char *native_lanman;
const char *primary_domain;
- struct auth_usersupplied_info *user_info = NULL;
struct auth_session_info *session_info = NULL;
uint16_t smb_flag2 = req->flags2;
uint16_t action = 0;
@@ -871,37 +872,29 @@ void reply_sesssetup_and_X(struct smb_request *req)
reload_services(sconn, conn_snum_used, true);
if (!*state->user) {
- struct auth4_context *auth_context = NULL;
-
DEBUG(3,("Got anonymous request\n"));
- nt_status = make_auth4_context(state, &auth_context);
+ nt_status = make_auth4_context(state, &state->auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
uint8_t chal[8];
- auth_context->get_ntlm_challenge(auth_context,
- chal);
+ state->auth_context->get_ntlm_challenge(
+ state->auth_context, chal);
if (!make_user_info_guest(state,
sconn->remote_address,
sconn->local_address,
- "SMB", &user_info)) {
+ "SMB", &state->user_info)) {
nt_status = NT_STATUS_NO_MEMORY;
}
if (NT_STATUS_IS_OK(nt_status)) {
- user_info->auth_description = "guest";
- nt_status = auth_check_password_session_info(
- auth_context,
- req, user_info,
- &session_info);
+ state->user_info->auth_description = "guest";
}
- TALLOC_FREE(auth_context);
}
} else if (doencrypt) {
- struct auth4_context *negprot_auth_context = NULL;
- negprot_auth_context = xconn->smb1.negprot.auth_context;
- if (!negprot_auth_context) {
+ state->auth_context = xconn->smb1.negprot.auth_context;
+ if (state->auth_context == NULL) {
DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
"session setup without negprot denied!\n"));
reply_nterror(req, nt_status_squash(
@@ -910,7 +903,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
return;
}
nt_status = make_user_info_for_reply_enc(state,
- &user_info,
+ &state->user_info,
state->user,
state->domain,
sconn->remote_address,
@@ -920,24 +913,18 @@ void reply_sesssetup_and_X(struct smb_request *req)
state->nt_resp);
if (NT_STATUS_IS_OK(nt_status)) {
- user_info->auth_description = "bare-NTLM";
- nt_status = auth_check_password_session_info(negprot_auth_context,
- req, user_info, &session_info);
+ state->user_info->auth_description = "bare-NTLM";
}
} else {
- struct auth4_context *plaintext_auth_context = NULL;
-
- nt_status = make_auth4_context(
- state, &plaintext_auth_context);
-
+ nt_status = make_auth4_context(state, &state->auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
uint8_t chal[8];
- plaintext_auth_context->get_ntlm_challenge(
- plaintext_auth_context, chal);
+ state->auth_context->get_ntlm_challenge(
+ state->auth_context, chal);
if (!make_user_info_for_reply(state,
- &user_info,
+ &state->user_info,
state->user,
state->domain,
sconn->remote_address,
@@ -949,16 +936,21 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
if (NT_STATUS_IS_OK(nt_status)) {
- user_info->auth_description = "plaintext";
- nt_status = auth_check_password_session_info(plaintext_auth_context,
- req, user_info, &session_info);
+ state->user_info->auth_description = "plaintext";
}
- TALLOC_FREE(plaintext_auth_context);
}
}
- TALLOC_FREE(user_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ reply_nterror(req, nt_status_squash(nt_status));
+ END_PROFILE(SMBsesssetupX);
+ return;
+ }
+ nt_status = auth_check_password_session_info(state->auth_context,
+ req, state->user_info,
+ &session_info);
+ TALLOC_FREE(state->user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status_squash(nt_status));
END_PROFILE(SMBsesssetupX);
--
1.9.1
From 2064b372ad4a502246c0e556b2ac1f30c54ea2f1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 19 Jun 2017 08:26:26 +0200
Subject: [PATCH 05/10] s4:auth/unix_token: remove unused tevent_context from
security_token_to_unix_token()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/unix_token.c | 3 +--
source4/ntvfs/unixuid/vfs_unixuid.c | 4 +---
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/source4/auth/unix_token.c b/source4/auth/unix_token.c
index 385109b..e1e7cda 100644
--- a/source4/auth/unix_token.c
+++ b/source4/auth/unix_token.c
@@ -29,7 +29,6 @@
form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
struct security_token *token,
struct security_unix_token **sec)
{
@@ -128,7 +127,7 @@ NTSTATUS auth_session_info_fill_unix(struct tevent_context *ev,
{
char *su;
size_t len;
- NTSTATUS status = security_token_to_unix_token(session_info, ev,
+ NTSTATUS status = security_token_to_unix_token(session_info,
session_info->security_token,
&session_info->unix_token);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c
index 40ccd4a..995d744 100644
--- a/source4/ntvfs/unixuid/vfs_unixuid.c
+++ b/source4/ntvfs/unixuid/vfs_unixuid.c
@@ -156,9 +156,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs,
struct security_token *token,
struct security_unix_token **sec)
{
- return security_token_to_unix_token(req,
- ntvfs->ctx->event_ctx,
- token, sec);
+ return security_token_to_unix_token(req, token, sec);
}
/*
--
1.9.1
From bf3dfe6a76b68f8b739a102fcee41f47c3a27b8e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 19 Jun 2017 08:26:26 +0200
Subject: [PATCH 06/10] s4:auth/unix_token: remove unused tevent_context from
auth_session_info_fill_unix()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/ntlm/auth.c | 6 +++---
source4/auth/unix_token.c | 3 +--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 51d1ed3..cbe49a1 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -524,9 +524,9 @@ static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_co
if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)
&& NT_STATUS_IS_OK(status)) {
- status = auth_session_info_fill_unix(auth_context->event_ctx,
- auth_context->lp_ctx,
- original_user_name, *session_info);
+ status = auth_session_info_fill_unix(auth_context->lp_ctx,
+ original_user_name,
+ *session_info);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(*session_info);
}
diff --git a/source4/auth/unix_token.c b/source4/auth/unix_token.c
index e1e7cda..e5eb0aa 100644
--- a/source4/auth/unix_token.c
+++ b/source4/auth/unix_token.c
@@ -120,8 +120,7 @@ NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
/*
Fill in the auth_user_info_unix and auth_unix_token elements in a struct session_info
*/
-NTSTATUS auth_session_info_fill_unix(struct tevent_context *ev,
- struct loadparm_context *lp_ctx,
+NTSTATUS auth_session_info_fill_unix(struct loadparm_context *lp_ctx,
const char *original_user_name,
struct auth_session_info *session_info)
{
--
1.9.1
From 07953bbdc14a9e6c0c509c709c7bbcd8ea609725 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 19 Jun 2017 08:39:19 +0200
Subject: [PATCH 07/10] s4:dsdb/samdb: pass an existing 'struct ldb_context' to
crack_name_to_nt4_name()
There's no point in creating a temporary ldb_context as
all direct callers already have a valid struct ldb_context for
the local sam.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/ntlm/auth_sam.c | 3 +--
source4/auth/ntlm/auth_winbind.c | 3 +--
source4/dsdb/samdb/cracknames.c | 16 +++++++---------
source4/rpc_server/lsa/lsa_lookup.c | 5 ++++-
4 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index ee4a054..24fe167 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -648,8 +648,7 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
bool is_my_domain = false;
nt_status = crack_name_to_nt4_name(mem_ctx,
- ctx->auth_ctx->event_ctx,
- ctx->auth_ctx->lp_ctx,
+ ctx->auth_ctx->sam_ctx,
/*
* DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON ?
*/
diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c
index 84f278d..7308a17 100644
--- a/source4/auth/ntlm/auth_winbind.c
+++ b/source4/auth/ntlm/auth_winbind.c
@@ -208,8 +208,7 @@ static NTSTATUS winbind_check_password(struct auth_method_context *ctx,
const char *nt4_account = NULL;
status = crack_name_to_nt4_name(mem_ctx,
- ctx->auth_ctx->event_ctx,
- ctx->auth_ctx->lp_ctx,
+ ctx->auth_ctx->sam_ctx,
DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
account_name,
&nt4_domain, &nt4_account);
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 596343a..a361238 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -1378,15 +1378,13 @@ NTSTATUS crack_service_principal_name(struct ldb_context *sam_ctx,
}
NTSTATUS crack_name_to_nt4_name(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev_ctx,
- struct loadparm_context *lp_ctx,
+ struct ldb_context *ldb,
enum drsuapi_DsNameFormat format_offered,
const char *name,
const char **nt4_domain, const char **nt4_account)
{
WERROR werr;
struct drsuapi_DsNameInfo1 info1;
- struct ldb_context *ldb;
char *p;
/* Handle anonymous bind */
@@ -1396,11 +1394,6 @@ NTSTATUS crack_name_to_nt4_name(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- ldb = samdb_connect(mem_ctx, ev_ctx, lp_ctx, system_session(lp_ctx), 0);
- if (ldb == NULL) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
werr = DsCrackNameOneName(ldb, mem_ctx, 0,
format_offered,
DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
@@ -1447,6 +1440,7 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx,
const char **nt4_domain,
const char **nt4_account)
{
+ struct ldb_context *ldb = NULL;
enum drsuapi_DsNameFormat format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN;
/* Handle anonymous bind */
@@ -1468,7 +1462,11 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_SUCH_USER;
}
- return crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, format_offered, name, nt4_domain, nt4_account);
+ ldb = samdb_connect(mem_ctx, ev_ctx, lp_ctx, system_session(lp_ctx), 0);
+ if (ldb == NULL) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ return crack_name_to_nt4_name(mem_ctx, ldb, format_offered, name, nt4_domain, nt4_account);
}
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index f4da0b48..f54b118 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -263,7 +263,10 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx,
}
username = p + 1;
} else if (strchr_m(name, '@')) {
- status = crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
+ status = crack_name_to_nt4_name(mem_ctx,
+ state->sam_ldb,
+ DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+ name, &domain, &username);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
return status;
--
1.9.1
From a935a991bcf7fec2f211562a82c90fd56c01080d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 19 Jun 2017 08:39:19 +0200
Subject: [PATCH 08/10] s4:dsdb/samdb: pass an existing 'struct ldb_context' to
crack_auto_name_to_nt4_name()
There's no point in creating a temporary ldb_context as
the only callers already have a valid struct ldb_context for
the local sam.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/ntlm/auth_simple.c | 4 ++--
source4/dsdb/samdb/cracknames.c | 8 +-------
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index c3bc25a..d7811b9 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -105,8 +105,8 @@ _PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_c
MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
- status = crack_auto_name_to_nt4_name(state, ev, lp_ctx, dn,
- &nt4_domain, &nt4_username);
+ status = crack_auto_name_to_nt4_name(state, state->auth_context->sam_ctx,
+ dn, &nt4_domain, &nt4_username);
if (!NT_STATUS_IS_OK(status)) {
log_authentication_event(msg, lp_ctx,
user_info, status,
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index a361238..14d6a53a 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -1434,13 +1434,11 @@ NTSTATUS crack_name_to_nt4_name(TALLOC_CTX *mem_ctx,
}
NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev_ctx,
- struct loadparm_context *lp_ctx,
+ struct ldb_context *ldb,
const char *name,
const char **nt4_domain,
const char **nt4_account)
{
- struct ldb_context *ldb = NULL;
enum drsuapi_DsNameFormat format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN;
/* Handle anonymous bind */
@@ -1462,10 +1460,6 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_SUCH_USER;
}
- ldb = samdb_connect(mem_ctx, ev_ctx, lp_ctx, system_session(lp_ctx), 0);
- if (ldb == NULL) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
return crack_name_to_nt4_name(mem_ctx, ldb, format_offered, name, nt4_domain, nt4_account);
}
--
1.9.1
From 60d9dbac815a9467be396ed5c1f8629d734b465f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 16 Jun 2017 18:03:11 +0200
Subject: [PATCH 09/10] auth/ntlmssp: remove useless talloc_steal calls in
ntlmssp_server_check_password()
We only create a temporary auth_usersupplied_info structure and pass it
down as const, lets keep the values on ntlmssp_state otherwise we may derefence
stale pointers.
We finally free the memory at the end of ntlmssp_server_postauth() now.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
auth/ntlmssp/ntlmssp_server.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index c525a93..35aa549 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -732,9 +732,7 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
user_info->password_state = AUTH_PASSWORD_RESPONSE;
user_info->password.response.lanman = ntlmssp_state->lm_resp;
- user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data);
user_info->password.response.nt = ntlmssp_state->nt_resp;
- user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
if (auth_context->check_ntlm_password) {
uint8_t authoritative = 0;
@@ -977,6 +975,11 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
nt_status = ntlmssp_sign_init(ntlmssp_state);
}
+ data_blob_clear_free(&ntlmssp_state->internal_chal);
+ data_blob_clear_free(&ntlmssp_state->chal);
+ data_blob_clear_free(&ntlmssp_state->lm_resp);
+ data_blob_clear_free(&ntlmssp_state->nt_resp);
+
ntlmssp_state->expected_state = NTLMSSP_DONE;
return nt_status;
--
1.9.1
From 0a0bc40fefda41020f8a13f2a6c5b0cbc145dc62 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 16 Jun 2017 17:11:17 +0200
Subject: [PATCH 10/10] auth/ntlmssp: make ntlmssp_server_check_password()
shorter
We move as must as possible into ntlmssp_server_{pre,post}auth().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
auth/ntlmssp/ntlmssp_server.c | 102 ++++++++++++++++++++++--------------------
1 file changed, 53 insertions(+), 49 deletions(-)
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index 35aa549..e17074e 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -294,6 +294,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security
}
struct ntlmssp_server_auth_state {
+ struct auth_usersupplied_info *user_info;
DATA_BLOB user_session_key;
DATA_BLOB lm_session_key;
/* internal variables used by KEY_EXCH (client-supplied user session key */
@@ -318,6 +319,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
{
struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
struct auth4_context *auth_context = gensec_security->auth_context;
+ struct auth_usersupplied_info *user_info = NULL;
uint32_t ntlmssp_command, auth_flags;
NTSTATUS nt_status;
const unsigned int version_len = 8;
@@ -686,27 +688,8 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
}
}
- return NT_STATUS_OK;
-}
-
-/**
- * Check the password on an NTLMSSP login.
- *
- * Return the session keys used on the connection.
- */
-static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_security,
- struct gensec_ntlmssp_context *gensec_ntlmssp,
- TALLOC_CTX *mem_ctx,
- DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
-{
- struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
- struct auth4_context *auth_context = gensec_security->auth_context;
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- struct auth_session_info *session_info = NULL;
- struct auth_usersupplied_info *user_info;
-
- user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info);
+ user_info = talloc_zero(state, struct auth_usersupplied_info);
if (!user_info) {
return NT_STATUS_NO_MEMORY;
}
@@ -734,6 +717,25 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
user_info->password.response.lanman = ntlmssp_state->lm_resp;
user_info->password.response.nt = ntlmssp_state->nt_resp;
+ state->user_info = user_info;
+ return NT_STATUS_OK;
+}
+
+/**
+ * Check the password on an NTLMSSP login.
+ *
+ * Return the session keys used on the connection.
+ */
+
+static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_security,
+ struct gensec_ntlmssp_context *gensec_ntlmssp,
+ const struct auth_usersupplied_info *user_info,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
+{
+ struct auth4_context *auth_context = gensec_security->auth_context;
+ NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
+
if (auth_context->check_ntlm_password) {
uint8_t authoritative = 0;
@@ -748,10 +750,37 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(5, (__location__ ": Checking NTLMSSP password for %s\\%s failed: %s\n", user_info->client.domain_name, user_info->client.account_name, nt_errstr(nt_status)));
}
- TALLOC_FREE(user_info);
-
NT_STATUS_NOT_OK_RETURN(nt_status);
+ talloc_steal(mem_ctx, user_session_key->data);
+ talloc_steal(mem_ctx, lm_session_key->data);
+
+ return nt_status;
+}
+
+/**
+ * Next state function for the Authenticate packet
+ * (after authentication - figures out the session keys etc)
+ *
+ * @param ntlmssp_state NTLMSSP State
+ * @return Errors or NT_STATUS_OK.
+ */
+
+static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
+ struct gensec_ntlmssp_context *gensec_ntlmssp,
+ struct ntlmssp_server_auth_state *state,
+ DATA_BLOB request)
+{
+ struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
+ struct auth4_context *auth_context = gensec_security->auth_context;
+ DATA_BLOB user_session_key = state->user_session_key;
+ DATA_BLOB lm_session_key = state->lm_session_key;
+ NTSTATUS nt_status = NT_STATUS_OK;
+ DATA_BLOB session_key = data_blob(NULL, 0);
+ struct auth_session_info *session_info = NULL;
+
+ TALLOC_FREE(state->user_info);
+
if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
&& auth_context->generate_session_info != NULL)
{
@@ -760,7 +789,7 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
/*
* We need to check if the auth is anonymous or mapped to guest
*/
- tmp_status = auth_context->generate_session_info(auth_context, mem_ctx,
+ tmp_status = auth_context->generate_session_info(auth_context, state,
gensec_ntlmssp->server_returned_info,
gensec_ntlmssp->ntlmssp_state->user,
AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
@@ -788,31 +817,6 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
TALLOC_FREE(session_info);
}
- talloc_steal(mem_ctx, user_session_key->data);
- talloc_steal(mem_ctx, lm_session_key->data);
-
- return nt_status;
-}
-
-/**
- * Next state function for the Authenticate packet
- * (after authentication - figures out the session keys etc)
- *
- * @param ntlmssp_state NTLMSSP State
- * @return Errors or NT_STATUS_OK.
- */
-
-static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
- struct gensec_ntlmssp_context *gensec_ntlmssp,
- struct ntlmssp_server_auth_state *state,
- DATA_BLOB request)
-{
- struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
- DATA_BLOB user_session_key = state->user_session_key;
- DATA_BLOB lm_session_key = state->lm_session_key;
- NTSTATUS nt_status = NT_STATUS_OK;
- DATA_BLOB session_key = data_blob(NULL, 0);
-
dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
@@ -1029,7 +1033,7 @@ NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security,
/* Finally, actually ask if the password is OK */
nt_status = ntlmssp_server_check_password(gensec_security, gensec_ntlmssp,
- state,
+ state->user_info, state,
&state->user_session_key,
&state->lm_session_key);
if (!NT_STATUS_IS_OK(nt_status)) {
--
1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20170625/14c02e12/signature.sig>
More information about the samba-technical
mailing list