The branch, master has been updated via eb691cd python:tests: Add test for warn_pwd_expire via 0a7db4d python:tests: Do not overwrite exit code via 9048725 source3/client: Fix typo in help message displayed by default via d51d4c9 python: Fix incorrect kdc.conf parameter name in kerberos.py via ccc8c1a winbindd: give an IRPC error if wb_irpc_SamLogon() is called without useful routing information via 615b0d8 winbindd: as DC we should try to get the target_domain from @SOMETHING part of the username in wb_irpc_SamLogon() via 0ed6ad4 winbindd: Print debug if we don't know how to route a wb_irpc_SamLogon() request via 039ad5c winbindd: allow all possible logon levels in wb_irpc_SamLogon() via b88f938 s4:auth/ntlmssp: add support for using "winbind" as DC via a6ad56c s4:auth: use "sam winbind" for the netlogon server via 690c5e6 s4:auth/ntlm: provide auth_check_password_wrapper_send/recv to auth4_context via e8264d9 auth/common: add support for auth4_ctx->check_ntlm_password_send/recv() via 7d43aec auth/ntlmssp: merge ntlmssp_server_check_password() into ntlmssp_server_auth_send() via 260e535 auth/ntlmssp: introduce ntlmssp_server_auth_send/recv via da3baf6 auth/ntlmssp: prepare update_send/recv for real async processing via 79b891a s4:auth_winbind: implement async authentication via IRPC via 8022b63 s4:rpc_server/netlogon: make use of auth_check_password_send/recv() via 023bd2d s4:rpc_server/netlogon: make use of async kdc_check_generic_kerberos_send/recv() via 373da95 s4:rpc_server/netlogon: prepare dcesrv_netr_LogonSamLogon_base for async processing via b10d01d s4:rpc_server/netlogon: check auth_level for validation level 6 already in dcesrv_netr_LogonSamLogon_check() via c8d14a5 s4:librpc/rpc: add support for HttpAuthOption=negotiate via 77b44fb s4:lib/http: pass down the target service/hostname to gensec via d1f479e s4:lib/http: add HTTP_AUTH_NEGOTIATE which maps to the "http_negotiate" gensec backend via 9fd27d7 s4:http/gensec: implement "http_negotiate" using GENSEC_OID_SPNEGO via 8813295 s4:http/gensec: make the "NTLM" base64 wrapping more generic via a219c35 s4:http/gensec: rename ntlm.c to generic.c via b5854ec s4:librpc/rpc: pass down HTTP_AUTH_* values directly to dcerpc_pipe_open_roh_send() via 8d36bbe s4:librpc/rpc: remember the target_hostname on ncacn_http connections via a6ae9da s4:lib/http: pass a generic prefix blob to http_parse_auth_response() via bdece1d s4:lib/http: use strcasecmp(h->key, "WWW-Authenticate") instead of strncasecmp() via 56ab5cd s4:lib/http: remove indentation level from http_parse_auth_response() via e42f12c s4:lib/http: let http_read_response_send/recv() also consume the body if it fits into a max value via 7b86da0 s4:lib/http: lower HTTP_MAX_HEADER_SIZE from UINT_MAX to 0x1FFFF from 2b67d93 winbindd: Simplify an if-condition
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit eb691cd024260f0bc97dbd1260a14575af0fb547 Author: Andreas Schneider <a...@samba.org> Date: Tue Aug 1 16:07:58 2017 +0200 python:tests: Add test for warn_pwd_expire Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Mon Aug 7 19:11:02 CEST 2017 on sn-devel-144 commit 0a7db4dd43b8ef226ba3a048c8adcc3dd1ecd3bd Author: Andreas Schneider <a...@samba.org> Date: Tue Aug 1 16:05:57 2017 +0200 python:tests: Do not overwrite exit code Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 90487259e365d5b966ccc47ac51eadb4733f3197 Author: Anoop C S <anoo...@redhat.com> Date: Mon Jul 31 15:39:19 2017 +0530 source3/client: Fix typo in help message displayed by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=12936 Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit d51d4c94585f12cd1a0f3262ee47a52403c96696 Author: Marc Muehlfeld <mmuehlf...@samba.org> Date: Sun Aug 6 11:50:55 2017 +0200 python: Fix incorrect kdc.conf parameter name in kerberos.py Signed-off-by: Marc Muehlfeld <mmuehlf...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit ccc8c1a45dd62ea77c3c4aabd218e0cd08a47c7c Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 12:29:31 2017 +0200 winbindd: give an IRPC error if wb_irpc_SamLogon() is called without useful routing information The caller should have checked this already! Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 615b0d83d0fa021ae1301a8dc37bf3b953531d84 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 12:29:31 2017 +0200 winbindd: as DC we should try to get the target_domain from @SOMETHING part of the username in wb_irpc_SamLogon() We still need a full routing table including all upn suffixes, but this is a start to support NTLM authentication using user@REALM against structed domains. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 0ed6ad45ad4dd8deda2d86157bba27ebb13225f0 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 12:29:31 2017 +0200 winbindd: Print debug if we don't know how to route a wb_irpc_SamLogon() request Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 039ad5c9ad4c4b930d2fa7857cf5fb4dc547e181 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 12:29:31 2017 +0200 winbindd: allow all possible logon levels in wb_irpc_SamLogon() We should just try to find the correct domain to forward the request, all logic of not implementing serveral logon levels belongs to the _winbind_SamLogon() implementation. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b88f9384b01d91e6060cd806e03fe9c90cbdbcf1 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Jun 17 01:06:46 2017 +0200 s4:auth/ntlmssp: add support for using "winbind" as DC This adds support for trusted domains to the auth stack on AD DCs. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a6ad56cfa9dfc7488dd328aa752ddd96154f0362 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Mar 22 11:16:47 2017 +0100 s4:auth: use "sam winbind" for the netlogon server This adds authentication support for trusted domains to the netlogon server. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 690c5e6f36e343f709715214e2368bcb7e67e0fb Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 16 23:07:04 2017 +0200 s4:auth/ntlm: provide auth_check_password_wrapper_send/recv to auth4_context Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit e8264d9678dff1cf56f7ac97d8a1a59b9532b6b8 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 16 17:18:17 2017 +0200 auth/common: add support for auth4_ctx->check_ntlm_password_send/recv() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 7d43aecb5002902486a6c57ff14a1dcbd64b0f40 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 16 17:14:35 2017 +0200 auth/ntlmssp: merge ntlmssp_server_check_password() into ntlmssp_server_auth_send() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 260e535252c2643ca435e036bfdbb44ddf4c28d1 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 16 16:16:15 2017 +0200 auth/ntlmssp: introduce ntlmssp_server_auth_send/recv We still use the sync ntlmssp_server_check_password(). Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit da3baf64d5a4bdf20b70edb66750c51a7315dd06 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jun 15 00:34:26 2017 +0200 auth/ntlmssp: prepare update_send/recv for real async processing Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 79b891a74663e6e3c637f5499eb8a5c41b2384f5 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Jun 17 00:56:09 2017 +0200 s4:auth_winbind: implement async authentication via IRPC Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 8022b63f6cfadc58d6711e346054f7387bd602d3 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Mar 17 19:36:08 2017 +0100 s4:rpc_server/netlogon: make use of auth_check_password_send/recv() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 023bd2d15d5e9599c592819a13acf0475a209706 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 08:10:02 2017 +0200 s4:rpc_server/netlogon: make use of async kdc_check_generic_kerberos_send/recv() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 373da95b0b72ec7db8463a4ee780177d7083ebae Author: Stefan Metzmacher <me...@samba.org> Date: Fri Mar 17 19:27:38 2017 +0100 s4:rpc_server/netlogon: prepare dcesrv_netr_LogonSamLogon_base for async processing Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b10d01d14a9144f32dfd497edfa8e0d2c365fd96 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jul 21 07:39:11 2017 +0200 s4:rpc_server/netlogon: check auth_level for validation level 6 already in dcesrv_netr_LogonSamLogon_check() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit c8d14a554e958865cbc354cd3488824599b1a0c4 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 13:06:58 2017 +0200 s4:librpc/rpc: add support for HttpAuthOption=negotiate Note that rpcproxy.dll on Windows doesn't support kerberos, it allways downgrades the connection to NTLMSSP. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 77b44fbe362660b65da0aa36aeeea3fecc4ae515 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 16:11:48 2017 +0200 s4:lib/http: pass down the target service/hostname to gensec Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit d1f479e73b87b7785b350df2a09132f9985efa28 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 13:03:40 2017 +0200 s4:lib/http: add HTTP_AUTH_NEGOTIATE which maps to the "http_negotiate" gensec backend Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 9fd27d7a4780040ccab8539efb919f7b618aa3da Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 13:03:03 2017 +0200 s4:http/gensec: implement "http_negotiate" using GENSEC_OID_SPNEGO Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 8813295e1f58f8972e084c8fa16e00b0e23d9216 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 13:00:27 2017 +0200 s4:http/gensec: make the "NTLM" base64 wrapping more generic We only need to know the prefix "NTLM" and the submech oid GENSEC_OID_NTLMSSP everything else can be generic. This should allow us to implement "Negotiate" with GENSEC_OID_SPNEGO trivial. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a219c359b959b956d39ba8442091ca5269ab4a5c Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 12:07:18 2017 +0200 s4:http/gensec: rename ntlm.c to generic.c Check with git show -C Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b5854ecc98c3db4aba56f91035b79aabde0fc266 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 13:05:39 2017 +0200 s4:librpc/rpc: pass down HTTP_AUTH_* values directly to dcerpc_pipe_open_roh_send() They get passed to http_send_auth_request_send() unmodified. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 8d36bbe1874f47230d663e16de3c8e0e0800d997 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 23:05:53 2017 +0200 s4:librpc/rpc: remember the target_hostname on ncacn_http connections Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a6ae9da98dff49e37e23481e8932eb18c8e45c02 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 15:48:35 2017 +0200 s4:lib/http: pass a generic prefix blob to http_parse_auth_response() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit bdece1df9cad4dbe1b41215d21dbcf34bfee1c66 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 15:46:38 2017 +0200 s4:lib/http: use strcasecmp(h->key, "WWW-Authenticate") instead of strncasecmp() The key is already normalized and should match completely. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 56ab5cdbe0bddb3edaf0e7bf82f2c04cea6e64a4 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 14:44:51 2017 +0200 s4:lib/http: remove indentation level from http_parse_auth_response() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit e42f12c6bec41a9d6c7f0f3c67b7fd9607b7457e Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 18:12:27 2017 +0200 s4:lib/http: let http_read_response_send/recv() also consume the body if it fits into a max value We need to consume full HTTP responses from the socket during the authentication exchanges, otherwise our HTTP parser gets out of sync for the next requests. This will be important for gensec mechs which use an even number for authentication packets. I guess this should be done just based on the Content-Length value and not based on the response code. So far I saw bodies with 200 and 401 codes. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 7b86da08ea760ac5198a9ca13a349c9536aba1a7 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jul 20 18:13:28 2017 +0200 s4:lib/http: lower HTTP_MAX_HEADER_SIZE from UINT_MAX to 0x1FFFF We don't need very large headers, the largest ones are "Authorization" or "WWW-Authenticate", but 128k should be more than enough for all headers. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: auth/common_auth.h | 10 + auth/ntlmssp/ntlmssp.c | 51 ++- auth/ntlmssp/ntlmssp_private.h | 20 +- auth/ntlmssp/ntlmssp_server.c | 221 +++++++----- python/samba/provision/kerberos.py | 2 +- ...m_winbind.py => pam_winbind_warn_pwd_expire.py} | 23 +- python/samba/tests/test_pam_winbind.sh | 1 - .../tests/test_pam_winbind_warn_pwd_expire.sh | 71 ++++ selftest/knownfail | 10 - selftest/tests.py | 4 + source3/auth/auth_generic.c | 49 ++- source3/client/client.c | 2 +- source3/script/tests/test_smbclient_s3.sh | 4 +- source3/winbindd/winbindd_irpc.c | 63 +++- source4/auth/ntlm/auth.c | 111 +++++-- source4/auth/ntlm/auth_winbind.c | 178 +++++++--- source4/lib/http/gensec/generic.c | 284 ++++++++++++++++ source4/lib/http/gensec/ntlm.c | 185 ----------- source4/lib/http/http.c | 63 +++- source4/lib/http/http.h | 7 +- source4/lib/http/http_auth.c | 83 ++++- source4/lib/http/http_internal.h | 1 + source4/lib/http/wscript_build | 6 +- source4/librpc/rpc/dcerpc_connect.c | 18 +- source4/librpc/rpc/dcerpc_roh.c | 10 +- source4/librpc/rpc/dcerpc_roh_channel_in.c | 5 +- source4/librpc/rpc/dcerpc_roh_channel_out.c | 8 +- source4/rpc_server/netlogon/dcerpc_netlogon.c | 369 ++++++++++++++++----- source4/selftest/tests.py | 4 +- 29 files changed, 1331 insertions(+), 532 deletions(-) copy python/samba/tests/{pam_winbind.py => pam_winbind_warn_pwd_expire.py} (69%) create mode 100755 python/samba/tests/test_pam_winbind_warn_pwd_expire.sh create mode 100644 source4/lib/http/gensec/generic.c delete mode 100644 source4/lib/http/gensec/ntlm.c Changeset truncated at 500 lines: diff --git a/auth/common_auth.h b/auth/common_auth.h index 5079717..3de227e 100644 --- a/auth/common_auth.h +++ b/auth/common_auth.h @@ -131,6 +131,16 @@ struct auth4_context { uint8_t *pauthoritative, void **server_returned_info, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); + struct tevent_req *(*check_ntlm_password_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct auth4_context *auth_ctx, + const struct auth_usersupplied_info *user_info); + NTSTATUS (*check_ntlm_password_recv)(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + uint8_t *pauthoritative, + void **server_returned_info, + DATA_BLOB *nt_session_key, + DATA_BLOB *lm_session_key); NTSTATUS (*get_ntlm_challenge)(struct auth4_context *auth_ctx, uint8_t chal[8]); diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index f79f0e2..36e7052 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -44,6 +44,13 @@ static const struct ntlmssp_callbacks { NTSTATUS (*sync_fn)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out); + struct tevent_req *(*send_fn)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct gensec_security *gensec_security, + const DATA_BLOB in); + NTSTATUS (*recv_fn)(struct tevent_req *req, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB *out); } ntlmssp_callbacks[] = { { .role = NTLMSSP_CLIENT, @@ -64,7 +71,8 @@ static const struct ntlmssp_callbacks { },{ .role = NTLMSSP_SERVER, .command = NTLMSSP_AUTH, - .sync_fn = gensec_ntlmssp_server_auth, + .send_fn = ntlmssp_server_auth_send, + .recv_fn = ntlmssp_server_auth_recv, } }; @@ -146,10 +154,13 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_security *gensec_securi } struct gensec_ntlmssp_update_state { + const struct ntlmssp_callbacks *cb; NTSTATUS status; DATA_BLOB out; }; +static void gensec_ntlmssp_update_done(struct tevent_req *subreq); + static struct tevent_req *gensec_ntlmssp_update_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_security *gensec_security, @@ -176,6 +187,23 @@ static struct tevent_req *gensec_ntlmssp_update_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + if (ntlmssp_callbacks[i].send_fn != NULL) { + struct tevent_req *subreq = NULL; + + state->cb = &ntlmssp_callbacks[i]; + + subreq = state->cb->send_fn(state, ev, + gensec_security, + in); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + gensec_ntlmssp_update_done, + req); + return req; + } + status = ntlmssp_callbacks[i].sync_fn(gensec_security, state, in, &state->out); @@ -192,6 +220,27 @@ static struct tevent_req *gensec_ntlmssp_update_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } +static void gensec_ntlmssp_update_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct gensec_ntlmssp_update_state *state = + tevent_req_data(req, + struct gensec_ntlmssp_update_state); + NTSTATUS status; + + status = state->cb->recv_fn(subreq, state, &state->out); + TALLOC_FREE(subreq); + if (GENSEC_UPDATE_IS_NTERROR(status)) { + tevent_req_nterror(req, status); + return; + } + + state->status = status; + tevent_req_done(req); +} + static NTSTATUS gensec_ntlmssp_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out) diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index eed48ed..95ec637 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -117,18 +117,14 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security TALLOC_CTX *out_mem_ctx, const DATA_BLOB request, DATA_BLOB *reply); -/** - * Next state function for the Authenticate packet (GENSEC wrapper) - * - * @param gensec_security GENSEC state - * @param out_mem_ctx Memory context for *out - * @param in The request, as a DATA_BLOB. reply.data must be NULL - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK if authentication sucessful - */ -NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out); +struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct gensec_security *gensec_security, + const DATA_BLOB in); +NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB *out); + /** * Start NTLMSSP on the server side diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index e17074e..417352b 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -21,6 +21,8 @@ */ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "lib/util/time_basic.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/ntlmssp_private.h" @@ -294,6 +296,9 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security } struct ntlmssp_server_auth_state { + struct gensec_security *gensec_security; + struct gensec_ntlmssp_context *gensec_ntlmssp; + DATA_BLOB in; struct auth_usersupplied_info *user_info; DATA_BLOB user_session_key; DATA_BLOB lm_session_key; @@ -304,6 +309,96 @@ struct ntlmssp_server_auth_state { uint8_t session_nonce[16]; }; +static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, + struct gensec_ntlmssp_context *gensec_ntlmssp, + struct ntlmssp_server_auth_state *state, + const DATA_BLOB request); +static void ntlmssp_server_auth_done(struct tevent_req *subreq); +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 tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct gensec_security *gensec_security, + const DATA_BLOB in) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct auth4_context *auth_context = gensec_security->auth_context; + struct tevent_req *req = NULL; + struct ntlmssp_server_auth_state *state = NULL; + uint8_t authoritative = 0; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct ntlmssp_server_auth_state); + if (req == NULL) { + return NULL; + } + state->gensec_security = gensec_security; + state->gensec_ntlmssp = gensec_ntlmssp; + state->in = in; + + status = ntlmssp_server_preauth(gensec_security, + gensec_ntlmssp, + state, in); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + if (auth_context->check_ntlm_password_send != NULL) { + struct tevent_req *subreq = NULL; + + subreq = auth_context->check_ntlm_password_send(state, ev, + auth_context, + state->user_info); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + ntlmssp_server_auth_done, + req); + return req; + } + + if (auth_context->check_ntlm_password == NULL) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } + + status = auth_context->check_ntlm_password(auth_context, + gensec_ntlmssp, + state->user_info, + &authoritative, + &gensec_ntlmssp->server_returned_info, + &state->user_session_key, + &state->lm_session_key); + if (!NT_STATUS_IS_OK(status)) { + DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n", + state->user_info->client.domain_name, + state->user_info->client.account_name, + nt_errstr(status)); + } + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + talloc_steal(state, state->user_session_key.data); + talloc_steal(state, state->lm_session_key.data); + + status = ntlmssp_server_postauth(gensec_security, + gensec_ntlmssp, + state, in); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + tevent_req_done(req); + return tevent_req_post(req, ev); +} + /** * Next state function for the Authenticate packet * @@ -721,41 +816,47 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, 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) +static void ntlmssp_server_auth_done(struct tevent_req *subreq) { + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct ntlmssp_server_auth_state *state = + tevent_req_data(req, + struct ntlmssp_server_auth_state); + struct gensec_security *gensec_security = state->gensec_security; + struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp; 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; + uint8_t authoritative = 0; + NTSTATUS status; - nt_status = auth_context->check_ntlm_password(auth_context, - gensec_ntlmssp, - user_info, - &authoritative, - &gensec_ntlmssp->server_returned_info, - user_session_key, lm_session_key); + status = auth_context->check_ntlm_password_recv(subreq, + gensec_ntlmssp, + &authoritative, + &gensec_ntlmssp->server_returned_info, + &state->user_session_key, + &state->lm_session_key); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n", + state->user_info->client.domain_name, + state->user_info->client.account_name, + nt_errstr(status)); } - - 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))); + if (tevent_req_nterror(req, status)) { + return; + } + talloc_steal(state, state->user_session_key.data); + talloc_steal(state, state->lm_session_key.data); + + status = ntlmssp_server_postauth(state->gensec_security, + state->gensec_ntlmssp, + state, state->in); + if (tevent_req_nterror(req, status)) { + return; } - 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; + tevent_req_done(req); } /** @@ -989,63 +1090,19 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, return nt_status; } - -/** - * Next state function for the NTLMSSP Authenticate packet - * - * @param gensec_security GENSEC state - * @param out_mem_ctx Memory context for *out - * @param in The request, as a DATA_BLOB. reply.data must be NULL - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK if authentication sucessful - */ - -NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - const DATA_BLOB in, DATA_BLOB *out) +NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB *out) { - struct gensec_ntlmssp_context *gensec_ntlmssp = - talloc_get_type_abort(gensec_security->private_data, - struct gensec_ntlmssp_context); - struct ntlmssp_server_auth_state *state; - NTSTATUS nt_status; + NTSTATUS status; - /* zero the outbound NTLMSSP packet */ *out = data_blob_null; - state = talloc_zero(gensec_ntlmssp, struct ntlmssp_server_auth_state); - if (state == NULL) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = ntlmssp_server_preauth(gensec_security, gensec_ntlmssp, state, in); - if (!NT_STATUS_IS_OK(nt_status)) { - TALLOC_FREE(state); - return nt_status; - } - - /* - * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth - * is required (by "ntlm auth = no" and "lm auth = no" being set in the - * smb.conf file) and no NTLMv2 response was sent then the password check - * will fail here. JRA. - */ - - /* Finally, actually ask if the password is OK */ - nt_status = ntlmssp_server_check_password(gensec_security, gensec_ntlmssp, - state->user_info, state, - &state->user_session_key, - &state->lm_session_key); - if (!NT_STATUS_IS_OK(nt_status)) { - TALLOC_FREE(state); - return nt_status; + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; } - /* When we get more async in the auth code behind - ntlmssp_state->check_password, the ntlmssp_server_postpath - can be done in a callback */ - - nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state, in); - TALLOC_FREE(state); - return nt_status; + tevent_req_received(req); + return NT_STATUS_OK; } diff --git a/python/samba/provision/kerberos.py b/python/samba/provision/kerberos.py index 24ced9c..4ed4d57 100644 --- a/python/samba/provision/kerberos.py +++ b/python/samba/provision/kerberos.py @@ -69,7 +69,7 @@ def create_kdc_conf(kdcconf, realm, domain, logdir): f.write("[dbmodules]\n") - f.write("\tdb_modules_dir = %s\n" % kdb_modules_dir) + f.write("\tdb_module_dir = %s\n" % kdb_modules_dir) f.write("\n") f.write("\t%s = {\n" % realm) diff --git a/python/samba/tests/pam_winbind.py b/python/samba/tests/pam_winbind_warn_pwd_expire.py similarity index 69% copy from python/samba/tests/pam_winbind.py copy to python/samba/tests/pam_winbind_warn_pwd_expire.py index 1054e86..c78cf58 100644 --- a/python/samba/tests/pam_winbind.py +++ b/python/samba/tests/pam_winbind_warn_pwd_expire.py @@ -20,11 +20,12 @@ import samba.tests import pypamtest import os -class SimplePamTests(samba.tests.TestCase): - def test_authenticate(self): +class PasswordExpirePamTests(samba.tests.TestCase): + def test_auth_expire_warning(self): domain = os.environ["DOMAIN"] username = os.environ["USERNAME"] password = os.environ["PASSWORD"] + warn_pwd_expire = int(os.environ["WARN_PWD_EXPIRE"]) unix_username = "%s/%s" % (domain, username) expected_rc = 0 # PAM_SUCCESS @@ -32,15 +33,9 @@ class SimplePamTests(samba.tests.TestCase): res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) self.assertTrue(res != None) - - def test_authenticate_error(self): - domain = os.environ["DOMAIN"] - username = os.environ["USERNAME"] - password = "WrongPassword" - unix_username = "%s/%s" % (domain, username) - expected_rc = 7 # PAM_AUTH_ERR - - tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) - - self.assertTrue(res != None) + if warn_pwd_expire == 0: + self.assertTrue(res.info == ()) + elif warn_pwd_expire == 50: + self.assertEqual(res.info[0], u"Your password will expire in 42 days.\n") + else: + self.assertEqual(warn_pwd_expire, 0) diff --git a/python/samba/tests/test_pam_winbind.sh b/python/samba/tests/test_pam_winbind.sh index fdd2870..c535759 100755 --- a/python/samba/tests/test_pam_winbind.sh +++ b/python/samba/tests/test_pam_winbind.sh @@ -39,5 +39,4 @@ exit_code=$? rm -rf $service_dir -exit_code=0 exit $exit_code diff --git a/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh new file mode 100755 index 0000000..305633d --- /dev/null +++ b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +PYTHON="$1" +PAM_WRAPPER_SO_PATH="$2" +shift 2 + +DOMAIN="$1" +export DOMAIN +USERNAME="$2" +export USERNAME +PASSWORD="$3" -- Samba Shared Repository