2005-05-31 17:46:45 +04:00
/*
Unix SMB / CIFS mplementation .
LDAP protocol helper functions for SAMBA
Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998
Copyright ( C ) Gerald Carter 2001 - 2003
Copyright ( C ) Shahms King 2001
Copyright ( C ) Andrew Bartlett 2002 - 2003
Copyright ( C ) Stefan ( metze ) Metzmacher 2002 - 2003
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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-05-31 17:46:45 +04: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-05-31 17:46:45 +04:00
*/
# include "includes.h"
# include "smbldap.h"
2005-09-30 21:13:37 +04:00
/**********************************************************************
Add the account - policies below the sambaDomain object to LDAP ,
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-25 01:04:07 +03:00
2005-09-30 21:13:37 +04:00
static NTSTATUS add_new_domain_account_policies ( struct smbldap_state * ldap_state ,
const char * domain_name )
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL ;
int i , rc ;
uint32 policy_default ;
const char * policy_attr = NULL ;
2007-11-16 01:19:52 +03:00
char * dn = NULL ;
2005-09-30 21:13:37 +04:00
LDAPMod * * mods = NULL ;
2007-03-01 03:49:28 +03:00
char * escape_domain_name ;
2005-09-30 21:13:37 +04:00
2006-02-25 01:04:07 +03:00
DEBUG ( 3 , ( " add_new_domain_account_policies: Adding new account policies for domain \n " ) ) ;
2007-03-01 03:49:28 +03:00
escape_domain_name = escape_rdn_val_string_alloc ( domain_name ) ;
if ( ! escape_domain_name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-11-16 01:19:52 +03:00
if ( asprintf ( & dn , " %s=%s,%s " ,
2005-09-30 21:13:37 +04:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
2007-11-16 01:19:52 +03:00
escape_domain_name , lp_ldap_suffix ( ) ) < 0 ) {
SAFE_FREE ( escape_domain_name ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-03-01 03:49:28 +03:00
SAFE_FREE ( escape_domain_name ) ;
2005-09-30 21:13:37 +04:00
for ( i = 1 ; decode_account_policy_name ( i ) ! = NULL ; i + + ) {
2007-11-16 01:19:52 +03:00
char * val = NULL ;
2005-09-30 21:13:37 +04:00
policy_attr = get_account_policy_attr ( i ) ;
if ( ! policy_attr ) {
DEBUG ( 0 , ( " add_new_domain_account_policies: ops. no policy! \n " ) ) ;
continue ;
}
if ( ! account_policy_get_default ( i , & policy_default ) ) {
DEBUG ( 0 , ( " add_new_domain_account_policies: failed to get default account policy \n " ) ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( dn ) ;
2005-09-30 21:13:37 +04:00
return ntstatus ;
}
DEBUG ( 10 , ( " add_new_domain_account_policies: adding \" %s \" with value: %d \n " , policy_attr , policy_default ) ) ;
2007-11-16 01:19:52 +03:00
if ( asprintf ( & val , " %d " , policy_default ) < 0 ) {
SAFE_FREE ( dn ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-09-30 21:13:37 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_REPLACE , policy_attr , val ) ;
rc = smbldap_modify ( ldap_state , dn , mods ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( val ) ;
2005-09-30 21:13:37 +04:00
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error = NULL ;
ldap_get_option ( ldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING , & ld_error ) ;
2006-02-25 01:04:07 +03:00
DEBUG ( 1 , ( " add_new_domain_account_policies: failed to add account policies to dn= %s with: %s \n \t %s \n " ,
2005-09-30 21:13:37 +04:00
dn , ldap_err2string ( rc ) ,
ld_error ? ld_error : " unknown " ) ) ;
SAFE_FREE ( ld_error ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( dn ) ;
2005-09-30 21:13:37 +04:00
ldap_mods_free ( mods , True ) ;
return ntstatus ;
}
}
2007-11-16 01:19:52 +03:00
SAFE_FREE ( dn ) ;
2005-09-30 21:13:37 +04:00
ldap_mods_free ( mods , True ) ;
return NT_STATUS_OK ;
}
2005-05-31 17:46:45 +04:00
/**********************************************************************
Add the sambaDomain to LDAP , so we don ' t have to search for this stuff
again . This is a once - add operation for now .
TODO : Add other attributes , and allow modification .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-25 01:04:07 +03:00
2007-11-16 01:19:52 +03:00
static NTSTATUS add_new_domain_info ( struct smbldap_state * ldap_state ,
const char * domain_name )
2005-05-31 17:46:45 +04:00
{
fstring sid_string ;
fstring algorithmic_rid_base_string ;
2007-11-16 01:19:52 +03:00
char * filter = NULL ;
char * dn = NULL ;
2005-05-31 17:46:45 +04:00
LDAPMod * * mods = NULL ;
int rc ;
LDAPMessage * result = NULL ;
int num_result ;
const char * * attr_list ;
2007-03-01 03:49:28 +03:00
char * escape_domain_name ;
/* escape for filter */
escape_domain_name = escape_ldap_string_alloc ( domain_name ) ;
if ( ! escape_domain_name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-05-31 17:46:45 +04:00
2007-11-16 01:19:52 +03:00
if ( asprintf ( & filter , " (&(%s=%s)(objectclass=%s)) " ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
escape_domain_name , LDAP_OBJ_DOMINFO ) < 0 ) {
SAFE_FREE ( escape_domain_name ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-03-01 03:49:28 +03:00
SAFE_FREE ( escape_domain_name ) ;
2005-05-31 17:46:45 +04:00
2007-11-16 01:19:52 +03:00
attr_list = get_attr_list ( NULL , dominfo_attr_list ) ;
2005-05-31 17:46:45 +04:00
rc = smbldap_search_suffix ( ldap_state , filter , attr_list , & result ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( attr_list ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( filter ) ;
2005-05-31 17:46:45 +04:00
if ( rc ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
}
num_result = ldap_count_entries ( ldap_state - > ldap_struct , result ) ;
2007-11-16 01:19:52 +03:00
2005-05-31 17:46:45 +04:00
if ( num_result > 1 ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 0 , ( " add_new_domain_info: More than domain with that name exists: bailing "
2006-02-04 01:19:41 +03:00
" out! \n " ) ) ;
2005-05-31 17:46:45 +04:00
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2007-11-16 01:19:52 +03:00
2005-05-31 17:46:45 +04:00
/* Check if we need to add an entry */
2006-02-25 01:04:07 +03:00
DEBUG ( 3 , ( " add_new_domain_info: Adding new domain \n " ) ) ;
2005-05-31 17:46:45 +04:00
2007-03-01 03:49:28 +03:00
/* this time escape for DN */
escape_domain_name = escape_rdn_val_string_alloc ( domain_name ) ;
if ( ! escape_domain_name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-11-16 01:19:52 +03:00
if ( asprintf ( & dn , " %s=%s,%s " ,
2006-02-04 01:19:41 +03:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
2007-11-16 01:19:52 +03:00
escape_domain_name , lp_ldap_suffix ( ) ) < 0 ) {
SAFE_FREE ( escape_domain_name ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-03-01 03:49:28 +03:00
SAFE_FREE ( escape_domain_name ) ;
2005-05-31 17:46:45 +04:00
/* Free original search */
ldap_msgfree ( result ) ;
2006-02-04 01:19:41 +03:00
/* make the changes - the entry *must* not already have samba
* attributes */
smbldap_set_mod ( & mods , LDAP_MOD_ADD ,
get_attr_key2string ( dominfo_attr_list ,
2007-11-16 01:19:52 +03:00
LDAP_ATTR_DOMAIN ) ,
2006-02-04 01:19:41 +03:00
domain_name ) ;
2005-05-31 17:46:45 +04:00
2006-02-04 01:19:41 +03:00
/* If we don't have an entry, then ask secrets.tdb for what it thinks.
2005-05-31 17:46:45 +04:00
It may choose to make it up */
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , get_global_sam_sid ( ) ) ;
2006-02-04 01:19:41 +03:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD ,
get_attr_key2string ( dominfo_attr_list ,
LDAP_ATTR_DOM_SID ) ,
sid_string ) ;
slprintf ( algorithmic_rid_base_string ,
sizeof ( algorithmic_rid_base_string ) - 1 , " %i " ,
algorithmic_rid_base ( ) ) ;
smbldap_set_mod ( & mods , LDAP_MOD_ADD ,
get_attr_key2string ( dominfo_attr_list ,
2007-11-16 01:19:52 +03:00
LDAP_ATTR_ALGORITHMIC_RID_BASE ) ,
2005-05-31 17:46:45 +04:00
algorithmic_rid_base_string ) ;
smbldap_set_mod ( & mods , LDAP_MOD_ADD , " objectclass " , LDAP_OBJ_DOMINFO ) ;
2007-11-16 01:19:52 +03:00
2006-02-04 01:19:41 +03:00
/* add the sambaNextUserRid attributes. */
2007-11-16 01:19:52 +03:00
2005-05-31 17:46:45 +04:00
{
2006-02-04 01:19:41 +03:00
uint32 rid = BASE_RID ;
2005-05-31 17:46:45 +04:00
fstring rid_str ;
2007-11-16 01:19:52 +03:00
2006-02-04 01:19:41 +03:00
fstr_sprintf ( rid_str , " %i " , rid ) ;
2006-02-25 01:04:07 +03:00
DEBUG ( 10 , ( " add_new_domain_info: setting next available user rid [%s] \n " , rid_str ) ) ;
2007-11-16 01:19:52 +03:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD ,
2006-02-04 01:19:41 +03:00
get_attr_key2string ( dominfo_attr_list ,
2007-11-16 01:19:52 +03:00
LDAP_ATTR_NEXT_USERRID ) ,
2005-05-31 17:46:45 +04:00
rid_str ) ;
}
2006-02-04 01:19:41 +03:00
rc = smbldap_add ( ldap_state , dn , mods ) ;
2005-05-31 17:46:45 +04:00
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error = NULL ;
2006-02-04 01:19:41 +03:00
ldap_get_option ( ldap_state - > ldap_struct ,
LDAP_OPT_ERROR_STRING , & ld_error ) ;
2006-02-25 01:04:07 +03:00
DEBUG ( 1 , ( " add_new_domain_info: failed to add domain dn= %s with: %s \n \t %s \n " ,
2006-02-04 01:19:41 +03:00
dn , ldap_err2string ( rc ) ,
ld_error ? ld_error : " unknown " ) ) ;
2005-05-31 17:46:45 +04:00
SAFE_FREE ( ld_error ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( dn ) ;
2005-05-31 17:46:45 +04:00
ldap_mods_free ( mods , True ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2006-02-25 01:04:07 +03:00
DEBUG ( 2 , ( " add_new_domain_info: added: domain = %s in the LDAP database \n " , domain_name ) ) ;
2005-05-31 17:46:45 +04:00
ldap_mods_free ( mods , True ) ;
2007-11-16 01:19:52 +03:00
SAFE_FREE ( dn ) ;
2005-05-31 17:46:45 +04:00
return NT_STATUS_OK ;
}
/**********************************************************************
Search for the domain info entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-25 01:04:07 +03:00
2005-05-31 17:46:45 +04:00
NTSTATUS smbldap_search_domain_info ( struct smbldap_state * ldap_state ,
LDAPMessage * * result , const char * domain_name ,
2007-10-19 04:40:25 +04:00
bool try_add )
2005-05-31 17:46:45 +04:00
{
2005-07-07 17:42:09 +04:00
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2007-11-16 01:19:52 +03:00
char * filter = NULL ;
2005-05-31 17:46:45 +04:00
int rc ;
const char * * attr_list ;
int count ;
2007-03-01 03:49:28 +03:00
char * escape_domain_name ;
2007-11-16 01:19:52 +03:00
2007-03-01 03:49:28 +03:00
escape_domain_name = escape_ldap_string_alloc ( domain_name ) ;
if ( ! escape_domain_name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-05-31 17:46:45 +04:00
2007-11-16 01:19:52 +03:00
if ( asprintf ( & filter , " (&(objectClass=%s)(%s=%s)) " ,
2005-05-31 17:46:45 +04:00
LDAP_OBJ_DOMINFO ,
2007-11-16 01:19:52 +03:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
escape_domain_name ) < 0 ) {
SAFE_FREE ( escape_domain_name ) ;
return NT_STATUS_NO_MEMORY ;
}
2007-03-01 03:49:28 +03:00
SAFE_FREE ( escape_domain_name ) ;
2005-05-31 17:46:45 +04:00
2006-02-25 01:04:07 +03:00
DEBUG ( 2 , ( " smbldap_search_domain_info: Searching for:[%s] \n " , filter ) ) ;
2005-05-31 17:46:45 +04:00
2006-02-04 01:19:41 +03:00
attr_list = get_attr_list ( NULL , dominfo_attr_list ) ;
2005-05-31 17:46:45 +04:00
rc = smbldap_search_suffix ( ldap_state , filter , attr_list , result ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( attr_list ) ;
2005-05-31 17:46:45 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 2 , ( " smbldap_search_domain_info: Problem during LDAPsearch: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUG ( 2 , ( " smbldap_search_domain_info: Query was: %s, %s \n " , lp_ldap_suffix ( ) , filter ) ) ;
2005-07-07 17:42:09 +04:00
goto failed ;
}
2007-11-16 01:19:52 +03:00
SAFE_FREE ( filter ) ;
2005-07-07 17:42:09 +04:00
count = ldap_count_entries ( ldap_state - > ldap_struct , * result ) ;
2007-11-16 01:19:52 +03:00
if ( count = = 1 ) {
2005-07-07 17:42:09 +04:00
return NT_STATUS_OK ;
2007-11-16 01:19:52 +03:00
}
2005-07-07 17:42:09 +04:00
ldap_msgfree ( * result ) ;
* result = NULL ;
2007-11-16 01:19:52 +03:00
2005-07-07 17:42:09 +04:00
if ( count < 1 ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 3 , ( " smbldap_search_domain_info: Got no domain info entries for domain \n " ) ) ;
2005-07-07 17:42:09 +04:00
if ( ! try_add )
goto failed ;
status = add_new_domain_info ( ldap_state , domain_name ) ;
2005-07-07 18:19:51 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 0 , ( " smbldap_search_domain_info: Adding domain info for %s failed with %s \n " ,
2005-07-07 17:42:09 +04:00
domain_name , nt_errstr ( status ) ) ) ;
goto failed ;
2005-05-31 17:46:45 +04:00
}
2007-11-16 01:19:52 +03:00
2005-09-30 21:13:37 +04:00
status = add_new_domain_account_policies ( ldap_state , domain_name ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 0 , ( " smbldap_search_domain_info: Adding domain account policies for %s failed with %s \n " ,
2005-09-30 21:13:37 +04:00
domain_name , nt_errstr ( status ) ) ) ;
goto failed ;
}
2005-07-07 17:42:09 +04:00
return smbldap_search_domain_info ( ldap_state , result , domain_name , False ) ;
2007-11-16 01:19:52 +03:00
2005-07-07 17:42:09 +04:00
}
if ( count > 1 ) {
2006-02-25 01:04:07 +03:00
DEBUG ( 0 , ( " smbldap_search_domain_info: Got too many (%d) domain info entries for domain %s \n " ,
2005-05-31 17:46:45 +04:00
count , domain_name ) ) ;
2005-07-07 17:42:09 +04:00
goto failed ;
2005-05-31 17:46:45 +04:00
}
2005-07-07 17:42:09 +04:00
failed :
return status ;
2005-05-31 17:46:45 +04:00
}