2005-01-12 14:43:18 +03:00
/*
Unix SMB / CIFS implementation .
2008-03-21 12:35:54 +03:00
Copyright ( C ) Volker Lendecke 2005
2005-01-12 14:43:18 +03:00
Copyright ( C ) Andrew Tridgell 2005
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-01-12 14:43:18 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-01-12 14:43:18 +03:00
*/
/*
composite API helper functions
*/
# include "includes.h"
2005-02-03 14:56:03 +03:00
# include "lib/events/events.h"
2005-01-12 14:43:18 +03:00
# include "libcli/raw/libcliraw.h"
2006-07-30 20:48:41 +04:00
# include "libcli/smb2/smb2.h"
2005-01-12 14:43:18 +03:00
# include "libcli/composite/composite.h"
2008-09-23 10:06:33 +04:00
# include "../libcli/nbt/libnbt.h"
2005-01-12 14:43:18 +03:00
2006-07-30 20:48:41 +04:00
/*
create a new composite_context structure
and initialize it
*/
_PUBLIC_ struct composite_context * composite_create ( TALLOC_CTX * mem_ctx ,
2008-12-29 22:24:57 +03:00
struct tevent_context * ev )
2006-07-30 20:48:41 +04:00
{
struct composite_context * c ;
c = talloc_zero ( mem_ctx , struct composite_context ) ;
if ( ! c ) return NULL ;
c - > state = COMPOSITE_STATE_IN_PROGRESS ;
2009-08-07 11:14:13 +04:00
c - > event_ctx = ev ;
2006-07-30 20:48:41 +04:00
return c ;
}
2005-01-12 14:43:18 +03:00
/*
block until a composite function has completed , then return the status
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ NTSTATUS composite_wait ( struct composite_context * c )
2005-01-12 14:43:18 +03:00
{
if ( c = = NULL ) return NT_STATUS_NO_MEMORY ;
2007-10-07 02:28:14 +04:00
c - > used_wait = true ;
2005-12-08 04:13:45 +03:00
2005-09-26 15:47:55 +04:00
while ( c - > state < COMPOSITE_STATE_DONE ) {
2010-05-25 23:26:42 +04:00
if ( tevent_loop_once ( c - > event_ctx ) ! = 0 ) {
2005-01-12 14:43:18 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
}
return c - > status ;
}
2008-05-16 09:02:58 +04:00
/*
block until a composite function has completed , then return the status .
Free the composite context before returning
*/
_PUBLIC_ NTSTATUS composite_wait_free ( struct composite_context * c )
{
NTSTATUS status = composite_wait ( c ) ;
talloc_free ( c ) ;
return status ;
}
2005-12-08 04:13:45 +03:00
/*
callback from composite_done ( ) and composite_error ( )
this is used to allow for a composite function to complete without
going through any state transitions . When that happens the caller
has had no opportunity to fill in the async callback fields
2009-02-02 12:17:00 +03:00
( ctx - > async . fn and ctx - > async . private_data ) which means the usual way of
2005-12-08 04:13:45 +03:00
dealing with composite functions doesn ' t work . To cope with this ,
we trigger a timer event that will happen then the event loop is
re - entered . This gives the caller a chance to setup the callback ,
and allows the caller to ignore the fact that the composite
function completed early
*/
2008-12-29 22:24:57 +03:00
static void composite_trigger ( struct tevent_context * ev , struct tevent_timer * te ,
2005-12-08 04:13:45 +03:00
struct timeval t , void * ptr )
{
struct composite_context * c = talloc_get_type ( ptr , struct composite_context ) ;
if ( c - > async . fn ) {
c - > async . fn ( c ) ;
}
}
2006-03-05 20:15:19 +03:00
_PUBLIC_ void composite_error ( struct composite_context * ctx , NTSTATUS status )
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
{
2008-05-16 09:02:58 +04:00
/* you are allowed to pass NT_STATUS_OK to composite_error(), in which
case it is equivalent to composite_done ( ) */
if ( NT_STATUS_IS_OK ( status ) ) {
composite_done ( ctx ) ;
return ;
}
2005-12-08 04:13:45 +03:00
if ( ! ctx - > used_wait & & ! ctx - > async . fn ) {
2010-05-25 23:26:42 +04:00
tevent_add_timer ( ctx - > event_ctx , ctx , timeval_zero ( ) , composite_trigger , ctx ) ;
2005-12-08 04:13:45 +03:00
}
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
ctx - > status = status ;
2008-02-12 14:16:38 +03:00
ctx - > state = COMPOSITE_STATE_ERROR ;
if ( ctx - > async . fn ! = NULL ) {
ctx - > async . fn ( ctx ) ;
}
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
}
2007-10-07 02:28:14 +04:00
_PUBLIC_ bool composite_nomem ( const void * p , struct composite_context * ctx )
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
{
if ( p ! = NULL ) {
2007-10-07 02:28:14 +04:00
return false ;
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
}
2005-10-10 23:57:55 +04:00
composite_error ( ctx , NT_STATUS_NO_MEMORY ) ;
2007-10-07 02:28:14 +04:00
return true ;
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
}
2008-02-12 14:16:38 +03:00
_PUBLIC_ bool composite_is_ok ( struct composite_context * ctx )
{
if ( NT_STATUS_IS_OK ( ctx - > status ) ) {
return true ;
}
composite_error ( ctx , ctx - > status ) ;
return false ;
}
2006-03-05 20:15:19 +03:00
_PUBLIC_ void composite_done ( struct composite_context * ctx )
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
{
2005-12-08 04:13:45 +03:00
if ( ! ctx - > used_wait & & ! ctx - > async . fn ) {
2010-05-25 23:26:42 +04:00
tevent_add_timer ( ctx - > event_ctx , ctx , timeval_zero ( ) , composite_trigger , ctx ) ;
2005-12-08 04:13:45 +03:00
}
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
ctx - > state = COMPOSITE_STATE_DONE ;
if ( ctx - > async . fn ! = NULL ) {
ctx - > async . fn ( ctx ) ;
}
}
2006-03-05 20:15:19 +03:00
_PUBLIC_ void composite_continue ( struct composite_context * ctx ,
2006-03-12 16:14:21 +03:00
struct composite_context * new_ctx ,
void ( * continuation ) ( struct composite_context * ) ,
void * private_data )
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
{
2005-10-10 23:57:55 +04:00
if ( composite_nomem ( new_ctx , ctx ) ) return ;
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
new_ctx - > async . fn = continuation ;
new_ctx - > async . private_data = private_data ;
2006-09-08 07:06:47 +04:00
/* if we are setting up a continuation, and the context has
already finished , then we should run the callback with an
immediate event , otherwise we can be stuck forever */
if ( new_ctx - > state > = COMPOSITE_STATE_DONE & & continuation ) {
2010-05-25 23:26:42 +04:00
tevent_add_timer ( new_ctx - > event_ctx , new_ctx , timeval_zero ( ) , composite_trigger , new_ctx ) ;
2006-09-08 07:06:47 +04:00
}
r10852: Continuation-based programming can become a bit spaghetti...
Initialize a domain structure properly. Excerpt from wb_init_domain.c:
/*
* Initialize a domain:
*
* - With schannel credentials, try to open the SMB connection with the machine
* creds. Fall back to anonymous.
*
* - If we have schannel creds, do the auth2 and open the schannel'ed netlogon
* pipe.
*
* - Open LSA. If we have machine creds, try to open with ntlmssp. Fall back
* to schannel and then to anon bind.
*
* - With queryinfopolicy, verify that we're talking to the right domain
*
* A bit complex, but with all the combinations I think it's the best we can
* get. NT4, W2k3SP1 and W2k all have different combinations, but in the end we
* have a signed&sealed lsa connection on all of them.
*
* Is this overkill? In particular the authenticated SMB connection seems a
* bit overkill, given that we do schannel for netlogon and ntlmssp for
* lsa later on w2k3, the others don't do this anyway.
*/
Thanks to Jeremy for his detective work, and to the Samba4 team for providing
such a great infrastructure.
Next step is to connect to SAM. Do it via LDAP if we can, fall back to samr
with all we have.
Volker
(This used to be commit 3e69fdc07cd76b4bc01b032148609ee4b59b8be7)
2005-10-10 00:32:24 +04:00
}
2006-03-05 20:15:19 +03:00
_PUBLIC_ void composite_continue_smb ( struct composite_context * ctx ,
2006-03-12 16:14:21 +03:00
struct smbcli_request * new_req ,
void ( * continuation ) ( struct smbcli_request * ) ,
void * private_data )
2005-11-23 21:49:30 +03:00
{
if ( composite_nomem ( new_req , ctx ) ) return ;
2014-08-28 13:05:23 +04:00
if ( new_req - > state > SMBCLI_REQUEST_RECV ) {
composite_error ( ctx , new_req - > status ) ;
return ;
}
2005-11-23 21:49:30 +03:00
new_req - > async . fn = continuation ;
2009-02-02 12:17:00 +03:00
new_req - > async . private_data = private_data ;
2005-11-23 21:49:30 +03:00
}
2005-11-30 15:39:32 +03:00
2006-07-30 20:48:41 +04:00
_PUBLIC_ void composite_continue_smb2 ( struct composite_context * ctx ,
struct smb2_request * new_req ,
void ( * continuation ) ( struct smb2_request * ) ,
void * private_data )
{
if ( composite_nomem ( new_req , ctx ) ) return ;
2014-08-28 13:05:23 +04:00
if ( new_req - > state > SMB2_REQUEST_RECV ) {
composite_error ( ctx , new_req - > status ) ;
return ;
}
2006-07-30 20:48:41 +04:00
new_req - > async . fn = continuation ;
2008-05-16 09:02:58 +04:00
new_req - > async . private_data = private_data ;
2006-07-30 20:48:41 +04:00
}
2006-03-05 20:15:19 +03:00
_PUBLIC_ void composite_continue_nbt ( struct composite_context * ctx ,
2006-03-12 16:14:21 +03:00
struct nbt_name_request * new_req ,
void ( * continuation ) ( struct nbt_name_request * ) ,
void * private_data )
2005-11-30 15:39:32 +03:00
{
if ( composite_nomem ( new_req , ctx ) ) return ;
new_req - > async . fn = continuation ;
2008-09-23 11:02:16 +04:00
new_req - > async . private_data = private_data ;
2005-11-30 15:39:32 +03:00
}