2001-09-26 00:21:21 +04:00
/*
2003-05-14 07:32:20 +04:00
Unix SMB / CIFS mplementation .
2001-09-26 00:21:21 +04:00
LDAP protocol helper functions for SAMBA
2002-09-25 19:19:00 +04:00
Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998
2003-05-14 07:32:20 +04:00
Copyright ( C ) Gerald Carter 2001 - 2003
2002-09-25 19:19:00 +04:00
Copyright ( C ) Shahms King 2001
2003-06-25 16:51:58 +04:00
Copyright ( C ) Andrew Bartlett 2002 - 2003
2002-09-25 19:19:00 +04:00
Copyright ( C ) Stefan ( metze ) Metzmacher 2002
2002-08-17 21:00:51 +04:00
2001-09-26 00:21:21 +04:00
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 .
*/
/* TODO:
* persistent connections : if using NSS LDAP , many connections are made
* however , using only one within Samba would be nice
*
* Clean up SSL stuff , compile on OpenLDAP 1. x , 2. x , and Netscape SDK
*
* Other LDAP based login attributes : accountExpires , etc .
* ( should be the domain of Samba proper , but the sam_password / SAM_ACCOUNT
* structures don ' t have fields for some of these attributes )
*
* SSL is done , but can ' t get the certificate based authentication to work
* against on my test platform ( Linux 2.4 , OpenLDAP 2. x )
*/
/* NOTE: this will NOT work against an Active Directory server
* due to the fact that the two password fields cannot be retrieved
* from a server ; recommend using security = domain in this situation
* and / or winbind
*/
2003-05-14 07:32:20 +04:00
# include "includes.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_PASSDB
2001-09-26 00:21:21 +04:00
# include <lber.h>
# include <ldap.h>
2003-06-25 16:51:58 +04:00
/*
* Work around versions of the LDAP client libs that don ' t have the OIDs
* defined , or have them defined under the old name .
* This functionality is really a factor of the server , not the client
*
*/
2003-04-23 15:03:08 +04:00
2003-06-07 02:50:54 +04:00
# if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
# define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
# elif !defined(LDAP_EXOP_MODIFY_PASSWD)
# define "1.3.6.1.4.1.4203.1.11.1"
# endif
# if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
# define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
# elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
# define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
# endif
# if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
# define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
# elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
# define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
# endif
2003-06-25 16:51:58 +04:00
2001-09-26 00:21:21 +04:00
# ifndef SAM_ACCOUNT
# define SAM_ACCOUNT struct sam_passwd
# endif
2003-06-05 06:34:30 +04:00
# include "smbldap.h"
2002-03-02 13:16:28 +03:00
struct ldapsam_privates {
2003-06-21 04:45:03 +04:00
struct smbldap_state * smbldap_state ;
2002-03-02 13:16:28 +03:00
/* Former statics */
2001-09-26 00:21:21 +04:00
LDAPMessage * result ;
LDAPMessage * entry ;
2002-03-01 18:17:10 +03:00
int index ;
2002-03-02 13:16:28 +03:00
2003-04-28 14:20:55 +04:00
const char * domain_name ;
DOM_SID domain_sid ;
2002-03-02 13:16:28 +03:00
2003-04-28 14:20:55 +04:00
/* configuration items */
2003-05-14 07:32:20 +04:00
int schema_ver ;
2003-04-28 14:20:55 +04:00
2002-03-02 13:16:28 +03:00
BOOL permit_non_unix_accounts ;
2003-04-28 14:20:55 +04:00
uint32 low_allocated_user_rid ;
uint32 high_allocated_user_rid ;
uint32 low_allocated_group_rid ;
uint32 high_allocated_group_rid ;
2002-08-17 21:00:51 +04:00
2001-09-26 00:21:21 +04:00
} ;
2003-07-05 13:46:12 +04:00
/**********************************************************************
Free a LDAPMessage ( one is stored on the SAM_ACCOUNT )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void private_data_free_fn ( void * * result )
{
ldap_memfree ( * result ) ;
* result = NULL ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
get the attribute name given a user schame version
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static const char * get_userattr_key2string ( int schema_ver , int key )
{
switch ( schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
return get_attr_key2string ( attrib_map_v22 , key ) ;
case SCHEMAVER_SAMBASAMACCOUNT :
return get_attr_key2string ( attrib_map_v30 , key ) ;
default :
DEBUG ( 0 , ( " get_userattr_key2string: unknown schema version specified \n " ) ) ;
break ;
}
return NULL ;
}
/**********************************************************************
return the list of attribute names given a user schema version
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * * get_userattr_list ( int schema_ver )
{
switch ( schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
return get_attr_list ( attrib_map_v22 ) ;
case SCHEMAVER_SAMBASAMACCOUNT :
return get_attr_list ( attrib_map_v30 ) ;
default :
DEBUG ( 0 , ( " get_userattr_list: unknown schema version specified! \n " ) ) ;
break ;
}
return NULL ;
}
/*******************************************************************
generate the LDAP search filter for the objectclass based on the
version of the schema we are using
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static const char * get_objclass_filter ( int schema_ver )
{
static fstring objclass_filter ;
switch ( schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
snprintf ( objclass_filter , sizeof ( objclass_filter ) - 1 , " (objectclass=%s) " , LDAP_OBJ_SAMBAACCOUNT ) ;
break ;
case SCHEMAVER_SAMBASAMACCOUNT :
snprintf ( objclass_filter , sizeof ( objclass_filter ) - 1 , " (objectclass=%s) " , LDAP_OBJ_SAMBASAMACCOUNT ) ;
break ;
default :
2003-06-21 04:45:03 +04:00
DEBUG ( 0 , ( " pdb_ldapsam: get_objclass_filter(): Invalid schema version specified! \n " ) ) ;
2003-05-14 07:32:20 +04:00
break ;
}
return objclass_filter ;
}
2001-09-26 00:21:21 +04:00
/*******************************************************************
run the search by name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-06-21 04:45:03 +04:00
static int ldapsam_search_suffix_by_name ( struct ldapsam_privates * ldap_state ,
const char * user ,
LDAPMessage * * result , char * * attr )
2001-09-26 00:21:21 +04:00
{
pstring filter ;
2003-02-01 10:59:29 +03:00
char * escape_user = escape_ldap_string_alloc ( user ) ;
if ( ! escape_user ) {
return LDAP_NO_MEMORY ;
}
2001-09-26 00:21:21 +04:00
/*
2001-12-31 03:06:51 +03:00
* in the filter expression , replace % u with the real name
* so in ldap filter , % u MUST exist : - )
2001-09-26 00:21:21 +04:00
*/
2003-05-14 07:32:20 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&%s%s) " , lp_ldap_filter ( ) ,
get_objclass_filter ( ldap_state - > schema_ver ) ) ;
2001-09-26 00:21:21 +04:00
2001-12-31 03:06:51 +03:00
/*
* have to use this here because $ is filtered out
2001-09-26 00:21:21 +04:00
* in pstring_sub
*/
2003-02-01 10:59:29 +03:00
all_string_sub ( filter , " %u " , escape_user , sizeof ( pstring ) ) ;
SAFE_FREE ( escape_user ) ;
2001-09-26 00:21:21 +04:00
2003-06-21 04:45:03 +04:00
return smbldap_search_suffix ( ldap_state - > smbldap_state , filter , attr , result ) ;
2001-09-26 00:21:21 +04:00
}
/*******************************************************************
run the search by rid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-04-28 14:20:55 +04:00
static int ldapsam_search_suffix_by_rid ( struct ldapsam_privates * ldap_state ,
2003-06-21 04:45:03 +04:00
uint32 rid , LDAPMessage * * result ,
char * * attr )
2001-09-26 00:21:21 +04:00
{
pstring filter ;
int rc ;
2003-05-14 07:32:20 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(rid=%i)%s) " , rid ,
get_objclass_filter ( ldap_state - > schema_ver ) ) ;
2001-12-31 03:06:51 +03:00
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state , filter , attr , result ) ;
2003-04-28 14:20:55 +04:00
return rc ;
}
/*******************************************************************
run the search by SID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int ldapsam_search_suffix_by_sid ( struct ldapsam_privates * ldap_state ,
2003-06-21 04:45:03 +04:00
const DOM_SID * sid , LDAPMessage * * result ,
char * * attr )
2003-04-28 14:20:55 +04:00
{
pstring filter ;
int rc ;
fstring sid_string ;
2003-05-14 07:32:20 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(%s=%s)%s) " ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) ,
sid_to_string ( sid_string , sid ) ,
get_objclass_filter ( ldap_state - > schema_ver ) ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state , filter , attr , result ) ;
2001-09-26 00:21:21 +04:00
return rc ;
}
2003-03-19 21:21:44 +03:00
/*******************************************************************
Delete complete object or objectclass and attrs from
2003-03-23 12:18:33 +03:00
object found in search_result depending on lp_ldap_delete_dn
2003-03-19 21:21:44 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_delete_entry ( struct ldapsam_privates * ldap_state ,
LDAPMessage * result ,
const char * objectclass ,
2003-05-14 07:32:20 +04:00
char * * attrs )
2003-03-19 21:21:44 +03:00
{
int rc ;
LDAPMessage * entry ;
LDAPMod * * mods = NULL ;
char * name , * dn ;
BerElement * ptr = NULL ;
2003-06-21 04:45:03 +04:00
rc = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-03-19 21:21:44 +03:00
if ( rc ! = 1 ) {
DEBUG ( 0 , ( " Entry must exist exactly once! \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
dn = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
2003-03-19 21:21:44 +03:00
2003-03-23 12:18:33 +03:00
if ( lp_ldap_delete_dn ( ) ) {
2003-03-19 21:21:44 +03:00
NTSTATUS ret = NT_STATUS_OK ;
2003-06-21 04:45:03 +04:00
rc = smbldap_delete ( ldap_state - > smbldap_state , dn ) ;
2003-03-19 21:21:44 +03:00
if ( rc ! = LDAP_SUCCESS ) {
DEBUG ( 0 , ( " Could not delete object %s \n " , dn ) ) ;
ret = NT_STATUS_UNSUCCESSFUL ;
}
ldap_memfree ( dn ) ;
return ret ;
}
/* Ok, delete only the SAM attributes */
2003-05-14 07:32:20 +04:00
2003-06-21 04:45:03 +04:00
for ( name = ldap_first_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry , & ptr ) ;
2003-03-19 21:21:44 +03:00
name ! = NULL ;
2003-06-21 04:45:03 +04:00
name = ldap_next_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry , ptr ) )
2003-05-14 07:32:20 +04:00
{
char * * attrib ;
2003-03-19 21:21:44 +03:00
/* We are only allowed to delete the attributes that
really exist . */
2003-05-14 07:32:20 +04:00
for ( attrib = attrs ; * attrib ! = NULL ; attrib + + )
{
2003-03-19 21:21:44 +03:00
if ( StrCaseCmp ( * attrib , name ) = = 0 ) {
DEBUG ( 10 , ( " deleting attribute %s \n " , name ) ) ;
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_DELETE , name , NULL ) ;
2003-03-19 21:21:44 +03:00
}
}
ldap_memfree ( name ) ;
}
2003-05-14 07:32:20 +04:00
2003-03-19 21:21:44 +03:00
if ( ptr ! = NULL ) {
ber_free ( ptr , 0 ) ;
}
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_DELETE , " objectClass " , objectclass ) ;
2003-03-19 21:21:44 +03:00
2003-06-21 04:45:03 +04:00
rc = smbldap_modify ( ldap_state - > smbldap_state , dn , mods ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-04-28 14:20:55 +04:00
& ld_error ) ;
DEBUG ( 0 , ( " could not delete attributes for %s, error: %s (%s) \n " ,
dn , ldap_err2string ( rc ) , ld_error ? ld_error : " unknown " ) ) ;
SAFE_FREE ( ld_error ) ;
ldap_memfree ( dn ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
ldap_memfree ( dn ) ;
return NT_STATUS_OK ;
}
/**********************************************************************
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS add_new_domain_info ( struct ldapsam_privates * ldap_state )
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
fstring sid_string ;
fstring algorithmic_rid_base_string ;
2003-06-06 17:48:39 +04:00
pstring filter , dn ;
2003-04-28 14:20:55 +04:00
LDAPMod * * mods = NULL ;
int rc ;
int ldap_op ;
LDAPMessage * result = NULL ;
int num_result ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( filter , sizeof ( filter ) - 1 , " (&(%s=%s)(objectclass=%s)) " ,
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
ldap_state - > domain_name , LDAP_OBJ_DOMINFO ) ;
2003-05-14 07:32:20 +04:00
attr_list = get_attr_list ( dominfo_attr_list ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state , filter ,
attr_list , & result ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
2003-04-28 14:20:55 +04:00
if ( rc ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
num_result = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-04-28 14:20:55 +04:00
if ( num_result > 1 ) {
DEBUG ( 0 , ( " More than domain with that name exists: bailing out! \n " ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-05-14 07:32:20 +04:00
/* Check if we need to add an entry */
DEBUG ( 3 , ( " Adding new domain \n " ) ) ;
ldap_op = LDAP_MOD_ADD ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
2003-06-06 17:48:39 +04:00
snprintf ( dn , sizeof ( dn ) , " %s=%s,%s " , get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
2003-05-14 07:32:20 +04:00
ldap_state - > domain_name , lp_ldap_suffix ( ) ) ;
2003-04-28 14:20:55 +04:00
/* Free original search */
ldap_msgfree ( result ) ;
/* make the changes - the entry *must* not already have samba attributes */
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD , get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
2003-05-14 07:32:20 +04:00
ldap_state - > domain_name ) ;
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
/* If we don't have an entry, then ask secrets.tdb for what it thinks.
It may choose to make it up */
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
sid_to_string ( sid_string , get_global_sam_sid ( ) ) ;
smbldap_set_mod ( & mods , LDAP_MOD_ADD , get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOM_SID ) , sid_string ) ;
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
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 , LDAP_ATTR_ALGORITHMIC_RID_BASE ) ,
algorithmic_rid_base_string ) ;
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD , " objectclass " , LDAP_OBJ_DOMINFO ) ;
2003-04-28 14:20:55 +04:00
switch ( ldap_op )
{
case LDAP_MOD_ADD :
2003-06-21 04:45:03 +04:00
rc = smbldap_add ( ldap_state - > smbldap_state , dn , mods ) ;
2003-04-28 14:20:55 +04:00
break ;
case LDAP_MOD_REPLACE :
2003-06-21 04:45:03 +04:00
rc = smbldap_modify ( ldap_state - > smbldap_state , dn , mods ) ;
2003-04-28 14:20:55 +04:00
break ;
default :
DEBUG ( 0 , ( " Wrong LDAP operation type: %d! \n " , ldap_op ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-04-28 14:20:55 +04:00
& ld_error ) ;
DEBUG ( 1 ,
( " failed to %s domain dn= %s with: %s \n \t %s \n " ,
ldap_op = = LDAP_MOD_ADD ? " add " : " modify " ,
dn , ldap_err2string ( rc ) ,
ld_error ? ld_error : " unknown " ) ) ;
SAFE_FREE ( ld_error ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
DEBUG ( 2 , ( " added: domain = %s in the LDAP database \n " , ldap_state - > domain_name ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
return NT_STATUS_OK ;
}
/**********************************************************************
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
Search for the domain info entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_search_domain_info ( struct ldapsam_privates * ldap_state ,
LDAPMessage * * result , BOOL try_add )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
pstring filter ;
int rc ;
char * * attr_list ;
int count ;
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(%s=%s)) " ,
LDAP_OBJ_DOMINFO ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOMAIN ) ,
ldap_state - > domain_name ) ;
DEBUG ( 2 , ( " Searching for:[%s] \n " , filter ) ) ;
attr_list = get_attr_list ( dominfo_attr_list ) ;
rc = smbldap_search_suffix ( ldap_state - > smbldap_state , filter ,
attr_list , result ) ;
free_attr_list ( attr_list ) ;
if ( rc ! = LDAP_SUCCESS ) {
DEBUG ( 2 , ( " Problem during LDAPsearch: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUG ( 2 , ( " Query was: %s, %s \n " , lp_ldap_suffix ( ) , filter ) ) ;
} else if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , * result ) < 1 ) {
DEBUG ( 3 , ( " Got no domain info entries for domain %s \n " ,
ldap_state - > domain_name ) ) ;
ldap_msgfree ( * result ) ;
* result = NULL ;
if ( try_add & & NT_STATUS_IS_OK ( ret = add_new_domain_info ( ldap_state ) ) ) {
return ldapsam_search_domain_info ( ldap_state , result , False ) ;
} else {
DEBUG ( 0 , ( " Adding domain info failed with %s \n " , nt_errstr ( ret ) ) ) ;
return ret ;
}
} else if ( ( count = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , * result ) ) > 1 ) {
DEBUG ( 0 , ( " Got too many (%d) domain info entries for domain %s \n " ,
count , ldap_state - > domain_name ) ) ;
ldap_msgfree ( * result ) ;
* result = NULL ;
return ret ;
} else {
return NT_STATUS_OK ;
}
return ret ;
}
/**********************************************************************
Even if the sambaDomain attribute in LDAP tells us that this RID is
2003-04-28 14:20:55 +04:00
safe to use , always check before use .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL sid_in_use ( struct ldapsam_privates * ldap_state ,
const DOM_SID * sid , int * error )
{
2003-05-14 07:32:20 +04:00
fstring filter ;
2003-04-28 14:20:55 +04:00
fstring sid_string ;
LDAPMessage * result = NULL ;
int count ;
int rc ;
2003-05-14 07:32:20 +04:00
char * sid_attr [ ] = { LDAP_ATTRIBUTE_SID , NULL } ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( filter , sizeof ( filter ) - 1 , " (%s=%s) " , LDAP_ATTRIBUTE_SID , sid_to_string ( sid_string , sid ) ) ;
2003-04-28 14:20:55 +04:00
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state ,
filter , sid_attr , & result ) ;
2003-04-28 14:20:55 +04:00
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING , & ld_error ) ;
2003-04-28 14:20:55 +04:00
DEBUG ( 2 , ( " Failed to check if sid %s is alredy in use: %s \n " ,
sid_string , ld_error ) ) ;
SAFE_FREE ( ld_error ) ;
* error = rc ;
return True ;
}
2003-06-21 04:45:03 +04:00
if ( ( count = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ) > 0 ) {
2003-04-28 14:20:55 +04:00
DEBUG ( 3 , ( " Sid %s already in use - trying next RID \n " ,
sid_string ) ) ;
ldap_msgfree ( result ) ;
return True ;
}
ldap_msgfree ( result ) ;
/* good, sid is not in use */
return False ;
}
/**********************************************************************
Set the new nextRid attribute , and return one we can use .
This also checks that this RID is actually free - in case the admin
manually stole it : - ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_next_rid ( struct ldapsam_privates * ldap_state , uint32 * rid , int rid_type )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
int rc ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
LDAPMessage * domain_result = NULL ;
2003-04-28 14:20:55 +04:00
LDAPMessage * entry = NULL ;
char * dn ;
LDAPMod * * mods = NULL ;
fstring old_rid_string ;
fstring next_rid_string ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
fstring algorithmic_rid_base_string ;
2003-04-28 14:20:55 +04:00
uint32 next_rid ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
uint32 alg_rid_base ;
2003-04-28 14:20:55 +04:00
int attempts = 0 ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
char * ld_error = NULL ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
if ( ldap_state - > schema_ver ! = SCHEMAVER_SAMBASAMACCOUNT ) {
DEBUG ( 0 , ( " Allocated RIDs require the %s objectclass used by 'ldapsam' \n " ,
LDAP_OBJ_SAMBASAMACCOUNT ) ) ;
2003-04-28 14:20:55 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-05-14 07:32:20 +04:00
while ( attempts < 10 )
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! NT_STATUS_IS_OK ( ret = ldapsam_search_domain_info ( ldap_state , & domain_result , True ) ) ) {
2003-04-28 14:20:55 +04:00
return ret ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , domain_result ) ;
2003-04-28 14:20:55 +04:00
if ( ! entry ) {
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
DEBUG ( 0 , ( " Could not get domain info entry \n " ) ) ;
ldap_msgfree ( domain_result ) ;
2003-04-28 14:20:55 +04:00
return ret ;
}
2003-06-21 04:45:03 +04:00
if ( ( dn = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ) = = NULL ) {
2003-04-28 14:20:55 +04:00
DEBUG ( 0 , ( " Could not get domain info DN \n " ) ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ldap_msgfree ( domain_result ) ;
2003-04-28 14:20:55 +04:00
return ret ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
/* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
algorithmic_rid_base . The other two are to avoid stomping on the
2003-04-28 14:20:55 +04:00
different sets of algorithmic RIDs */
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_ALGORITHMIC_RID_BASE ) ,
algorithmic_rid_base_string ) )
{
alg_rid_base = ( uint32 ) atol ( algorithmic_rid_base_string ) ;
} else {
alg_rid_base = algorithmic_rid_base ( ) ;
/* Try to make the modification atomically by enforcing the
old value in the delete mod . */
slprintf ( algorithmic_rid_base_string , sizeof ( algorithmic_rid_base_string ) - 1 , " %d " , alg_rid_base ) ;
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , entry , & mods ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_ALGORITHMIC_RID_BASE ) ,
algorithmic_rid_base_string ) ;
2003-04-28 14:20:55 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
next_rid = 0 ;
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( alg_rid_base > BASE_RID ) {
/* we have a non-default 'algorithmic rid base', so we have 'low' rids that we
can allocate to new users */
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_RID ) ,
old_rid_string ) )
{
* rid = ( uint32 ) atol ( old_rid_string ) ;
} else {
* rid = BASE_RID ;
}
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
next_rid = * rid + 1 ;
if ( next_rid > = alg_rid_base ) {
2003-04-28 14:20:55 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
slprintf ( next_rid_string , sizeof ( next_rid_string ) - 1 , " %d " , next_rid ) ;
2003-04-28 14:20:55 +04:00
/* Try to make the modification atomically by enforcing the
old value in the delete mod . */
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , entry , & mods ,
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_RID ) ,
next_rid_string ) ;
}
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! next_rid ) { /* not got one already */
switch ( rid_type ) {
case USER_RID_TYPE :
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_USERRID ) ,
old_rid_string ) )
{
* rid = ( uint32 ) atol ( old_rid_string ) ;
} else {
* rid = ldap_state - > low_allocated_user_rid ;
}
break ;
case GROUP_RID_TYPE :
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_GROUPRID ) ,
old_rid_string ) )
{
* rid = ( uint32 ) atol ( old_rid_string ) ;
} else {
* rid = ldap_state - > low_allocated_group_rid ;
}
break ;
2003-04-28 14:20:55 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
/* This is the core of the whole routine. If we had
scheme - style closures , there would be a * lot * less code
duplication . . . */
2003-04-28 14:20:55 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
next_rid = * rid + RID_MULTIPLIER ;
slprintf ( next_rid_string , sizeof ( next_rid_string ) - 1 , " %d " , next_rid ) ;
switch ( rid_type ) {
case USER_RID_TYPE :
if ( next_rid > ldap_state - > high_allocated_user_rid ) {
return NT_STATUS_UNSUCCESSFUL ;
}
/* Try to make the modification atomically by enforcing the
old value in the delete mod . */
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , entry , & mods ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_USERRID ) ,
next_rid_string ) ;
break ;
case GROUP_RID_TYPE :
if ( next_rid > ldap_state - > high_allocated_group_rid ) {
return NT_STATUS_UNSUCCESSFUL ;
}
/* Try to make the modification atomically by enforcing the
old value in the delete mod . */
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , entry , & mods ,
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_NEXT_GROUPRID ) ,
next_rid_string ) ;
break ;
}
2003-04-28 14:20:55 +04:00
}
2003-06-21 04:45:03 +04:00
if ( ( rc = ldap_modify_s ( ldap_state - > smbldap_state - > ldap_struct , dn , mods ) ) = = LDAP_SUCCESS ) {
2003-04-28 14:20:55 +04:00
DOM_SID dom_sid ;
DOM_SID sid ;
pstring domain_sid_string ;
int error = 0 ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , domain_result ,
2003-05-14 07:32:20 +04:00
get_attr_key2string ( dominfo_attr_list , LDAP_ATTR_DOM_SID ) ,
domain_sid_string ) )
{
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
ldap_memfree ( dn ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ldap_msgfree ( domain_result ) ;
2003-04-28 14:20:55 +04:00
return ret ;
}
if ( ! string_to_sid ( & dom_sid , domain_sid_string ) ) {
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
ldap_memfree ( dn ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ldap_msgfree ( domain_result ) ;
2003-04-28 14:20:55 +04:00
return ret ;
}
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
mods = NULL ;
ldap_memfree ( dn ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ldap_msgfree ( domain_result ) ;
2003-03-19 21:21:44 +03:00
2003-04-28 14:20:55 +04:00
sid_copy ( & sid , & dom_sid ) ;
sid_append_rid ( & sid , * rid ) ;
/* check RID is not in use */
if ( sid_in_use ( ldap_state , & sid , & error ) ) {
if ( error ) {
return ret ;
}
continue ;
}
return NT_STATUS_OK ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING , & ld_error ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
DEBUG ( 2 , ( " Failed to modify rid: %s \n " , ld_error ? ld_error : " (NULL " ) ) ;
2003-03-28 12:59:11 +03:00
SAFE_FREE ( ld_error ) ;
2003-04-28 14:20:55 +04:00
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-04-28 14:20:55 +04:00
mods = NULL ;
2003-03-19 21:21:44 +03:00
ldap_memfree ( dn ) ;
2003-04-28 14:20:55 +04:00
dn = NULL ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
ldap_msgfree ( domain_result ) ;
domain_result = NULL ;
2003-04-28 14:20:55 +04:00
{
/* Sleep for a random timeout */
unsigned sleeptime = ( sys_random ( ) * sys_getpid ( ) * attempts ) ;
attempts + = 1 ;
sleeptime % = 100 ;
msleep ( sleeptime ) ;
}
2003-03-19 21:21:44 +03:00
}
2003-04-28 14:20:55 +04:00
DEBUG ( 0 , ( " Failed to set new RID \n " ) ) ;
return ret ;
2003-03-19 21:21:44 +03:00
}
2003-04-28 14:20:55 +04:00
2001-09-26 00:21:21 +04:00
/* New Interface is being implemented here */
2002-11-02 15:13:44 +03:00
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query ( unix attributes only )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_unix_attributes ( struct ldapsam_privates * ldap_state ,
SAM_ACCOUNT * sampass ,
2003-05-12 22:12:31 +04:00
LDAPMessage * entry ,
gid_t * gid )
2002-11-02 15:13:44 +03:00
{
pstring homedir ;
pstring temp ;
char * * ldap_values ;
char * * values ;
2003-06-21 04:45:03 +04:00
if ( ( ldap_values = ldap_get_values ( ldap_state - > smbldap_state - > ldap_struct , entry , " objectClass " ) ) = = NULL ) {
2002-11-02 15:13:44 +03:00
DEBUG ( 1 , ( " get_unix_attributes: no objectClass! \n " ) ) ;
return False ;
}
for ( values = ldap_values ; * values ; values + + ) {
2003-05-14 07:32:20 +04:00
if ( strcasecmp ( * values , LDAP_OBJ_POSIXACCOUNT ) = = 0 ) {
2002-11-02 15:13:44 +03:00
break ;
}
}
if ( ! * values ) { /*end of array, no posixAccount */
2003-05-14 07:32:20 +04:00
DEBUG ( 10 , ( " user does not have %s attributes \n " , LDAP_OBJ_POSIXACCOUNT ) ) ;
2002-11-02 15:13:44 +03:00
ldap_value_free ( ldap_values ) ;
return False ;
}
ldap_value_free ( ldap_values ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_UNIX_HOME ) , homedir ) )
{
2002-11-02 15:13:44 +03:00
return False ;
2003-05-14 07:32:20 +04:00
}
2002-11-02 15:13:44 +03:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_GIDNUMBER ) , temp ) )
{
2002-11-02 15:13:44 +03:00
return False ;
2003-05-14 07:32:20 +04:00
}
2002-11-02 15:13:44 +03:00
2003-05-14 04:58:41 +04:00
* gid = ( gid_t ) atol ( temp ) ;
2002-11-02 15:13:44 +03:00
pdb_set_unix_homedir ( sampass , homedir , PDB_SET ) ;
2003-05-14 07:32:20 +04:00
DEBUG ( 10 , ( " user has %s attributes \n " , LDAP_OBJ_POSIXACCOUNT ) ) ;
2002-11-02 15:13:44 +03:00
return True ;
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query
( Based on init_sam_from_buffer in pdb_tdb . c )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static BOOL init_sam_from_ldap ( struct ldapsam_privates * ldap_state ,
SAM_ACCOUNT * sampass ,
2002-11-02 06:47:48 +03:00
LDAPMessage * entry )
2001-09-26 00:21:21 +04:00
{
time_t logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
2001-12-31 03:06:51 +03:00
pstring username ,
domain ,
nt_username ,
fullname ,
homedir ,
dir_drive ,
logon_script ,
profile_path ,
acct_desc ,
munged_dial ,
workstations ;
2003-04-25 09:59:49 +04:00
uint32 user_rid ;
2002-11-02 06:47:48 +03:00
uint8 smblmpwd [ LM_HASH_LEN ] ,
smbntpwd [ NT_HASH_LEN ] ;
2003-01-15 19:41:29 +03:00
uint16 acct_ctrl = 0 ,
2001-12-31 03:06:51 +03:00
logon_divs ;
2001-09-26 00:21:21 +04:00
uint32 hours_len ;
2001-12-31 03:06:51 +03:00
uint8 hours [ MAX_HOURS_LEN ] ;
2001-09-26 00:21:21 +04:00
pstring temp ;
2002-01-21 11:08:54 +03:00
uid_t uid = - 1 ;
2003-05-12 22:12:31 +04:00
gid_t gid = getegid ( ) ;
2001-12-31 03:06:51 +03:00
/*
* do a little initialization
*/
username [ 0 ] = ' \0 ' ;
domain [ 0 ] = ' \0 ' ;
nt_username [ 0 ] = ' \0 ' ;
fullname [ 0 ] = ' \0 ' ;
homedir [ 0 ] = ' \0 ' ;
dir_drive [ 0 ] = ' \0 ' ;
logon_script [ 0 ] = ' \0 ' ;
profile_path [ 0 ] = ' \0 ' ;
acct_desc [ 0 ] = ' \0 ' ;
munged_dial [ 0 ] = ' \0 ' ;
workstations [ 0 ] = ' \0 ' ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( sampass = = NULL | | ldap_state = = NULL | | entry = = NULL ) {
2001-12-30 22:21:25 +03:00
DEBUG ( 0 , ( " init_sam_from_ldap: NULL parameters found! \n " ) ) ;
return False ;
}
2003-06-21 04:45:03 +04:00
if ( ldap_state - > smbldap_state - > ldap_struct = = NULL ) {
DEBUG ( 0 , ( " init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL! \n " ) ) ;
2002-11-02 06:47:48 +03:00
return False ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry , " uid " , username ) ) {
2003-04-28 14:20:55 +04:00
DEBUG ( 1 , ( " No uid attribute found for this user! \n " ) ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
DEBUG ( 2 , ( " Entry found for user: %s \n " , username ) ) ;
2001-10-10 21:04:23 +04:00
pstrcpy ( nt_username , username ) ;
2001-09-26 00:21:21 +04:00
2003-04-28 14:20:55 +04:00
pstrcpy ( domain , ldap_state - > domain_name ) ;
2002-11-02 06:47:48 +03:00
pdb_set_username ( sampass , username , PDB_SET ) ;
pdb_set_domain ( sampass , domain , PDB_DEFAULT ) ;
pdb_set_nt_username ( sampass , nt_username , PDB_SET ) ;
2003-05-22 21:07:41 +04:00
2003-05-14 07:32:20 +04:00
/* deal with different attributes between the schema first */
if ( ldap_state - > schema_ver = = SCHEMAVER_SAMBASAMACCOUNT )
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) , temp ) )
{
2003-04-28 14:20:55 +04:00
pdb_set_user_sid_from_string ( sampass , temp , PDB_SET ) ;
}
2003-05-14 07:32:20 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PRIMARY_GROUP_SID ) , temp ) )
{
pdb_set_group_sid_from_string ( sampass , temp , PDB_SET ) ;
}
else
{
pdb_set_group_sid_from_rid ( sampass , DOMAIN_GROUP_RID_USERS , PDB_DEFAULT ) ;
}
}
else
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_RID ) , temp ) )
{
2003-04-28 14:20:55 +04:00
user_rid = ( uint32 ) atol ( temp ) ;
pdb_set_user_sid_from_rid ( sampass , user_rid , PDB_SET ) ;
}
2003-05-14 07:32:20 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PRIMARY_GROUP_RID ) , temp ) )
{
pdb_set_group_sid_from_rid ( sampass , DOMAIN_GROUP_RID_USERS , PDB_DEFAULT ) ;
} else {
uint32 group_rid ;
2003-05-14 22:36:54 +04:00
2003-05-14 07:32:20 +04:00
group_rid = ( uint32 ) atol ( temp ) ;
2003-05-14 22:36:54 +04:00
/* for some reason, we often have 0 as a primary group RID.
Make sure that we treat this just as a ' default ' value */
if ( group_rid > 0 )
pdb_set_group_sid_from_rid ( sampass , group_rid , PDB_SET ) ;
else
pdb_set_group_sid_from_rid ( sampass , DOMAIN_GROUP_RID_USERS , PDB_DEFAULT ) ;
2003-05-14 07:32:20 +04:00
}
2003-04-28 14:20:55 +04:00
}
2001-09-26 00:21:21 +04:00
2003-04-28 14:20:55 +04:00
if ( pdb_get_init_flags ( sampass , PDB_USERSID ) = = PDB_DEFAULT ) {
2003-05-14 07:32:20 +04:00
DEBUG ( 1 , ( " no %s or %s attribute found for this user %s \n " ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_RID ) ,
username ) ) ;
2003-04-28 14:20:55 +04:00
return False ;
}
2002-07-15 14:35:28 +04:00
2003-05-12 22:12:31 +04:00
2002-11-02 15:13:44 +03:00
/*
* If so configured , try and get the values from LDAP
*/
2003-05-14 22:36:54 +04:00
if ( lp_ldap_trust_ids ( ) & & ( get_unix_attributes ( ldap_state , sampass , entry , & gid ) ) )
2003-05-14 07:32:20 +04:00
{
if ( pdb_get_init_flags ( sampass , PDB_GROUPSID ) = = PDB_DEFAULT )
{
2003-05-12 22:12:31 +04:00
GROUP_MAP map ;
/* call the mapping code here */
2003-06-18 19:24:10 +04:00
if ( pdb_getgrgid ( & map , gid ) ) {
2003-05-12 22:12:31 +04:00
pdb_set_group_sid ( sampass , & map . sid , PDB_SET ) ;
}
else {
pdb_set_group_sid_from_rid ( sampass , pdb_gid_to_group_rid ( gid ) , PDB_SET ) ;
2002-11-02 15:13:44 +03:00
}
2002-03-02 13:16:28 +03:00
}
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_LAST_SET ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pass_last_set_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_last_set_time ( sampass , pass_last_set_time , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGON_TIME ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
logon_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_logon_time ( sampass , logon_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGOFF_TIME ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
logoff_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_logoff_time ( sampass , logoff_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_KICKOFF_TIME ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
kickoff_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_kickoff_time ( sampass , kickoff_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_CAN_CHANGE ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
pass_can_change_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_can_change_time ( sampass , pass_can_change_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_MUST_CHANGE ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
pass_must_change_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_must_change_time ( sampass , pass_must_change_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
/* recommend that 'gecos' and 'displayName' should refer to the same
2002-03-02 13:16:28 +03:00
* attribute OID . userFullName depreciated , only used by Samba
* primary rules of LDAP : don ' t make a new attribute when one is already defined
2001-12-31 03:06:51 +03:00
* that fits your needs ; using cn then displayName rather than ' userFullName '
2001-09-26 00:21:21 +04:00
*/
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_DISPLAY_NAME ) , fullname ) )
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_CN ) , fullname ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-11-02 06:47:48 +03:00
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
} else {
2002-11-02 06:47:48 +03:00
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_HOME_DRIVE ) , dir_drive ) )
{
2002-07-15 14:35:28 +04:00
pdb_set_dir_drive ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_drive ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_dir_drive ( sampass , dir_drive , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_HOME_PATH ) , homedir ) )
{
2002-07-15 14:35:28 +04:00
pdb_set_homedir ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_home ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_homedir ( sampass , homedir , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGON_SCRIPT ) , logon_script ) )
{
2002-07-15 14:35:28 +04:00
pdb_set_logon_script ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_script ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_logon_script ( sampass , logon_script , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PROFILE_PATH ) , profile_path ) )
{
2002-07-15 14:35:28 +04:00
pdb_set_profile_path ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_path ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_profile_path ( sampass , profile_path , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_DESC ) , acct_desc ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-11-02 06:47:48 +03:00
pdb_set_acct_desc ( sampass , acct_desc , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_WKS ) , workstations ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */ ;
} else {
2002-11-02 06:47:48 +03:00
pdb_set_workstations ( sampass , workstations , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
/* FIXME: hours stuff should be cleaner */
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
logon_divs = 168 ;
hours_len = 21 ;
memset ( hours , 0xff , hours_len ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LMPW ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pdb_gethexpwd ( temp , smblmpwd ) ;
2002-08-17 21:00:51 +04:00
memset ( ( char * ) temp , ' \0 ' , strlen ( temp ) + 1 ) ;
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_lanman_passwd ( sampass , smblmpwd , PDB_SET ) )
2002-04-08 05:52:44 +04:00
return False ;
2002-08-17 21:00:51 +04:00
ZERO_STRUCT ( smblmpwd ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_NTPW ) , temp ) )
{
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pdb_gethexpwd ( temp , smbntpwd ) ;
2002-08-17 21:00:51 +04:00
memset ( ( char * ) temp , ' \0 ' , strlen ( temp ) + 1 ) ;
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_nt_passwd ( sampass , smbntpwd , PDB_SET ) )
2002-04-08 05:52:44 +04:00
return False ;
2002-08-17 21:00:51 +04:00
ZERO_STRUCT ( smbntpwd ) ;
2002-04-08 05:52:44 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_ACB_INFO ) , temp ) )
{
2001-09-26 00:21:21 +04:00
acct_ctrl | = ACB_NORMAL ;
2002-04-08 05:52:44 +04:00
} else {
acct_ctrl = pdb_decode_acct_ctrl ( temp ) ;
if ( acct_ctrl = = 0 )
acct_ctrl | = ACB_NORMAL ;
2002-11-02 06:47:48 +03:00
pdb_set_acct_ctrl ( sampass , acct_ctrl , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_hours_len ( sampass , hours_len , PDB_SET ) ;
pdb_set_logon_divs ( sampass , logon_divs , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_munged_dial ( sampass , munged_dial , PDB_SET ) ;
2001-12-31 03:06:51 +03:00
2002-11-02 06:47:48 +03:00
/* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
/* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
/* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_hours ( sampass , hours , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
return True ;
}
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query
( Based on init_buffer_from_sam in pdb_tdb . c )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static BOOL init_ldap_from_sam ( struct ldapsam_privates * ldap_state ,
2003-03-22 22:16:36 +03:00
LDAPMessage * existing ,
2003-04-23 04:59:19 +04:00
LDAPMod * * * mods , SAM_ACCOUNT * sampass ,
2003-03-27 17:31:46 +03:00
BOOL ( * need_update ) ( const SAM_ACCOUNT * ,
enum pdb_elements ) )
2001-09-26 00:21:21 +04:00
{
pstring temp ;
2002-03-02 13:16:28 +03:00
uint32 rid ;
2001-09-26 00:21:21 +04:00
2001-12-30 22:21:25 +03:00
if ( mods = = NULL | | sampass = = NULL ) {
DEBUG ( 0 , ( " init_ldap_from_sam: NULL parameters found! \n " ) ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
* mods = NULL ;
/*
* took out adding " objectclass: sambaAccount "
* do this on a per - mod basis
*/
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_USERNAME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-03-30 20:40:41 +04:00
" uid " , pdb_get_username ( sampass ) ) ;
2003-03-22 22:16:36 +03:00
DEBUG ( 2 , ( " Setting entry for user: %s \n " , pdb_get_username ( sampass ) ) ) ;
2003-04-28 14:20:55 +04:00
if ( pdb_get_init_flags ( sampass , PDB_USERSID ) = = PDB_DEFAULT ) {
2003-04-28 15:46:22 +04:00
if ( ldap_state - > permit_non_unix_accounts ) {
2003-04-28 14:20:55 +04:00
if ( ! NT_STATUS_IS_OK ( ldapsam_next_rid ( ldap_state , & rid , USER_RID_TYPE ) ) ) {
2003-03-22 23:49:26 +03:00
DEBUG ( 0 , ( " NO user RID specified on account %s, and "
2003-04-09 18:51:17 +04:00
" finding next available NUA RID failed, "
2003-03-22 23:49:26 +03:00
" cannot store! \n " ,
pdb_get_username ( sampass ) ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( * mods , True ) ;
2003-03-22 23:49:26 +03:00
return False ;
}
} else {
DEBUG ( 0 , ( " NO user RID specified on account %s, "
" cannot store! \n " , pdb_get_username ( sampass ) ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( * mods , True ) ;
2002-03-02 13:16:28 +03:00
return False ;
}
2003-03-30 20:40:41 +04:00
2003-04-23 04:59:19 +04:00
/* now that we have figured out the RID, always store it, as
2003-05-14 07:32:20 +04:00
the schema requires it ( either as a SID or a RID ) */
2003-04-23 04:59:19 +04:00
if ( ! pdb_set_user_sid_from_rid ( sampass , rid , PDB_CHANGED ) ) {
DEBUG ( 0 , ( " Could not store RID back onto SAM_ACCOUNT for user %s! \n " ,
pdb_get_username ( sampass ) ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( * mods , True ) ;
2003-04-23 04:59:19 +04:00
return False ;
}
2003-04-23 03:14:49 +04:00
}
2002-03-02 13:16:28 +03:00
2003-04-23 04:59:19 +04:00
/* only update the RID if we actually need to */
2003-05-14 07:32:20 +04:00
if ( need_update ( sampass , PDB_USERSID ) )
{
2003-04-28 14:20:55 +04:00
fstring sid_string ;
fstring dom_sid_string ;
2003-05-14 22:36:54 +04:00
const DOM_SID * user_sid = pdb_get_user_sid ( sampass ) ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
switch ( ldap_state - > schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! sid_peek_check_rid ( & ldap_state - > domain_sid , user_sid , & rid ) ) {
2003-05-14 22:36:54 +04:00
DEBUG ( 1 , ( " User's SID (%s) is not for this domain (%s), cannot add to LDAP! \n " ,
sid_to_string ( sid_string , user_sid ) ,
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
sid_to_string ( dom_sid_string , & ldap_state - > domain_sid ) ) ) ;
2003-05-14 07:32:20 +04:00
return False ;
}
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_RID ) ,
temp ) ;
break ;
case SCHEMAVER_SAMBASAMACCOUNT :
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) ,
sid_to_string ( sid_string , user_sid ) ) ;
break ;
default :
DEBUG ( 0 , ( " init_ldap_from_sam: unknown schema version specified \n " ) ) ;
break ;
}
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2003-04-28 14:20:55 +04:00
/* we don't need to store the primary group RID - so leaving it
' free ' to hang off the unix primary group makes life easier */
2003-03-30 20:40:41 +04:00
2003-05-14 07:32:20 +04:00
if ( need_update ( sampass , PDB_GROUPSID ) )
{
2003-05-14 22:36:54 +04:00
fstring sid_string ;
fstring dom_sid_string ;
const DOM_SID * group_sid = pdb_get_group_sid ( sampass ) ;
2003-05-14 07:32:20 +04:00
switch ( ldap_state - > schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! sid_peek_check_rid ( & ldap_state - > domain_sid , group_sid , & rid ) ) {
2003-05-14 22:36:54 +04:00
DEBUG ( 1 , ( " User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP! \n " ,
sid_to_string ( sid_string , group_sid ) ,
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
sid_to_string ( dom_sid_string , & ldap_state - > domain_sid ) ) ) ;
2003-05-14 22:36:54 +04:00
return False ;
}
2003-05-14 07:32:20 +04:00
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 22:36:54 +04:00
get_userattr_key2string ( ldap_state - > schema_ver ,
LDAP_ATTR_PRIMARY_GROUP_RID ) , temp ) ;
2003-05-14 07:32:20 +04:00
break ;
case SCHEMAVER_SAMBASAMACCOUNT :
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 22:36:54 +04:00
get_userattr_key2string ( ldap_state - > schema_ver ,
LDAP_ATTR_PRIMARY_GROUP_SID ) , sid_to_string ( sid_string , group_sid ) ) ;
2003-05-14 07:32:20 +04:00
break ;
default :
DEBUG ( 0 , ( " init_ldap_from_sam: unknown schema version specified \n " ) ) ;
break ;
}
2003-04-28 14:20:55 +04:00
}
2003-05-14 07:32:20 +04:00
2001-09-26 00:21:21 +04:00
/* displayName, cn, and gecos should all be the same
2002-10-01 17:10:57 +04:00
* most easily accomplished by giving them the same OID
* gecos isn ' t set here b / c it should be handled by the
* add - user script
2003-03-22 22:16:36 +03:00
* We change displayName only and fall back to cn if
* it does not exist .
2001-12-31 03:06:51 +03:00
*/
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_FULLNAME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_DISPLAY_NAME ) ,
pdb_get_fullname ( sampass ) ) ;
2003-03-22 22:16:36 +03:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_ACCTDESC ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_DESC ) ,
pdb_get_acct_desc ( sampass ) ) ;
2003-03-22 22:16:36 +03:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_WORKSTATIONS ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_WKS ) ,
pdb_get_workstations ( sampass ) ) ;
2003-03-22 22:16:36 +03:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_SMBHOME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_HOME_PATH ) ,
pdb_get_homedir ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_DRIVE ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_HOME_DRIVE ) ,
pdb_get_dir_drive ( sampass ) ) ;
2001-09-26 00:21:21 +04:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_LOGONSCRIPT ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGON_SCRIPT ) ,
pdb_get_logon_script ( sampass ) ) ;
2001-12-31 03:06:51 +03:00
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_PROFILE ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PROFILE_PATH ) ,
pdb_get_profile_path ( sampass ) ) ;
2001-09-26 00:21:21 +04:00
2003-03-22 22:16:36 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_logon_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_LOGONTIME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGON_TIME ) , temp ) ;
2002-03-02 13:16:28 +03:00
2003-03-22 22:16:36 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_logoff_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_LOGOFFTIME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LOGOFF_TIME ) , temp ) ;
2003-03-30 20:40:41 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_kickoff_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_KICKOFFTIME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_KICKOFF_TIME ) , temp ) ;
2003-03-30 20:40:41 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_can_change_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_CANCHANGETIME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_CAN_CHANGE ) , temp ) ;
2003-03-30 20:40:41 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_must_change_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_MUSTCHANGETIME ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_MUST_CHANGE ) , temp ) ;
2001-09-26 00:21:21 +04:00
2003-05-14 07:32:20 +04:00
if ( ( pdb_get_acct_ctrl ( sampass ) & ( ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST ) )
| | ( lp_ldap_passwd_sync ( ) ! = LDAP_PASSWD_SYNC_ONLY ) )
{
2002-09-25 19:19:00 +04:00
2003-05-14 07:32:20 +04:00
pdb_sethexpwd ( temp , pdb_get_lanman_passwd ( sampass ) ,
2003-03-22 22:16:36 +03:00
pdb_get_acct_ctrl ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_LMPASSWD ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_LMPW ) ,
temp ) ;
2003-03-22 22:16:36 +03:00
pdb_sethexpwd ( temp , pdb_get_nt_passwd ( sampass ) ,
pdb_get_acct_ctrl ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_NTPASSWD ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_NTPW ) ,
temp ) ;
2003-03-30 20:40:41 +04:00
2003-05-14 07:32:20 +04:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_last_set_time ( sampass ) ) ;
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_PASSLASTSET ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_PWD_LAST_SET ) ,
temp ) ;
2002-09-25 19:19:00 +04:00
}
/* FIXME: Hours stuff goes in LDAP */
2003-03-30 20:40:41 +04:00
if ( need_update ( sampass , PDB_ACCTCTRL ) )
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_state - > smbldap_state - > ldap_struct , existing , mods ,
2003-05-14 07:32:20 +04:00
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_ACB_INFO ) ,
pdb_encode_acct_ctrl ( pdb_get_acct_ctrl ( sampass ) , NEW_PW_FORMAT_SPACE_PADDED_LEN ) ) ;
2003-03-30 20:40:41 +04:00
2001-09-26 00:21:21 +04:00
return True ;
}
2002-03-02 13:16:28 +03:00
2001-09-26 00:21:21 +04:00
/**********************************************************************
Connect to LDAP server for password enumeration
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_setsampwent ( struct pdb_methods * my_methods , BOOL update )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
pstring filter ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2001-09-26 00:21:21 +04:00
2003-05-14 07:32:20 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&%s%s) " , lp_ldap_filter ( ) ,
get_objclass_filter ( ldap_state - > schema_ver ) ) ;
2001-09-26 00:21:21 +04:00
all_string_sub ( filter , " %u " , " * " , sizeof ( pstring ) ) ;
2003-05-14 07:32:20 +04:00
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state , filter ,
attr_list , & ldap_state - > result ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
2001-09-26 00:21:21 +04:00
2002-09-25 19:19:00 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " LDAP search failed: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUG ( 3 , ( " Query was: %s, %s \n " , lp_ldap_suffix ( ) , filter ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( ldap_state - > result ) ;
ldap_state - > result = NULL ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-03-02 13:16:28 +03:00
DEBUG ( 2 , ( " ldapsam_setsampwent: %d entries in the base! \n " ,
2003-06-21 04:45:03 +04:00
ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct ,
2002-03-02 13:16:28 +03:00
ldap_state - > result ) ) ) ;
2001-09-26 00:21:21 +04:00
2003-06-21 04:45:03 +04:00
ldap_state - > entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct ,
2002-03-02 13:16:28 +03:00
ldap_state - > result ) ;
ldap_state - > index = 0 ;
2001-09-26 00:21:21 +04:00
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
End enumeration of the LDAP password list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
static void ldapsam_endsampwent ( struct pdb_methods * my_methods )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-11-02 06:47:48 +03:00
if ( ldap_state - > result ) {
2002-03-02 13:16:28 +03:00
ldap_msgfree ( ldap_state - > result ) ;
ldap_state - > result = NULL ;
2001-09-26 00:21:21 +04:00
}
}
/**********************************************************************
Get the next entry in the LDAP password database
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwent ( struct pdb_methods * my_methods , SAM_ACCOUNT * user )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-09-26 22:58:34 +04:00
BOOL bret = False ;
2001-09-26 00:21:21 +04:00
2002-09-26 22:58:34 +04:00
while ( ! bret ) {
2002-03-02 13:16:28 +03:00
if ( ! ldap_state - > entry )
2002-09-26 22:58:34 +04:00
return ret ;
2002-03-02 13:16:28 +03:00
ldap_state - > index + + ;
2002-11-02 06:47:48 +03:00
bret = init_sam_from_ldap ( ldap_state , user , ldap_state - > entry ) ;
2002-03-02 13:16:28 +03:00
2003-06-21 04:45:03 +04:00
ldap_state - > entry = ldap_next_entry ( ldap_state - > smbldap_state - > ldap_struct ,
2002-09-25 19:19:00 +04:00
ldap_state - > entry ) ;
2002-03-01 18:17:10 +03:00
}
2001-09-26 00:21:21 +04:00
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by username
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwnam ( struct pdb_methods * my_methods , SAM_ACCOUNT * user , const char * sname )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
LDAPMessage * result ;
LDAPMessage * entry ;
2003-02-01 10:59:29 +03:00
int count ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
int rc ;
2003-02-01 10:59:29 +03:00
2003-05-14 07:32:20 +04:00
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
rc = ldapsam_search_suffix_by_name ( ldap_state , sname , & result , attr_list ) ;
free_attr_list ( attr_list ) ;
if ( rc ! = LDAP_SUCCESS )
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
2003-02-01 10:59:29 +03:00
2003-06-21 04:45:03 +04:00
count = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-02-01 10:59:29 +03:00
if ( count < 1 ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 4 ,
2003-05-14 07:32:20 +04:00
( " Unable to locate user [%s] count=%d \n " , sname ,
2003-02-01 10:59:29 +03:00
count ) ) ;
return NT_STATUS_NO_SUCH_USER ;
} else if ( count > 1 ) {
DEBUG ( 1 ,
( " Duplicate entries for this user [%s] Failing. count=%d \n " , sname ,
count ) ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
2001-09-26 00:21:21 +04:00
}
2003-02-01 10:59:29 +03:00
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2002-09-25 19:19:00 +04:00
if ( entry ) {
2002-11-02 06:47:48 +03:00
if ( ! init_sam_from_ldap ( ldap_state , user , entry ) ) {
2002-08-17 21:00:51 +04:00
DEBUG ( 1 , ( " ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'! \n " , sname ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( result ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
2002-03-02 13:16:28 +03:00
}
2003-07-05 13:46:12 +04:00
pdb_set_backend_private_data ( user , result ,
private_data_free_fn ,
my_methods , PDB_CHANGED ) ;
2002-09-26 22:58:34 +04:00
ret = NT_STATUS_OK ;
2002-09-25 19:19:00 +04:00
} else {
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
}
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
static int ldapsam_get_ldap_user_by_sid ( struct ldapsam_privates * ldap_state ,
const DOM_SID * sid , LDAPMessage * * result )
2001-09-26 00:21:21 +04:00
{
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
int rc = - 1 ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2003-07-05 14:39:41 +04:00
uint32 rid ;
2003-05-14 07:32:20 +04:00
switch ( ldap_state - > schema_ver )
{
case SCHEMAVER_SAMBASAMACCOUNT :
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
rc = ldapsam_search_suffix_by_sid ( ldap_state , sid , result , attr_list ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
if ( rc ! = LDAP_SUCCESS )
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
return rc ;
2003-05-14 07:32:20 +04:00
break ;
case SCHEMAVER_SAMBAACCOUNT :
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! sid_peek_check_rid ( & ldap_state - > domain_sid , sid , & rid ) ) {
return rc ;
2003-05-14 07:32:20 +04:00
}
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
rc = ldapsam_search_suffix_by_rid ( ldap_state , rid , result , attr_list ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
if ( rc ! = LDAP_SUCCESS )
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
return rc ;
2003-07-05 14:39:41 +04:00
break ;
2001-09-26 00:21:21 +04:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
return rc ;
}
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by SID
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_getsampwsid ( struct pdb_methods * my_methods , SAM_ACCOUNT * user , const DOM_SID * sid )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
LDAPMessage * result ;
LDAPMessage * entry ;
int count ;
int rc ;
fstring sid_string ;
rc = ldapsam_get_ldap_user_by_sid ( ldap_state ,
sid , & result ) ;
if ( rc ! = LDAP_SUCCESS )
return NT_STATUS_NO_SUCH_USER ;
2003-06-21 04:45:03 +04:00
count = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
if ( count < 1 )
{
2002-08-17 21:00:51 +04:00
DEBUG ( 4 ,
2003-05-14 07:32:20 +04:00
( " Unable to locate SID [%s] count=%d \n " , sid_to_string ( sid_string , sid ) ,
2003-02-01 10:59:29 +03:00
count ) ) ;
2003-06-07 07:22:37 +04:00
ldap_msgfree ( result ) ;
2003-02-01 10:59:29 +03:00
return NT_STATUS_NO_SUCH_USER ;
2003-05-14 07:32:20 +04:00
}
else if ( count > 1 )
{
2003-02-01 10:59:29 +03:00
DEBUG ( 1 ,
2003-04-28 14:20:55 +04:00
( " More than one user with SID [%s]. Failing. count=%d \n " , sid_to_string ( sid_string , sid ) ,
2003-02-01 10:59:29 +03:00
count ) ) ;
2003-06-07 07:22:37 +04:00
ldap_msgfree ( result ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
2001-09-26 00:21:21 +04:00
}
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-05-14 07:32:20 +04:00
if ( entry )
{
2002-11-02 06:47:48 +03:00
if ( ! init_sam_from_ldap ( ldap_state , user , entry ) ) {
2002-08-17 21:00:51 +04:00
DEBUG ( 1 , ( " ldapsam_getsampwrid: init_sam_from_ldap failed! \n " ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( result ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
2002-03-02 13:16:28 +03:00
}
2003-07-05 13:46:12 +04:00
pdb_set_backend_private_data ( user , result ,
private_data_free_fn ,
my_methods , PDB_CHANGED ) ;
2002-09-26 22:58:34 +04:00
ret = NT_STATUS_OK ;
2003-07-05 13:46:12 +04:00
} else {
ldap_msgfree ( result ) ;
2001-09-26 00:21:21 +04:00
}
2003-07-05 14:39:41 +04:00
return NT_STATUS_NO_SUCH_USER ;
2002-07-15 14:35:28 +04:00
}
2002-11-02 06:47:48 +03:00
/********************************************************************
Do the actual modification - also change a plaittext passord if
it it set .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_modify_entry ( struct pdb_methods * my_methods ,
SAM_ACCOUNT * newpwd , char * dn ,
2003-04-23 03:14:49 +04:00
LDAPMod * * mods , int ldap_op ,
BOOL ( * need_update ) ( const SAM_ACCOUNT * ,
enum pdb_elements ) )
2002-09-25 19:19:00 +04:00
{
2002-11-02 06:47:48 +03:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-09-25 19:19:00 +04:00
int rc ;
2002-11-02 06:47:48 +03:00
if ( ! my_methods | | ! newpwd | | ! dn ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! mods ) {
DEBUG ( 5 , ( " mods is empty: nothing to modify \n " ) ) ;
/* may be password change below however */
} else {
switch ( ldap_op )
{
case LDAP_MOD_ADD :
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD ,
" objectclass " ,
LDAP_OBJ_ACCOUNT ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_add ( ldap_state - > smbldap_state ,
dn , mods ) ;
2002-09-25 19:19:00 +04:00
break ;
2002-11-02 06:47:48 +03:00
case LDAP_MOD_REPLACE :
2003-06-21 04:45:03 +04:00
rc = smbldap_modify ( ldap_state - > smbldap_state ,
dn , mods ) ;
2002-09-25 19:19:00 +04:00
break ;
2002-11-02 06:47:48 +03:00
default :
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
DEBUG ( 0 , ( " Wrong LDAP operation type: %d! \n " ,
ldap_op ) ) ;
2003-04-28 14:20:55 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2002-11-02 06:47:48 +03:00
}
if ( rc ! = LDAP_SUCCESS ) {
2003-04-05 09:11:50 +04:00
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2002-11-02 06:47:48 +03:00
& ld_error ) ;
DEBUG ( 1 ,
( " failed to %s user dn= %s with: %s \n \t %s \n " ,
ldap_op = = LDAP_MOD_ADD ? " add " : " modify " ,
dn , ldap_err2string ( rc ) ,
2003-04-05 09:11:50 +04:00
ld_error ? ld_error : " unknown " ) ) ;
SAFE_FREE ( ld_error ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
2002-09-25 19:19:00 +04:00
}
2003-04-23 03:14:49 +04:00
if ( ! ( pdb_get_acct_ctrl ( newpwd ) & ( ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST ) ) & &
( lp_ldap_passwd_sync ( ) ! = LDAP_PASSWD_SYNC_OFF ) & &
need_update ( newpwd , PDB_PLAINTEXT_PW ) & &
2002-09-25 19:19:00 +04:00
( pdb_get_plaintext_passwd ( newpwd ) ! = NULL ) ) {
BerElement * ber ;
struct berval * bv ;
char * retoid ;
struct berval * retdata ;
2003-04-25 09:59:49 +04:00
char * utf8_password ;
2003-04-26 17:29:37 +04:00
char * utf8_dn ;
2003-04-25 09:59:49 +04:00
if ( push_utf8_allocate ( & utf8_password , pdb_get_plaintext_passwd ( newpwd ) ) = = ( size_t ) - 1 ) {
return NT_STATUS_NO_MEMORY ;
}
2002-09-25 19:19:00 +04:00
2003-04-26 17:29:37 +04:00
if ( push_utf8_allocate ( & utf8_dn , dn ) = = ( size_t ) - 1 ) {
return NT_STATUS_NO_MEMORY ;
}
2002-09-25 19:19:00 +04:00
if ( ( ber = ber_alloc_t ( LBER_USE_DER ) ) = = NULL ) {
DEBUG ( 0 , ( " ber_alloc_t returns NULL \n " ) ) ;
2003-04-25 09:59:49 +04:00
SAFE_FREE ( utf8_password ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-09-25 19:19:00 +04:00
}
2003-04-25 09:59:49 +04:00
2002-09-25 19:19:00 +04:00
ber_printf ( ber , " { " ) ;
2003-06-07 02:50:54 +04:00
ber_printf ( ber , " ts " , LDAP_TAG_EXOP_MODIFY_PASSWD_ID , utf8_dn ) ;
ber_printf ( ber , " ts " , LDAP_TAG_EXOP_MODIFY_PASSWD_NEW , utf8_password ) ;
2002-09-25 19:19:00 +04:00
ber_printf ( ber , " N} " ) ;
if ( ( rc = ber_flatten ( ber , & bv ) ) < 0 ) {
DEBUG ( 0 , ( " ber_flatten returns a value <0 \n " ) ) ;
2003-04-25 09:59:49 +04:00
ber_free ( ber , 1 ) ;
2003-04-26 17:29:37 +04:00
SAFE_FREE ( utf8_dn ) ;
2003-04-25 09:59:49 +04:00
SAFE_FREE ( utf8_password ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-09-25 19:19:00 +04:00
}
2003-04-26 17:29:37 +04:00
SAFE_FREE ( utf8_dn ) ;
2003-04-25 09:59:49 +04:00
SAFE_FREE ( utf8_password ) ;
ber_free ( ber , 1 ) ;
2002-11-02 06:47:48 +03:00
2003-06-21 04:45:03 +04:00
if ( ( rc = smbldap_extended_operation ( ldap_state - > smbldap_state ,
LDAP_EXOP_MODIFY_PASSWD ,
bv , NULL , NULL , & retoid ,
& retdata ) ) ! = LDAP_SUCCESS ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " LDAP Password could not be changed for user %s: %s \n " ,
pdb_get_username ( newpwd ) , ldap_err2string ( rc ) ) ) ;
} else {
DEBUG ( 3 , ( " LDAP Password changed for user %s \n " , pdb_get_username ( newpwd ) ) ) ;
2003-04-23 03:14:49 +04:00
# ifdef DEBUG_PASSWORD
DEBUG ( 100 , ( " LDAP Password changed to %s \n " , pdb_get_plaintext_passwd ( newpwd ) ) ) ;
# endif
2002-09-25 19:19:00 +04:00
ber_bvfree ( retdata ) ;
ber_memfree ( retoid ) ;
}
ber_bvfree ( bv ) ;
}
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2002-09-25 19:19:00 +04:00
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Delete entry from LDAP for username
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_delete_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * sam_acct )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
const char * sname ;
2001-09-26 00:21:21 +04:00
int rc ;
LDAPMessage * result ;
2003-03-19 21:21:44 +03:00
NTSTATUS ret ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
fstring objclass ;
2001-09-26 00:21:21 +04:00
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
if ( ! sam_acct ) {
DEBUG ( 0 , ( " sam_acct was NULL! \n " ) ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_INVALID_PARAMETER ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
}
sname = pdb_get_username ( sam_acct ) ;
2001-09-26 00:21:21 +04:00
DEBUG ( 3 , ( " Deleting user %s from LDAP. \n " , sname ) ) ;
2003-05-14 07:32:20 +04:00
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
rc = ldapsam_search_suffix_by_name ( ldap_state , sname , & result , attr_list ) ;
if ( rc ! = LDAP_SUCCESS ) {
free_attr_list ( attr_list ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_NO_SUCH_USER ;
}
2003-05-14 07:32:20 +04:00
switch ( ldap_state - > schema_ver )
{
case SCHEMAVER_SAMBASAMACCOUNT :
fstrcpy ( objclass , LDAP_OBJ_SAMBASAMACCOUNT ) ;
break ;
case SCHEMAVER_SAMBAACCOUNT :
fstrcpy ( objclass , LDAP_OBJ_SAMBAACCOUNT ) ;
break ;
default :
fstrcpy ( objclass , " UNKNOWN " ) ;
DEBUG ( 0 , ( " ldapsam_delete_sam_account: Unknown schema version specified! \n " ) ) ;
break ;
}
2002-11-27 00:00:18 +03:00
2003-05-14 07:32:20 +04:00
ret = ldapsam_delete_entry ( ldap_state , result , objclass , attr_list ) ;
2002-09-25 19:19:00 +04:00
ldap_msgfree ( result ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
2003-03-19 21:21:44 +03:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2003-03-27 17:31:46 +03:00
/**********************************************************************
Helper function to determine for update_sam_account whether
we need LDAP modification .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL element_is_changed ( const SAM_ACCOUNT * sampass ,
enum pdb_elements element )
{
return IS_SAM_CHANGED ( sampass , element ) ;
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Update SAM_ACCOUNT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_update_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * newpwd )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
char * dn ;
LDAPMessage * result ;
LDAPMessage * entry ;
LDAPMod * * mods ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2001-09-26 00:21:21 +04:00
2003-07-05 13:46:12 +04:00
result = pdb_get_backend_private_data ( newpwd , my_methods ) ;
if ( ! result ) {
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
rc = ldapsam_search_suffix_by_name ( ldap_state , pdb_get_username ( newpwd ) , & result , attr_list ) ;
free_attr_list ( attr_list ) ;
2003-07-05 14:39:41 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2003-07-05 13:46:12 +04:00
return NT_STATUS_UNSUCCESSFUL ;
2003-07-05 14:39:41 +04:00
}
2003-07-05 13:46:12 +04:00
pdb_set_backend_private_data ( newpwd , result , private_data_free_fn , my_methods , PDB_CHANGED ) ;
}
2001-09-26 00:21:21 +04:00
2003-06-21 04:45:03 +04:00
if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) = = 0 ) {
2002-11-02 06:47:48 +03:00
DEBUG ( 0 , ( " No user to modify! \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
dn = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
2003-03-22 22:16:36 +03:00
2003-07-05 14:39:41 +04:00
DEBUG ( 4 , ( " user %s to be modified has dn: %s \n " , pdb_get_username ( newpwd ) , dn ) ) ;
2003-03-27 17:31:46 +03:00
if ( ! init_ldap_from_sam ( ldap_state , entry , & mods , newpwd ,
element_is_changed ) ) {
2003-03-22 22:16:36 +03:00
DEBUG ( 0 , ( " ldapsam_update_sam_account: init_ldap_from_sam failed! \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( mods = = NULL ) {
DEBUG ( 4 , ( " mods is empty: nothing to update for user: %s \n " ,
pdb_get_username ( newpwd ) ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-03-22 22:16:36 +03:00
return NT_STATUS_OK ;
}
2003-04-23 03:14:49 +04:00
ret = ldapsam_modify_entry ( my_methods , newpwd , dn , mods , LDAP_MOD_REPLACE , element_is_changed ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-03-22 22:16:36 +03:00
2003-03-28 12:59:11 +03:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-04-05 09:11:50 +04:00
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-03-28 12:59:11 +03:00
& ld_error ) ;
DEBUG ( 0 , ( " failed to modify user with uid = %s, error: %s (%s) \n " ,
2003-04-05 09:11:50 +04:00
pdb_get_username ( newpwd ) , ld_error ? ld_error : " (unknwon) " , ldap_err2string ( rc ) ) ) ;
2003-03-28 12:59:11 +03:00
SAFE_FREE ( ld_error ) ;
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2003-03-22 22:16:36 +03:00
DEBUG ( 2 , ( " successfully modified uid = %s in the LDAP database \n " ,
pdb_get_username ( newpwd ) ) ) ;
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
2003-03-27 17:31:46 +03:00
/**********************************************************************
Helper function to determine for update_sam_account whether
we need LDAP modification .
2003-05-14 07:32:20 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-27 17:31:46 +03:00
static BOOL element_is_set_or_changed ( const SAM_ACCOUNT * sampass ,
enum pdb_elements element )
{
return ( IS_SAM_SET ( sampass , element ) | |
IS_SAM_CHANGED ( sampass , element ) ) ;
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Add SAM_ACCOUNT to LDAP
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-05-14 07:32:20 +04:00
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_add_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * newpwd )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
2003-05-14 07:32:20 +04:00
LDAPMessage * result = NULL ;
LDAPMessage * entry = NULL ;
pstring dn ;
LDAPMod * * mods = NULL ;
2001-12-31 03:06:51 +03:00
int ldap_op ;
uint32 num_result ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
char * escape_user ;
const char * username = pdb_get_username ( newpwd ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
const DOM_SID * sid = pdb_get_user_sid ( newpwd ) ;
2003-05-14 07:32:20 +04:00
pstring filter ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
fstring sid_string ;
2003-05-14 07:32:20 +04:00
2002-03-23 11:32:25 +03:00
if ( ! username | | ! * username ) {
DEBUG ( 0 , ( " Cannot add user without a username! \n " ) ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2001-09-26 00:21:21 +04:00
}
2003-05-14 07:32:20 +04:00
/* free this list after the second search or in case we exit on failure */
attr_list = get_userattr_list ( ldap_state - > schema_ver ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
2003-05-14 07:32:20 +04:00
rc = ldapsam_search_suffix_by_name ( ldap_state , username , & result , attr_list ) ;
2002-11-27 00:00:18 +03:00
if ( rc ! = LDAP_SUCCESS ) {
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
2001-09-26 00:21:21 +04:00
2003-06-21 04:45:03 +04:00
if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ! = 0 ) {
2003-05-14 07:32:20 +04:00
DEBUG ( 0 , ( " User '%s' already in the base, with samba attributes \n " ,
2003-02-01 10:59:29 +03:00
username ) ) ;
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
2003-05-14 07:32:20 +04:00
free_attr_list ( attr_list ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
ldap_msgfree ( result ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
result = NULL ;
if ( element_is_set_or_changed ( newpwd , PDB_USERSID ) ) {
rc = ldapsam_get_ldap_user_by_sid ( ldap_state ,
sid , & result ) ;
if ( rc = = LDAP_SUCCESS ) {
if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ! = 0 ) {
DEBUG ( 0 , ( " SID '%s' already in the base, with samba attributes \n " ,
sid_to_string ( sid_string , sid ) ) ) ;
free_attr_list ( attr_list ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
ldap_msgfree ( result ) ;
}
}
2001-09-26 00:21:21 +04:00
2003-07-05 14:39:41 +04:00
/* does the entry already exist but without a samba attributes?
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
we need to return the samba attributes here */
2003-05-14 07:32:20 +04:00
escape_user = escape_ldap_string_alloc ( username ) ;
pstrcpy ( filter , lp_ldap_filter ( ) ) ;
all_string_sub ( filter , " %u " , escape_user , sizeof ( filter ) ) ;
SAFE_FREE ( escape_user ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search_suffix ( ldap_state - > smbldap_state ,
filter , attr_list , & result ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( rc ! = LDAP_SUCCESS ) {
free_attr_list ( attr_list ) ;
2002-11-27 00:00:18 +03:00
return NT_STATUS_UNSUCCESSFUL ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
}
2002-11-27 00:00:18 +03:00
2003-06-21 04:45:03 +04:00
num_result = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2001-12-31 03:06:51 +03:00
if ( num_result > 1 ) {
DEBUG ( 0 , ( " More than one user with that uid exists: bailing out! \n " ) ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
free_attr_list ( attr_list ) ;
2002-03-23 11:32:25 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-12-31 03:06:51 +03:00
}
/* Check if we need to update an existing entry */
if ( num_result = = 1 ) {
2001-09-26 00:21:21 +04:00
char * tmp ;
2001-12-31 03:06:51 +03:00
2003-05-14 07:32:20 +04:00
DEBUG ( 3 , ( " User exists without samba attributes: adding them \n " ) ) ;
2001-09-26 00:21:21 +04:00
ldap_op = LDAP_MOD_REPLACE ;
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
tmp = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
2001-09-26 00:21:21 +04:00
slprintf ( dn , sizeof ( dn ) - 1 , " %s " , tmp ) ;
ldap_memfree ( tmp ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
} else if ( ldap_state - > schema_ver = = SCHEMAVER_SAMBASAMACCOUNT ) {
/* There might be a SID for this account already - say an idmap entry */
snprintf ( filter , sizeof ( filter ) - 1 , " (&(%s=%s)(|(objectClass=%s)(objectClass=%s))) " ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) ,
sid_to_string ( sid_string , sid ) ,
LDAP_OBJ_IDMAP_ENTRY ,
LDAP_OBJ_SID_ENTRY ) ;
rc = smbldap_search_suffix ( ldap_state - > smbldap_state ,
filter , attr_list , & result ) ;
free_attr_list ( attr_list ) ;
if ( rc ! = LDAP_SUCCESS ) {
free_attr_list ( attr_list ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
num_result = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
if ( num_result > 1 ) {
DEBUG ( 0 , ( " More than one user with that uid exists: bailing out! \n " ) ) ;
free_attr_list ( attr_list ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* Check if we need to update an existing entry */
if ( num_result = = 1 ) {
char * tmp ;
DEBUG ( 3 , ( " User exists without samba attributes: adding them \n " ) ) ;
ldap_op = LDAP_MOD_REPLACE ;
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
tmp = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
slprintf ( dn , sizeof ( dn ) - 1 , " %s " , tmp ) ;
ldap_memfree ( tmp ) ;
}
}
if ( num_result = = 0 ) {
2001-12-31 03:06:51 +03:00
/* Check if we need to add an entry */
DEBUG ( 3 , ( " Adding new user \n " ) ) ;
ldap_op = LDAP_MOD_ADD ;
2002-03-23 11:32:25 +03:00
if ( username [ strlen ( username ) - 1 ] = = ' $ ' ) {
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
slprintf ( dn , sizeof ( dn ) - 1 , " uid=%s,%s " , username , lp_ldap_machine_suffix ( ) ) ;
} else {
slprintf ( dn , sizeof ( dn ) - 1 , " uid=%s,%s " , username , lp_ldap_user_suffix ( ) ) ;
}
2001-09-26 00:21:21 +04:00
}
2003-03-27 17:31:46 +03:00
if ( ! init_ldap_from_sam ( ldap_state , entry , & mods , newpwd ,
element_is_set_or_changed ) ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 0 , ( " ldapsam_add_sam_account: init_ldap_from_sam failed! \n " ) ) ;
2003-03-22 22:16:36 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
2003-03-22 22:16:36 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
if ( mods = = NULL ) {
DEBUG ( 0 , ( " mods is empty: nothing to add for user: %s \n " , pdb_get_username ( newpwd ) ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
2002-11-27 00:00:18 +03:00
}
2003-05-14 07:32:20 +04:00
switch ( ldap_state - > schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT :
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD , " objectclass " , LDAP_OBJ_SAMBAACCOUNT ) ;
2003-05-14 07:32:20 +04:00
break ;
case SCHEMAVER_SAMBASAMACCOUNT :
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD , " objectclass " , LDAP_OBJ_SAMBASAMACCOUNT ) ;
2003-05-14 07:32:20 +04:00
break ;
default :
DEBUG ( 0 , ( " ldapsam_add_sam_account: invalid schema version specified \n " ) ) ;
break ;
}
2001-09-26 00:21:21 +04:00
2003-04-23 03:14:49 +04:00
ret = ldapsam_modify_entry ( my_methods , newpwd , dn , mods , ldap_op , element_is_set_or_changed ) ;
2003-06-22 14:09:52 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " failed to modify/add user with uid = %s (dn = %s) \n " ,
2002-11-02 06:47:48 +03:00
pdb_get_username ( newpwd ) , dn ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2002-09-25 19:19:00 +04:00
2003-05-14 07:32:20 +04:00
DEBUG ( 2 , ( " added: uid == %s in the LDAP database \n " , pdb_get_username ( newpwd ) ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-05-14 07:32:20 +04:00
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static int ldapsam_search_one_group ( struct ldapsam_privates * ldap_state ,
const char * filter ,
LDAPMessage * * result )
{
int scope = LDAP_SCOPE_SUBTREE ;
int rc ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2003-03-19 12:43:23 +03:00
DEBUG ( 2 , ( " ldapsam_search_one_group: searching for:[%s] \n " , filter ) ) ;
2003-05-14 07:32:20 +04:00
attr_list = get_attr_list ( groupmap_attr_list ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search ( ldap_state - > smbldap_state ,
lp_ldap_group_suffix ( ) , scope ,
2003-05-14 07:32:20 +04:00
filter , attr_list , 0 , result ) ;
free_attr_list ( attr_list ) ;
2003-03-19 12:43:23 +03:00
if ( rc ! = LDAP_SUCCESS ) {
2003-04-05 09:11:50 +04:00
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-03-28 12:59:11 +03:00
& ld_error ) ;
2003-03-19 12:43:23 +03:00
DEBUG ( 0 , ( " ldapsam_search_one_group: "
2003-03-28 12:59:11 +03:00
" Problem during the LDAP search: LDAP error: %s (%s) " ,
2003-04-05 09:11:50 +04:00
ld_error ? ld_error : " (unknown) " , ldap_err2string ( rc ) ) ) ;
2003-03-19 12:43:23 +03:00
DEBUG ( 3 , ( " ldapsam_search_one_group: Query was: %s, %s \n " ,
2003-06-06 17:48:39 +04:00
lp_ldap_group_suffix ( ) , filter ) ) ;
2003-03-28 12:59:11 +03:00
SAFE_FREE ( ld_error ) ;
2003-03-19 12:43:23 +03:00
}
return rc ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static BOOL init_group_from_ldap ( struct ldapsam_privates * ldap_state ,
GROUP_MAP * map , LDAPMessage * entry )
{
pstring temp ;
if ( ldap_state = = NULL | | map = = NULL | | entry = = NULL | |
2003-06-21 04:45:03 +04:00
ldap_state - > smbldap_state - > ldap_struct = = NULL )
2003-05-14 09:28:16 +04:00
{
2003-03-19 12:43:23 +03:00
DEBUG ( 0 , ( " init_group_from_ldap: NULL parameters found! \n " ) ) ;
return False ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GIDNUMBER ) , temp ) )
{
DEBUG ( 0 , ( " Mandatory attribute %s not found \n " ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GIDNUMBER ) ) ) ;
2003-03-19 12:43:23 +03:00
return False ;
}
DEBUG ( 2 , ( " Entry found for group: %s \n " , temp ) ) ;
2003-03-23 11:41:05 +03:00
map - > gid = ( gid_t ) atol ( temp ) ;
2003-03-19 12:43:23 +03:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_SID ) , temp ) )
{
DEBUG ( 0 , ( " Mandatory attribute %s not found \n " ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_SID ) ) ) ;
2003-03-19 12:43:23 +03:00
return False ;
}
string_to_sid ( & map - > sid , temp ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_TYPE ) , temp ) )
{
DEBUG ( 0 , ( " Mandatory attribute %s not found \n " ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_TYPE ) ) ) ;
2003-03-19 12:43:23 +03:00
return False ;
}
map - > sid_name_use = ( uint32 ) atol ( temp ) ;
if ( ( map - > sid_name_use < SID_NAME_USER ) | |
( map - > sid_name_use > SID_NAME_UNKNOWN ) ) {
DEBUG ( 0 , ( " Unknown Group type: %d \n " , map - > sid_name_use ) ) ;
return False ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_DISPLAY_NAME ) , temp ) )
{
2003-03-19 12:43:23 +03:00
temp [ 0 ] = ' \0 ' ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_CN ) , temp ) )
{
2003-03-25 11:55:37 +03:00
DEBUG ( 0 , ( " Attributes cn not found either "
" for gidNumber(%i) \n " , map - > gid ) ) ;
2003-03-23 11:41:05 +03:00
return False ;
}
2003-03-19 12:43:23 +03:00
}
fstrcpy ( map - > nt_name , temp ) ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_DESC ) , temp ) )
{
2003-03-19 12:43:23 +03:00
temp [ 0 ] = ' \0 ' ;
}
fstrcpy ( map - > comment , temp ) ;
return True ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-30 20:40:41 +04:00
static BOOL init_ldap_from_group ( LDAP * ldap_struct ,
LDAPMessage * existing ,
LDAPMod * * * mods ,
2003-03-19 12:43:23 +03:00
const GROUP_MAP * map )
{
pstring tmp ;
if ( mods = = NULL | | map = = NULL ) {
DEBUG ( 0 , ( " init_ldap_from_group: NULL parameters found! \n " ) ) ;
return False ;
}
* mods = NULL ;
sid_to_string ( tmp , & map - > sid ) ;
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_struct , existing , mods ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_SID ) , tmp ) ;
2003-03-19 12:43:23 +03:00
snprintf ( tmp , sizeof ( tmp ) - 1 , " %i " , map - > sid_name_use ) ;
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_struct , existing , mods ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_TYPE ) , tmp ) ;
2003-03-19 12:43:23 +03:00
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_struct , existing , mods ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_DISPLAY_NAME ) , map - > nt_name ) ;
2003-06-21 04:45:03 +04:00
smbldap_make_mod ( ldap_struct , existing , mods ,
2003-05-14 09:28:16 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_DESC ) , map - > comment ) ;
2003-03-19 12:43:23 +03:00
return True ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static NTSTATUS ldapsam_getgroup ( struct pdb_methods * methods ,
const char * filter ,
GROUP_MAP * map )
{
struct ldapsam_privates * ldap_state =
( struct ldapsam_privates * ) methods - > private_data ;
LDAPMessage * result ;
LDAPMessage * entry ;
int count ;
if ( ldapsam_search_one_group ( ldap_state , filter , & result )
! = LDAP_SUCCESS ) {
return NT_STATUS_NO_SUCH_GROUP ;
}
2003-06-21 04:45:03 +04:00
count = ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-03-19 12:43:23 +03:00
if ( count < 1 ) {
DEBUG ( 4 , ( " Did not find group for filter %s \n " , filter ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( count > 1 ) {
DEBUG ( 1 , ( " Duplicate entries for filter %s: count=%d \n " ,
filter , count ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
2003-03-19 12:43:23 +03:00
if ( ! entry ) {
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( ! init_group_from_ldap ( ldap_state , map , entry ) ) {
DEBUG ( 1 , ( " init_group_from_ldap failed for group filter %s \n " ,
filter ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
ldap_msgfree ( result ) ;
return NT_STATUS_OK ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_getgrsid ( struct pdb_methods * methods , GROUP_MAP * map ,
2003-06-18 19:24:10 +04:00
DOM_SID sid )
2002-11-02 06:47:48 +03:00
{
2003-03-19 12:43:23 +03:00
pstring filter ;
2003-05-14 09:28:16 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(%s=%s)) " ,
LDAP_OBJ_GROUPMAP ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GROUP_SID ) ,
sid_string_static ( & sid ) ) ;
2003-03-19 12:43:23 +03:00
return ldapsam_getgroup ( methods , filter , map ) ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_getgrgid ( struct pdb_methods * methods , GROUP_MAP * map ,
2003-06-18 19:24:10 +04:00
gid_t gid )
2002-11-02 06:47:48 +03:00
{
2003-03-19 12:43:23 +03:00
pstring filter ;
2003-05-14 09:28:16 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(%s=%d)) " ,
LDAP_OBJ_GROUPMAP ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GIDNUMBER ) ,
gid ) ;
2003-03-19 12:43:23 +03:00
return ldapsam_getgroup ( methods , filter , map ) ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_getgrnam ( struct pdb_methods * methods , GROUP_MAP * map ,
2003-06-18 19:24:10 +04:00
const char * name )
2002-11-02 06:47:48 +03:00
{
2003-03-19 12:43:23 +03:00
pstring filter ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
char * escape_name = escape_ldap_string_alloc ( name ) ;
2003-03-19 12:43:23 +03:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
if ( ! escape_name ) {
return NT_STATUS_NO_MEMORY ;
}
2003-03-19 12:43:23 +03:00
2003-05-14 09:28:16 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(|(%s=%s)(%s=%s))) " ,
LDAP_OBJ_GROUPMAP ,
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_DISPLAY_NAME ) , escape_name ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_CN ) , escape_name ) ;
SAFE_FREE ( escape_name ) ;
2003-03-19 12:43:23 +03:00
return ldapsam_getgroup ( methods , filter , map ) ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static int ldapsam_search_one_group_by_gid ( struct ldapsam_privates * ldap_state ,
gid_t gid ,
LDAPMessage * * result )
{
pstring filter ;
2003-05-14 09:28:16 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(%s=%i)) " ,
LDAP_OBJ_POSIXGROUP ,
get_attr_key2string ( groupmap_attr_list , LDAP_ATTR_GIDNUMBER ) ,
gid ) ;
2003-03-19 12:43:23 +03:00
return ldapsam_search_one_group ( ldap_state , filter , result ) ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_add_group_mapping_entry ( struct pdb_methods * methods ,
2002-11-02 06:47:48 +03:00
GROUP_MAP * map )
{
2003-03-19 12:43:23 +03:00
struct ldapsam_privates * ldap_state =
( struct ldapsam_privates * ) methods - > private_data ;
LDAPMessage * result = NULL ;
LDAPMod * * mods = NULL ;
char * tmp ;
pstring dn ;
LDAPMessage * entry ;
GROUP_MAP dummy ;
int rc ;
if ( NT_STATUS_IS_OK ( ldapsam_getgrgid ( methods , & dummy ,
2003-06-18 19:24:10 +04:00
map - > gid ) ) ) {
2003-03-19 12:43:23 +03:00
DEBUG ( 0 , ( " Group %i already exists in LDAP \n " , map - > gid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
rc = ldapsam_search_one_group_by_gid ( ldap_state , map - > gid , & result ) ;
if ( rc ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) ! = 1 ) {
2003-03-19 12:43:23 +03:00
DEBUG ( 2 , ( " Group %i must exist exactly once in LDAP \n " ,
map - > gid ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
tmp = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
2003-03-19 12:43:23 +03:00
pstrcpy ( dn , tmp ) ;
ldap_memfree ( tmp ) ;
2003-06-21 04:45:03 +04:00
if ( ! init_ldap_from_group ( ldap_state - > smbldap_state - > ldap_struct ,
2003-03-30 20:40:41 +04:00
result , & mods , map ) ) {
2003-03-19 12:43:23 +03:00
DEBUG ( 0 , ( " init_ldap_from_group failed! \n " ) ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-03-30 20:40:41 +04:00
ldap_msgfree ( result ) ;
2003-03-19 12:43:23 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-03-30 20:40:41 +04:00
ldap_msgfree ( result ) ;
2003-03-19 12:43:23 +03:00
if ( mods = = NULL ) {
DEBUG ( 0 , ( " mods is empty \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
smbldap_set_mod ( & mods , LDAP_MOD_ADD , " objectClass " , LDAP_OBJ_GROUPMAP ) ;
2003-03-19 12:43:23 +03:00
2003-06-21 04:45:03 +04:00
rc = smbldap_modify ( ldap_state - > smbldap_state , dn , mods ) ;
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-03-19 12:43:23 +03:00
if ( rc ! = LDAP_SUCCESS ) {
2003-04-05 09:11:50 +04:00
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-03-28 12:59:11 +03:00
& ld_error ) ;
DEBUG ( 0 , ( " failed to add group %i error: %s (%s) \n " , map - > gid ,
2003-04-05 09:11:50 +04:00
ld_error ? ld_error : " (unknown) " , ldap_err2string ( rc ) ) ) ;
2003-03-28 12:59:11 +03:00
SAFE_FREE ( ld_error ) ;
2003-03-19 12:43:23 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
DEBUG ( 2 , ( " successfully modified group %i in LDAP \n " , map - > gid ) ) ;
return NT_STATUS_OK ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_update_group_mapping_entry ( struct pdb_methods * methods ,
2002-11-02 06:47:48 +03:00
GROUP_MAP * map )
{
2003-03-19 12:43:23 +03:00
struct ldapsam_privates * ldap_state =
( struct ldapsam_privates * ) methods - > private_data ;
int rc ;
char * dn ;
LDAPMessage * result ;
LDAPMessage * entry ;
LDAPMod * * mods ;
rc = ldapsam_search_one_group_by_gid ( ldap_state , map - > gid , & result ) ;
if ( rc ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
if ( ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct , result ) = = 0 ) {
2003-03-19 12:43:23 +03:00
DEBUG ( 0 , ( " No group to modify! \n " ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-21 04:45:03 +04:00
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
dn = ldap_get_dn ( ldap_state - > smbldap_state - > ldap_struct , entry ) ;
2003-03-30 20:40:41 +04:00
2003-06-21 04:45:03 +04:00
if ( ! init_ldap_from_group ( ldap_state - > smbldap_state - > ldap_struct ,
2003-03-30 20:40:41 +04:00
result , & mods , map ) ) {
DEBUG ( 0 , ( " init_ldap_from_group failed \n " ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
ldap_msgfree ( result ) ;
if ( mods = = NULL ) {
DEBUG ( 4 , ( " mods is empty: nothing to do \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2003-03-19 12:43:23 +03:00
2003-06-21 04:45:03 +04:00
rc = smbldap_modify ( ldap_state - > smbldap_state , dn , mods ) ;
2003-03-19 12:43:23 +03:00
2003-06-06 17:48:39 +04:00
ldap_mods_free ( mods , True ) ;
2003-03-19 12:43:23 +03:00
if ( rc ! = LDAP_SUCCESS ) {
2003-04-05 09:11:50 +04:00
char * ld_error = NULL ;
2003-06-21 04:45:03 +04:00
ldap_get_option ( ldap_state - > smbldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
2003-03-28 12:59:11 +03:00
& ld_error ) ;
DEBUG ( 0 , ( " failed to modify group %i error: %s (%s) \n " , map - > gid ,
2003-04-05 09:11:50 +04:00
ld_error ? ld_error : " (unknown) " , ldap_err2string ( rc ) ) ) ;
2003-03-28 12:59:11 +03:00
SAFE_FREE ( ld_error ) ;
2003-03-19 12:43:23 +03:00
}
DEBUG ( 2 , ( " successfully modified group %i in LDAP \n " , map - > gid ) ) ;
return NT_STATUS_OK ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_delete_group_mapping_entry ( struct pdb_methods * methods ,
2002-11-02 06:47:48 +03:00
DOM_SID sid )
{
2003-05-14 07:32:20 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) methods - > private_data ;
2003-03-19 12:43:23 +03:00
pstring sidstring , filter ;
LDAPMessage * result ;
2003-03-19 21:21:44 +03:00
int rc ;
NTSTATUS ret ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2003-03-19 12:43:23 +03:00
sid_to_string ( sidstring , & sid ) ;
2003-05-14 07:32:20 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (&(objectClass=%s)(%s=%s)) " ,
LDAP_OBJ_GROUPMAP , LDAP_ATTRIBUTE_SID , sidstring ) ;
2003-03-19 12:43:23 +03:00
rc = ldapsam_search_one_group ( ldap_state , filter , & result ) ;
if ( rc ! = LDAP_SUCCESS ) {
2003-03-19 21:21:44 +03:00
return NT_STATUS_NO_SUCH_GROUP ;
2003-03-19 12:43:23 +03:00
}
2003-05-14 09:28:16 +04:00
attr_list = get_attr_list ( groupmap_attr_list_to_delete ) ;
2003-05-14 07:32:20 +04:00
ret = ldapsam_delete_entry ( ldap_state , result , LDAP_OBJ_GROUPMAP , attr_list ) ;
free_attr_list ( attr_list ) ;
2003-03-19 21:21:44 +03:00
ldap_msgfree ( result ) ;
2003-05-14 07:32:20 +04:00
2003-03-19 21:21:44 +03:00
return ret ;
2003-03-19 12:43:23 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_setsamgrent ( struct pdb_methods * my_methods , BOOL update )
2003-03-19 12:43:23 +03:00
{
2003-05-14 07:32:20 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
fstring filter ;
2003-03-19 12:43:23 +03:00
int rc ;
2003-05-14 07:32:20 +04:00
char * * attr_list ;
2003-03-19 12:43:23 +03:00
2003-05-14 09:28:16 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " (objectclass=%s) " , LDAP_OBJ_GROUPMAP ) ;
2003-05-14 07:32:20 +04:00
attr_list = get_attr_list ( groupmap_attr_list ) ;
2003-06-21 04:45:03 +04:00
rc = smbldap_search ( ldap_state - > smbldap_state , lp_ldap_group_suffix ( ) ,
2003-03-19 12:43:23 +03:00
LDAP_SCOPE_SUBTREE , filter ,
2003-05-14 07:32:20 +04:00
attr_list , 0 , & ldap_state - > result ) ;
free_attr_list ( attr_list ) ;
2003-03-19 12:43:23 +03:00
if ( rc ! = LDAP_SUCCESS ) {
DEBUG ( 0 , ( " LDAP search failed: %s \n " , ldap_err2string ( rc ) ) ) ;
2003-06-06 17:48:39 +04:00
DEBUG ( 3 , ( " Query was: %s, %s \n " , lp_ldap_group_suffix ( ) , filter ) ) ;
2003-03-19 12:43:23 +03:00
ldap_msgfree ( ldap_state - > result ) ;
ldap_state - > result = NULL ;
return NT_STATUS_UNSUCCESSFUL ;
}
DEBUG ( 2 , ( " ldapsam_setsampwent: %d entries in the base! \n " ,
2003-06-21 04:45:03 +04:00
ldap_count_entries ( ldap_state - > smbldap_state - > ldap_struct ,
2003-03-19 12:43:23 +03:00
ldap_state - > result ) ) ) ;
2003-06-21 04:45:03 +04:00
ldap_state - > entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , ldap_state - > result ) ;
2003-03-19 12:43:23 +03:00
ldap_state - > index = 0 ;
return NT_STATUS_OK ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static void ldapsam_endsamgrent ( struct pdb_methods * my_methods )
{
2003-03-20 01:38:37 +03:00
ldapsam_endsampwent ( my_methods ) ;
2003-03-19 12:43:23 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-19 12:43:23 +03:00
static NTSTATUS ldapsam_getsamgrent ( struct pdb_methods * my_methods ,
GROUP_MAP * map )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
BOOL bret = False ;
while ( ! bret ) {
if ( ! ldap_state - > entry )
return ret ;
ldap_state - > index + + ;
bret = init_group_from_ldap ( ldap_state , map , ldap_state - > entry ) ;
2003-06-21 04:45:03 +04:00
ldap_state - > entry = ldap_next_entry ( ldap_state - > smbldap_state - > ldap_struct ,
2003-03-19 12:43:23 +03:00
ldap_state - > entry ) ;
}
return NT_STATUS_OK ;
2002-11-02 06:47:48 +03:00
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-10 02:28:40 +03:00
static NTSTATUS ldapsam_enum_group_mapping ( struct pdb_methods * methods ,
2002-11-02 06:47:48 +03:00
enum SID_NAME_USE sid_name_use ,
GROUP_MAP * * rmap , int * num_entries ,
2003-06-18 19:24:10 +04:00
BOOL unix_only )
2002-11-02 06:47:48 +03:00
{
2003-03-19 12:43:23 +03:00
GROUP_MAP map ;
GROUP_MAP * mapt ;
int entries = 0 ;
NTSTATUS nt_status ;
2002-11-02 06:47:48 +03:00
2003-03-19 12:43:23 +03:00
* num_entries = 0 ;
* rmap = NULL ;
2002-03-02 13:16:28 +03:00
2003-03-19 12:43:23 +03:00
if ( ! NT_STATUS_IS_OK ( ldapsam_setsamgrent ( methods , False ) ) ) {
DEBUG ( 0 , ( " Unable to open passdb \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
2002-08-17 21:00:51 +04:00
}
2003-03-19 12:43:23 +03:00
while ( NT_STATUS_IS_OK ( nt_status = ldapsam_getsamgrent ( methods , & map ) ) ) {
if ( sid_name_use ! = SID_NAME_UNKNOWN & &
sid_name_use ! = map . sid_name_use ) {
DEBUG ( 11 , ( " enum_group_mapping: group %s is not of the requested type \n " , map . nt_name ) ) ;
continue ;
}
if ( unix_only = = ENUM_ONLY_MAPPED & & map . gid = = - 1 ) {
DEBUG ( 11 , ( " enum_group_mapping: group %s is non mapped \n " , map . nt_name ) ) ;
continue ;
}
2002-08-17 21:00:51 +04:00
2003-03-19 12:43:23 +03:00
mapt = ( GROUP_MAP * ) Realloc ( ( * rmap ) , ( entries + 1 ) * sizeof ( GROUP_MAP ) ) ;
if ( ! mapt ) {
DEBUG ( 0 , ( " enum_group_mapping: Unable to enlarge group map! \n " ) ) ;
SAFE_FREE ( * rmap ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
else
( * rmap ) = mapt ;
2002-03-02 13:16:28 +03:00
2003-03-19 12:43:23 +03:00
mapt [ entries ] = map ;
entries + = 1 ;
}
ldapsam_endsamgrent ( methods ) ;
* num_entries = entries ;
return NT_STATUS_OK ;
2002-03-02 13:16:28 +03:00
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
/**********************************************************************
Housekeeping
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_private_data ( void * * vp )
{
struct ldapsam_privates * * ldap_state = ( struct ldapsam_privates * * ) vp ;
smbldap_free_struct ( & ( * ldap_state ) - > smbldap_state ) ;
* ldap_state = NULL ;
/* No need to free any further, as it is talloc()ed */
}
2003-06-21 04:45:03 +04:00
/**********************************************************************
Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2003-05-14 07:32:20 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS pdb_init_ldapsam_common ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method ,
const char * location )
2002-03-02 13:16:28 +03:00
{
NTSTATUS nt_status ;
struct ldapsam_privates * ldap_state ;
if ( ! NT_STATUS_IS_OK ( nt_status = make_pdb_methods ( pdb_context - > mem_ctx , pdb_method ) ) ) {
return nt_status ;
}
( * pdb_method ) - > name = " ldapsam " ;
( * pdb_method ) - > setsampwent = ldapsam_setsampwent ;
( * pdb_method ) - > endsampwent = ldapsam_endsampwent ;
( * pdb_method ) - > getsampwent = ldapsam_getsampwent ;
( * pdb_method ) - > getsampwnam = ldapsam_getsampwnam ;
2002-07-15 14:35:28 +04:00
( * pdb_method ) - > getsampwsid = ldapsam_getsampwsid ;
2002-03-02 13:16:28 +03:00
( * pdb_method ) - > add_sam_account = ldapsam_add_sam_account ;
( * pdb_method ) - > update_sam_account = ldapsam_update_sam_account ;
( * pdb_method ) - > delete_sam_account = ldapsam_delete_sam_account ;
2003-03-19 12:43:23 +03:00
2002-11-09 02:08:59 +03:00
( * pdb_method ) - > getgrsid = ldapsam_getgrsid ;
( * pdb_method ) - > getgrgid = ldapsam_getgrgid ;
( * pdb_method ) - > getgrnam = ldapsam_getgrnam ;
( * pdb_method ) - > add_group_mapping_entry = ldapsam_add_group_mapping_entry ;
( * pdb_method ) - > update_group_mapping_entry = ldapsam_update_group_mapping_entry ;
( * pdb_method ) - > delete_group_mapping_entry = ldapsam_delete_group_mapping_entry ;
( * pdb_method ) - > enum_group_mapping = ldapsam_enum_group_mapping ;
2002-03-02 13:16:28 +03:00
/* TODO: Setup private data and free */
2003-06-21 04:45:03 +04:00
ldap_state = talloc_zero ( pdb_context - > mem_ctx , sizeof ( * ldap_state ) ) ;
2002-03-02 13:16:28 +03:00
if ( ! ldap_state ) {
DEBUG ( 0 , ( " talloc() failed for ldapsam private_data! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2003-06-21 04:45:03 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status =
smbldap_init ( pdb_context - > mem_ctx , location ,
& ldap_state - > smbldap_state ) ) ) ;
2003-04-28 14:20:55 +04:00
2003-05-14 22:36:54 +04:00
ldap_state - > domain_name = talloc_strdup ( pdb_context - > mem_ctx , get_global_sam_name ( ) ) ;
2003-04-28 14:20:55 +04:00
if ( ! ldap_state - > domain_name ) {
return NT_STATUS_NO_MEMORY ;
}
( * pdb_method ) - > private_data = ldap_state ;
( * pdb_method ) - > free_private_data = free_private_data ;
return NT_STATUS_OK ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
2003-06-21 04:45:03 +04:00
Initialise the ' compat ' mode for pdb_ldap
2003-05-14 07:32:20 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-04-28 14:20:55 +04:00
static NTSTATUS pdb_init_ldapsam_compat ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
{
NTSTATUS nt_status ;
struct ldapsam_privates * ldap_state ;
2003-06-24 18:23:34 +04:00
# ifdef WITH_LDAP_SAMCONFIG
if ( ! location ) {
2002-10-01 17:10:57 +04:00
int ldap_port = lp_ldap_port ( ) ;
2002-11-02 06:47:48 +03:00
/* remap default port if not using SSL (ie clear or TLS) */
if ( ( lp_ldap_ssl ( ) ! = LDAP_SSL_ON ) & & ( ldap_port = = 636 ) ) {
2002-10-01 17:10:57 +04:00
ldap_port = 389 ;
}
2003-06-21 04:45:03 +04:00
location = talloc_asprintf ( pdb_context - > mem_ctx , " %s://%s:%d " , lp_ldap_ssl ( ) = = LDAP_SSL_ON ? " ldaps " : " ldap " , lp_ldap_server ( ) , ldap_port ) ;
if ( ! location ) {
2002-10-01 17:10:57 +04:00
return NT_STATUS_NO_MEMORY ;
}
2003-06-21 04:45:03 +04:00
}
2002-10-01 17:10:57 +04:00
# endif
2003-06-21 04:45:03 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_ldapsam_common ( pdb_context , pdb_method , location ) ) ) {
return nt_status ;
2002-03-02 13:16:28 +03:00
}
2003-06-21 04:45:03 +04:00
( * pdb_method ) - > name = " ldapsam_compat " ;
ldap_state = ( * pdb_method ) - > private_data ;
ldap_state - > schema_ver = SCHEMAVER_SAMBAACCOUNT ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
sid_copy ( & ldap_state - > domain_sid , get_global_sam_sid ( ) ) ;
2002-03-02 13:16:28 +03:00
return NT_STATUS_OK ;
}
2003-05-14 07:32:20 +04:00
/**********************************************************************
2003-06-21 04:45:03 +04:00
Initialise the normal mode for pdb_ldap
2003-05-14 07:32:20 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-05-12 22:12:31 +04:00
static NTSTATUS pdb_init_ldapsam ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
2002-03-02 13:16:28 +03:00
{
NTSTATUS nt_status ;
struct ldapsam_privates * ldap_state ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
uint32 alg_rid_base ;
pstring alg_rid_base_string ;
2003-05-12 22:12:31 +04:00
uint32 low_idmap_uid , high_idmap_uid ;
uint32 low_idmap_gid , high_idmap_gid ;
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
LDAPMessage * result ;
LDAPMessage * entry ;
DOM_SID ldap_domain_sid ;
DOM_SID secrets_domain_sid ;
pstring domain_sid_string ;
2002-03-02 13:16:28 +03:00
2003-05-12 22:12:31 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_ldapsam_common ( pdb_context , pdb_method , location ) ) ) {
2002-03-02 13:16:28 +03:00
return nt_status ;
}
2003-05-12 22:12:31 +04:00
( * pdb_method ) - > name = " ldapsam " ;
2002-03-02 13:16:28 +03:00
ldap_state = ( * pdb_method ) - > private_data ;
2003-05-14 07:32:20 +04:00
ldap_state - > schema_ver = SCHEMAVER_SAMBASAMACCOUNT ;
ldap_state - > permit_non_unix_accounts = False ;
2002-03-02 13:16:28 +03:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
/* Try to setup the Domain Name, Domain SID, algorithmic rid base */
if ( ! NT_STATUS_IS_OK ( nt_status = ldapsam_search_domain_info ( ldap_state , & result , True ) ) ) {
DEBUG ( 2 , ( " WARNING: Could not get domain info, nor add one to the domain \n " ) ) ;
DEBUGADD ( 2 , ( " Continuing on regardless, will be unable to allocate new users/groups, and will risk BDCs having inconsistant SIDs \n " ) ) ;
sid_copy ( & ldap_state - > domain_sid , get_global_sam_sid ( ) ) ;
return NT_STATUS_OK ;
}
/* Given that the above might fail, everything below this must be optional */
entry = ldap_first_entry ( ldap_state - > smbldap_state - > ldap_struct , result ) ;
if ( ! entry ) {
DEBUG ( 0 , ( " Could not get domain info entry \n " ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_USER_SID ) ,
domain_sid_string ) )
{
BOOL found_sid ;
string_to_sid ( & ldap_domain_sid , domain_sid_string ) ;
found_sid = secrets_fetch_domain_sid ( ldap_state - > domain_name , & secrets_domain_sid ) ;
if ( ! found_sid | | ! sid_equal ( & secrets_domain_sid , & ldap_domain_sid ) ) {
/* reset secrets.tdb sid */
secrets_store_domain_sid ( ldap_state - > domain_name , & ldap_domain_sid ) ;
}
sid_copy ( & ldap_state - > domain_sid , & ldap_domain_sid ) ;
}
if ( smbldap_get_single_attribute ( ldap_state - > smbldap_state - > ldap_struct , entry ,
get_userattr_key2string ( ldap_state - > schema_ver , LDAP_ATTR_ALGORITHMIC_RID_BASE ) ,
alg_rid_base_string ) )
{
alg_rid_base = ( uint32 ) atol ( alg_rid_base_string ) ;
if ( alg_rid_base ! = algorithmic_rid_base ( ) ) {
DEBUG ( 0 , ( " The value of 'algorithmic RID base' has changed since the LDAP \n "
" database was initialised. Aborting. \n " ) ) ;
ldap_msgfree ( result ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
}
ldap_msgfree ( result ) ;
2003-05-14 07:32:20 +04:00
/* check for non-unix account ranges */
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
if ( lp_idmap_uid ( & low_idmap_uid , & high_idmap_uid )
& & lp_idmap_gid ( & low_idmap_gid , & high_idmap_gid ) )
{
DEBUG ( 2 , ( " Enabling non-unix account ranges \n " ) ) ;
2003-04-28 14:20:55 +04:00
2003-05-14 07:32:20 +04:00
ldap_state - > permit_non_unix_accounts = True ;
2002-03-02 13:16:28 +03:00
2003-05-14 07:32:20 +04:00
ldap_state - > low_allocated_user_rid = fallback_pdb_uid_to_user_rid ( low_idmap_uid ) ;
ldap_state - > high_allocated_user_rid = fallback_pdb_uid_to_user_rid ( high_idmap_uid ) ;
ldap_state - > low_allocated_group_rid = pdb_gid_to_group_rid ( low_idmap_gid ) ;
ldap_state - > high_allocated_group_rid = pdb_gid_to_group_rid ( high_idmap_gid ) ;
}
2002-03-02 13:16:28 +03:00
return NT_STATUS_OK ;
}
2003-05-01 03:06:44 +04:00
NTSTATUS pdb_ldap_init ( void )
2002-03-02 13:16:28 +03:00
{
2003-05-12 22:12:31 +04:00
NTSTATUS nt_status ;
if ( ! NT_STATUS_IS_OK ( nt_status = smb_register_passdb ( PASSDB_INTERFACE_VERSION , " ldapsam " , pdb_init_ldapsam ) ) )
return nt_status ;
if ( ! NT_STATUS_IS_OK ( nt_status = smb_register_passdb ( PASSDB_INTERFACE_VERSION , " ldapsam_compat " , pdb_init_ldapsam_compat ) ) )
return nt_status ;
2003-05-01 03:06:44 +04:00
return NT_STATUS_OK ;
2002-03-02 13:16:28 +03:00
}
2003-05-14 07:32:20 +04:00