2004-08-12 08:55:59 +04:00
/*
Unix SMB / CIFS Implementation .
LDAP protocol helper functions for SAMBA
Copyright ( C ) Volker Lendecke 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# ifndef _SMB_LDAP_H
# define _SMB_LDAP_H
enum ldap_request_tag {
LDAP_TAG_BindRequest = 0 ,
LDAP_TAG_BindResponse = 1 ,
LDAP_TAG_UnbindRequest = 2 ,
LDAP_TAG_SearchRequest = 3 ,
LDAP_TAG_SearchResultEntry = 4 ,
LDAP_TAG_SearchResultDone = 5 ,
LDAP_TAG_ModifyRequest = 6 ,
LDAP_TAG_ModifyResponse = 7 ,
LDAP_TAG_AddRequest = 8 ,
LDAP_TAG_AddResponse = 9 ,
2004-09-27 19:40:12 +04:00
LDAP_TAG_DelRequest = 10 ,
LDAP_TAG_DelResponse = 11 ,
2004-08-12 08:55:59 +04:00
LDAP_TAG_ModifyDNRequest = 12 ,
LDAP_TAG_ModifyDNResponse = 13 ,
LDAP_TAG_CompareRequest = 14 ,
LDAP_TAG_CompareResponse = 15 ,
LDAP_TAG_AbandonRequest = 16 ,
LDAP_TAG_SearchResultReference = 19 ,
LDAP_TAG_ExtendedRequest = 23 ,
LDAP_TAG_ExtendedResponse = 24
} ;
enum ldap_auth_mechanism {
LDAP_AUTH_MECH_SIMPLE = 0 ,
LDAP_AUTH_MECH_SASL = 3
} ;
2004-08-13 09:26:38 +04:00
enum ldap_result_code {
2004-10-21 00:34:32 +04:00
LDAP_SUCCESS = 0 ,
LDAP_OPERATIONS_ERROR = 1 ,
LDAP_PROTOCOL_ERROR = 2 ,
LDAP_TIME_LIMIT_EXCEEDED = 3 ,
LDAP_SIZE_LIMIT_EXCEEDED = 4 ,
LDAP_COMPARE_FALSE = 5 ,
2004-10-21 02:44:08 +04:00
LDAP_COMPARE_TRUE = 6 ,
2004-10-21 00:34:32 +04:00
LDAP_AUTH_METHOD_NOT_SUPPORTED = 7 ,
LDAP_STRONG_AUTH_REQUIRED = 8 ,
LDAP_REFERRAL = 10 ,
LDAP_ADMIN_LIMIT_EXCEEDED = 11 ,
LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12 ,
LDAP_CONFIDENTIALITY_REQUIRED = 13 ,
LDAP_SASL_BIND_IN_PROGRESS = 14 ,
LDAP_NO_SUCH_ATTRIBUTE = 16 ,
LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17 ,
LDAP_INAPPROPRIATE_MATCHING = 18 ,
LDAP_CONSTRAINT_VIOLATION = 19 ,
LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20 ,
LDAP_INVALID_ATTRIBUTE_SYNTAX = 21 ,
LDAP_NO_SUCH_OBJECT = 32 ,
LDAP_ALIAS_PROBLEM = 33 ,
LDAP_INVALID_DN_SYNTAX = 34 ,
LDAP_ALIAS_DEREFERENCING_PROBLEM = 36 ,
LDAP_INAPPROPRIATE_AUTHENTICATION = 48 ,
LDAP_INVALID_CREDENTIALS = 49 ,
LDAP_INSUFFICIENT_ACCESS_RIGHTs = 50 ,
LDAP_BUSY = 51 ,
LDAP_UNAVAILABLE = 52 ,
LDAP_UNWILLING_TO_PERFORM = 53 ,
LDAP_LOOP_DETECT = 54 ,
LDAP_NAMING_VIOLATION = 64 ,
LDAP_OBJECT_CLASS_VIOLATION = 65 ,
LDAP_NOT_ALLOWED_ON_NON_LEAF = 66 ,
LDAP_NOT_ALLOWED_ON_RDN = 67 ,
LDAP_ENTRY_ALREADY_EXISTS = 68 ,
LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69 ,
LDAP_AFFECTS_MULTIPLE_DSAS = 71 ,
LDAP_OTHER = 80
2004-08-13 09:26:38 +04:00
} ;
2004-08-12 08:55:59 +04:00
struct ldap_Result {
int resultcode ;
const char * dn ;
const char * errormessage ;
const char * referral ;
} ;
struct ldap_attribute {
const char * name ;
int num_values ;
DATA_BLOB * values ;
} ;
struct ldap_BindRequest {
int version ;
const char * dn ;
enum ldap_auth_mechanism mechanism ;
union {
const char * password ;
struct {
const char * mechanism ;
2004-08-13 09:26:38 +04:00
DATA_BLOB secblob ;
2004-08-12 08:55:59 +04:00
} SASL ;
} creds ;
} ;
struct ldap_BindResponse {
struct ldap_Result response ;
union {
2004-08-13 10:27:02 +04:00
DATA_BLOB secblob ;
2004-08-13 09:26:38 +04:00
} SASL ;
2004-08-12 08:55:59 +04:00
} ;
struct ldap_UnbindRequest {
2004-08-18 17:01:10 +04:00
uint8_t __dummy ;
2004-08-12 08:55:59 +04:00
} ;
enum ldap_scope {
LDAP_SEARCH_SCOPE_BASE = 0 ,
LDAP_SEARCH_SCOPE_SINGLE = 1 ,
LDAP_SEARCH_SCOPE_SUB = 2
} ;
enum ldap_deref {
LDAP_DEREFERENCE_NEVER = 0 ,
LDAP_DEREFERENCE_IN_SEARCHING = 1 ,
LDAP_DEREFERENCE_FINDING_BASE = 2 ,
LDAP_DEREFERENCE_ALWAYS
} ;
struct ldap_SearchRequest {
const char * basedn ;
enum ldap_scope scope ;
enum ldap_deref deref ;
2005-01-27 09:16:59 +03:00
uint32_t timelimit ;
uint32_t sizelimit ;
2004-08-12 08:55:59 +04:00
BOOL attributesonly ;
char * filter ;
int num_attributes ;
const char * * attributes ;
} ;
struct ldap_SearchResEntry {
const char * dn ;
int num_attributes ;
struct ldap_attribute * attributes ;
} ;
struct ldap_SearchResRef {
2004-11-06 23:43:36 +03:00
const char * referral ;
2004-08-12 08:55:59 +04:00
} ;
enum ldap_modify_type {
LDAP_MODIFY_NONE = - 1 ,
LDAP_MODIFY_ADD = 0 ,
LDAP_MODIFY_DELETE = 1 ,
LDAP_MODIFY_REPLACE = 2
} ;
struct ldap_mod {
enum ldap_modify_type type ;
struct ldap_attribute attrib ;
} ;
struct ldap_ModifyRequest {
const char * dn ;
int num_mods ;
struct ldap_mod * mods ;
} ;
struct ldap_AddRequest {
const char * dn ;
int num_attributes ;
struct ldap_attribute * attributes ;
} ;
2004-09-27 19:40:12 +04:00
struct ldap_DelRequest {
2004-08-12 08:55:59 +04:00
const char * dn ;
} ;
struct ldap_ModifyDNRequest {
const char * dn ;
const char * newrdn ;
BOOL deleteolddn ;
const char * newsuperior ;
} ;
struct ldap_CompareRequest {
const char * dn ;
const char * attribute ;
2004-09-29 16:18:06 +04:00
DATA_BLOB value ;
2004-08-12 08:55:59 +04:00
} ;
struct ldap_AbandonRequest {
2005-01-27 09:16:59 +03:00
uint32_t messageid ;
2004-08-12 08:55:59 +04:00
} ;
struct ldap_ExtendedRequest {
const char * oid ;
DATA_BLOB value ;
} ;
struct ldap_ExtendedResponse {
struct ldap_Result response ;
const char * name ;
DATA_BLOB value ;
} ;
union ldap_Request {
struct ldap_BindRequest BindRequest ;
struct ldap_BindResponse BindResponse ;
struct ldap_UnbindRequest UnbindRequest ;
struct ldap_SearchRequest SearchRequest ;
struct ldap_SearchResEntry SearchResultEntry ;
struct ldap_Result SearchResultDone ;
struct ldap_SearchResRef SearchResultReference ;
struct ldap_ModifyRequest ModifyRequest ;
struct ldap_Result ModifyResponse ;
struct ldap_AddRequest AddRequest ;
struct ldap_Result AddResponse ;
2004-09-27 19:40:12 +04:00
struct ldap_DelRequest DelRequest ;
struct ldap_Result DelResponse ;
2004-08-12 08:55:59 +04:00
struct ldap_ModifyDNRequest ModifyDNRequest ;
struct ldap_Result ModifyDNResponse ;
struct ldap_CompareRequest CompareRequest ;
struct ldap_Result CompareResponse ;
struct ldap_AbandonRequest AbandonRequest ;
struct ldap_ExtendedRequest ExtendedRequest ;
struct ldap_ExtendedResponse ExtendedResponse ;
} ;
struct ldap_Control {
const char * oid ;
BOOL critical ;
DATA_BLOB value ;
} ;
struct ldap_message {
TALLOC_CTX * mem_ctx ;
2005-01-27 09:16:59 +03:00
uint32_t messageid ;
uint8_t type ;
2004-08-12 08:55:59 +04:00
union ldap_Request r ;
int num_controls ;
struct ldap_Control * controls ;
} ;
struct ldap_queue_entry {
struct ldap_queue_entry * next , * prev ;
int msgid ;
struct ldap_message * msg ;
} ;
struct ldap_connection {
TALLOC_CTX * mem_ctx ;
int sock ;
int next_msgid ;
char * host ;
2005-01-27 09:16:59 +03:00
uint16_t port ;
2004-08-12 08:55:59 +04:00
BOOL ldaps ;
const char * auth_dn ;
const char * simple_pw ;
/* Current outstanding search entry */
int searchid ;
/* List for incoming search entries */
struct ldap_queue_entry * search_entries ;
/* Outstanding LDAP requests that have not yet been replied to */
struct ldap_queue_entry * outstanding ;
2004-08-13 09:26:38 +04:00
/* Let's support SASL */
struct gensec_security * gensec ;
2004-08-12 08:55:59 +04:00
} ;
2004-08-20 11:39:19 +04:00
/* Hmm. A blob might be more appropriate here :-) */
struct ldap_val {
unsigned int length ;
void * data ;
} ;
enum ldap_parse_op { LDAP_OP_SIMPLE , LDAP_OP_AND , LDAP_OP_OR , LDAP_OP_NOT } ;
struct ldap_parse_tree {
enum ldap_parse_op operation ;
union {
struct {
char * attr ;
struct ldap_val value ;
} simple ;
struct {
unsigned int num_elements ;
struct ldap_parse_tree * * elements ;
} list ;
struct {
struct ldap_parse_tree * child ;
} not ;
} u ;
} ;
# define LDAP_ALL_SEP "()&|=!"
# define LDAP_CONNECTION_TIMEOUT 10000
2005-02-10 10:08:40 +03:00
/* The following definitions come from libcli/ldap/ldap.c */
BOOL ldap_encode ( struct ldap_message * msg , DATA_BLOB * result ) ;
BOOL ldap_decode ( struct asn1_data * data , struct ldap_message * msg ) ;
BOOL ldap_parse_basic_url ( TALLOC_CTX * mem_ctx , const char * url ,
char * * host , uint16_t * port , BOOL * ldaps ) ;
/* The following definitions come from libcli/ldap/ldap_client.c */
struct ldap_connection * ldap_connect ( TALLOC_CTX * mem_ctx , const char * url ) ;
struct ldap_message * new_ldap_message ( TALLOC_CTX * mem_ctx ) ;
BOOL ldap_send_msg ( struct ldap_connection * conn , struct ldap_message * msg ,
const struct timeval * endtime ) ;
BOOL ldap_receive_msg ( struct ldap_connection * conn , struct ldap_message * msg ,
const struct timeval * endtime ) ;
struct ldap_message * ldap_receive ( struct ldap_connection * conn , int msgid ,
const struct timeval * endtime ) ;
struct ldap_message * ldap_transaction ( struct ldap_connection * conn ,
struct ldap_message * request ) ;
int ldap_bind_simple ( struct ldap_connection * conn , const char * userdn , const char * password ) ;
r6028: A MAJOR update to intergrate the new credentails system fully with
GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'.
GENSEC now no longer has it's own handling of 'set username' etc,
instead it uses cli_credentials calls.
In order to link the credentails code right though Samba, a lot of
interfaces have changed to remove 'username, domain, password'
arguments, and these have been replaced with a single 'struct
cli_credentials'.
In the session setup code, a new parameter 'workgroup' contains the
client/server current workgroup, which seems unrelated to the
authentication exchange (it was being filled in from the auth info).
This allows in particular kerberos to only call back for passwords
when it actually needs to perform the kinit.
The kerberos code has been modified not to use the SPNEGO provided
'principal name' (in the mechListMIC), but to instead use the name the
host was connected to as. This better matches Microsoft behaviour,
is more secure and allows better use of standard kerberos functions.
To achieve this, I made changes to our socket code so that the
hostname (before name resolution) is now recorded on the socket.
In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now
in libcli/auth/schannel.c, and it looks much more like a standard
GENSEC module. The actual sign/seal code moved to
libcli/auth/schannel_sign.c in a previous commit.
The schannel credentails structure is now merged with the rest of the
credentails, as many of the values (username, workstation, domain)
where already present there. This makes handling this in a generic
manner much easier, as there is no longer a custom entry-point.
The auth_domain module continues to be developed, but is now just as
functional as auth_winbind. The changes here are consequential to the
schannel changes.
The only removed function at this point is the RPC-LOGIN test
(simulating the load of a WinXP login), which needs much more work to
clean it up (it contains copies of too much code from all over the
torture suite, and I havn't been able to penetrate its 'structure').
Andrew Bartlett
(This used to be commit 2301a4b38a21aa60917973451687063d83d18d66)
2005-03-24 07:14:06 +03:00
int ldap_bind_sasl ( struct ldap_connection * conn , struct cli_credentials * creds ) ;
2005-02-10 10:08:40 +03:00
struct ldap_connection * ldap_setup_connection ( TALLOC_CTX * mem_ctx , const char * url ,
const char * userdn , const char * password ) ;
struct ldap_connection * ldap_setup_connection_with_sasl ( TALLOC_CTX * mem_ctx , const char * url ,
r6028: A MAJOR update to intergrate the new credentails system fully with
GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'.
GENSEC now no longer has it's own handling of 'set username' etc,
instead it uses cli_credentials calls.
In order to link the credentails code right though Samba, a lot of
interfaces have changed to remove 'username, domain, password'
arguments, and these have been replaced with a single 'struct
cli_credentials'.
In the session setup code, a new parameter 'workgroup' contains the
client/server current workgroup, which seems unrelated to the
authentication exchange (it was being filled in from the auth info).
This allows in particular kerberos to only call back for passwords
when it actually needs to perform the kinit.
The kerberos code has been modified not to use the SPNEGO provided
'principal name' (in the mechListMIC), but to instead use the name the
host was connected to as. This better matches Microsoft behaviour,
is more secure and allows better use of standard kerberos functions.
To achieve this, I made changes to our socket code so that the
hostname (before name resolution) is now recorded on the socket.
In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now
in libcli/auth/schannel.c, and it looks much more like a standard
GENSEC module. The actual sign/seal code moved to
libcli/auth/schannel_sign.c in a previous commit.
The schannel credentails structure is now merged with the rest of the
credentails, as many of the values (username, workstation, domain)
where already present there. This makes handling this in a generic
manner much easier, as there is no longer a custom entry-point.
The auth_domain module continues to be developed, but is now just as
functional as auth_winbind. The changes here are consequential to the
schannel changes.
The only removed function at this point is the RPC-LOGIN test
(simulating the load of a WinXP login), which needs much more work to
clean it up (it contains copies of too much code from all over the
torture suite, and I havn't been able to penetrate its 'structure').
Andrew Bartlett
(This used to be commit 2301a4b38a21aa60917973451687063d83d18d66)
2005-03-24 07:14:06 +03:00
struct cli_credentials * creds ) ;
2005-02-10 10:08:40 +03:00
BOOL ldap_abandon_message ( struct ldap_connection * conn , int msgid ,
const struct timeval * endtime ) ;
BOOL ldap_setsearchent ( struct ldap_connection * conn , struct ldap_message * msg ,
const struct timeval * endtime ) ;
struct ldap_message * ldap_getsearchent ( struct ldap_connection * conn ,
const struct timeval * endtime ) ;
void ldap_endsearchent ( struct ldap_connection * conn ,
const struct timeval * endtime ) ;
struct ldap_message * ldap_searchone ( struct ldap_connection * conn ,
struct ldap_message * msg ,
const struct timeval * endtime ) ;
BOOL ldap_find_single_value ( struct ldap_message * msg , const char * attr ,
DATA_BLOB * value ) ;
BOOL ldap_find_single_string ( struct ldap_message * msg , const char * attr ,
TALLOC_CTX * mem_ctx , char * * value ) ;
BOOL ldap_find_single_int ( struct ldap_message * msg , const char * attr ,
int * value ) ;
int ldap_error ( struct ldap_connection * conn ) ;
NTSTATUS ldap2nterror ( int ldaperror ) ;
/* The following definitions come from libcli/ldap/ldap_ldif.c */
BOOL add_value_to_attrib ( TALLOC_CTX * mem_ctx , struct ldap_val * value ,
struct ldap_attribute * attrib ) ;
BOOL add_attrib_to_array_talloc ( TALLOC_CTX * mem_ctx ,
const struct ldap_attribute * attrib ,
struct ldap_attribute * * attribs ,
int * num_attribs ) ;
BOOL add_mod_to_array_talloc ( TALLOC_CTX * mem_ctx ,
struct ldap_mod * mod ,
struct ldap_mod * * mods ,
int * num_mods ) ;
struct ldap_message * ldap_ldif2msg ( TALLOC_CTX * mem_ctx , const char * s ) ;
2004-08-12 08:55:59 +04:00
# endif