2009-06-06 13:25:02 +04:00
/*
Unix SMB / CIFS implementation .
pdb_ldap with ads schema
Copyright ( C ) Volker Lendecke 2009
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
struct pdb_ads_state {
2009-06-28 17:30:08 +04:00
struct sockaddr_un socket_address ;
2009-06-06 13:25:02 +04:00
struct tldap_context * ld ;
struct dom_sid domainsid ;
2009-06-30 00:28:19 +04:00
struct GUID domainguid ;
2009-06-06 13:25:02 +04:00
char * domaindn ;
char * configdn ;
char * netbiosname ;
} ;
2009-07-04 14:26:08 +04:00
struct pdb_ads_samu_private {
char * dn ;
struct tldap_message * ldapmsg ;
} ;
2009-06-09 17:24:06 +04:00
static NTSTATUS pdb_ads_getsampwsid ( struct pdb_methods * m ,
struct samu * sam_acct ,
const DOM_SID * sid ) ;
static bool pdb_ads_gid_to_sid ( struct pdb_methods * m , gid_t gid ,
DOM_SID * sid ) ;
2009-06-28 17:30:08 +04:00
static bool pdb_ads_dnblob2sid ( struct pdb_ads_state * state , DATA_BLOB * dnblob ,
2009-06-09 17:24:06 +04:00
struct dom_sid * psid ) ;
static NTSTATUS pdb_ads_sid2dn ( struct pdb_ads_state * state ,
const struct dom_sid * sid ,
TALLOC_CTX * mem_ctx , char * * pdn ) ;
2009-06-28 17:30:08 +04:00
static struct tldap_context * pdb_ads_ld ( struct pdb_ads_state * state ) ;
static int pdb_ads_search_fmt ( struct pdb_ads_state * state , const char * base ,
int scope , const char * attrs [ ] , int num_attrs ,
int attrsonly ,
TALLOC_CTX * mem_ctx , struct tldap_message * * * res ,
const char * fmt , . . . ) ;
2009-07-04 14:26:08 +04:00
static NTSTATUS pdb_ads_getsamupriv ( struct pdb_ads_state * state ,
const char * filter ,
TALLOC_CTX * mem_ctx ,
struct pdb_ads_samu_private * * presult ) ;
2009-06-09 17:24:06 +04:00
2009-06-06 13:25:02 +04:00
static bool pdb_ads_pull_time ( struct tldap_message * msg , const char * attr ,
time_t * ptime )
{
uint64_t tmp ;
if ( ! tldap_pull_uint64 ( msg , attr , & tmp ) ) {
return false ;
}
* ptime = uint64s_nt_time_to_unix_abs ( & tmp ) ;
return true ;
}
static gid_t pdb_ads_sid2gid ( const struct dom_sid * sid )
{
uint32_t rid ;
sid_peek_rid ( sid , & rid ) ;
return rid ;
}
2009-07-04 13:09:42 +04:00
static char * pdb_ads_domaindn2dns ( TALLOC_CTX * mem_ctx , char * dn )
{
char * result , * p ;
result = talloc_string_sub2 ( mem_ctx , dn , " DC= " , " " , false , false ,
true ) ;
if ( result = = NULL ) {
return NULL ;
}
while ( ( p = strchr_m ( result , ' , ' ) ) ! = NULL ) {
* p = ' . ' ;
}
return result ;
}
2009-07-04 13:12:33 +04:00
static struct pdb_domain_info * pdb_ads_get_domain_info (
struct pdb_methods * m , TALLOC_CTX * mem_ctx )
{
2009-07-04 13:09:42 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
struct pdb_domain_info * info ;
struct tldap_message * rootdse ;
char * tmp ;
info = talloc ( mem_ctx , struct pdb_domain_info ) ;
if ( info = = NULL ) {
return NULL ;
}
info - > name = talloc_strdup ( info , state - > netbiosname ) ;
if ( info - > name = = NULL ) {
goto fail ;
}
info - > dns_domain = pdb_ads_domaindn2dns ( info , state - > domaindn ) ;
if ( info - > dns_domain = = NULL ) {
goto fail ;
}
rootdse = tldap_rootdse ( state - > ld ) ;
tmp = tldap_talloc_single_attribute ( rootdse , " rootDomainNamingContext " ,
talloc_tos ( ) ) ;
if ( tmp = = NULL ) {
goto fail ;
}
info - > dns_forest = pdb_ads_domaindn2dns ( info , tmp ) ;
TALLOC_FREE ( tmp ) ;
if ( info - > dns_forest = = NULL ) {
goto fail ;
}
info - > sid = state - > domainsid ;
info - > guid = state - > domainguid ;
return info ;
fail :
TALLOC_FREE ( info ) ;
2009-07-04 13:12:33 +04:00
return NULL ;
}
2009-06-06 13:25:02 +04:00
static struct pdb_ads_samu_private * pdb_ads_get_samu_private (
struct pdb_methods * m , struct samu * sam )
{
2009-07-04 14:26:08 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-06 13:25:02 +04:00
struct pdb_ads_samu_private * result ;
2009-07-04 14:26:08 +04:00
char * sidstr , * filter ;
NTSTATUS status ;
2009-06-06 13:25:02 +04:00
result = ( struct pdb_ads_samu_private * )
pdb_get_backend_private_data ( sam , m ) ;
if ( result ! = NULL ) {
return talloc_get_type_abort (
result , struct pdb_ads_samu_private ) ;
}
2009-07-04 14:26:08 +04:00
sidstr = sid_binstring ( talloc_tos ( ) , pdb_get_user_sid ( sam ) ) ;
if ( sidstr = = NULL ) {
return NULL ;
}
2009-06-06 13:25:02 +04:00
2009-07-04 14:26:08 +04:00
filter = talloc_asprintf (
talloc_tos ( ) , " (&(objectsid=%s)(objectclass=user)) " , sidstr ) ;
TALLOC_FREE ( sidstr ) ;
if ( filter = = NULL ) {
return NULL ;
}
2009-06-06 13:25:02 +04:00
2009-07-04 14:26:08 +04:00
status = pdb_ads_getsamupriv ( state , filter , sam , & result ) ;
TALLOC_FREE ( filter ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NULL ;
2009-06-06 13:25:02 +04:00
}
2009-07-04 14:26:08 +04:00
return result ;
2009-06-06 13:25:02 +04:00
}
2009-07-04 14:26:08 +04:00
static NTSTATUS pdb_ads_init_sam_from_priv ( struct pdb_methods * m ,
struct samu * sam ,
struct pdb_ads_samu_private * priv )
2009-06-06 13:25:02 +04:00
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
2009-07-04 14:26:08 +04:00
struct tldap_message * entry = priv - > ldapmsg ;
2009-06-06 13:25:02 +04:00
char * str ;
time_t tmp_time ;
struct dom_sid sid ;
uint64_t n ;
DATA_BLOB blob ;
str = tldap_talloc_single_attribute ( entry , " samAccountName " , sam ) ;
if ( str = = NULL ) {
DEBUG ( 10 , ( " no samAccountName \n " ) ) ;
goto fail ;
}
pdb_set_username ( sam , str , PDB_SET ) ;
if ( pdb_ads_pull_time ( entry , " lastLogon " , & tmp_time ) ) {
pdb_set_logon_time ( sam , tmp_time , PDB_SET ) ;
}
if ( pdb_ads_pull_time ( entry , " lastLogoff " , & tmp_time ) ) {
pdb_set_logoff_time ( sam , tmp_time , PDB_SET ) ;
}
if ( pdb_ads_pull_time ( entry , " pwdLastSet " , & tmp_time ) ) {
pdb_set_pass_last_set_time ( sam , tmp_time , PDB_SET ) ;
}
if ( pdb_ads_pull_time ( entry , " accountExpires " , & tmp_time ) ) {
2009-07-13 23:56:31 +04:00
pdb_set_kickoff_time ( sam , tmp_time , PDB_SET ) ;
2009-06-06 13:25:02 +04:00
}
str = tldap_talloc_single_attribute ( entry , " displayName " ,
talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_fullname ( sam , str , PDB_SET ) ;
}
str = tldap_talloc_single_attribute ( entry , " homeDirectory " ,
talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_homedir ( sam , str , PDB_SET ) ;
}
str = tldap_talloc_single_attribute ( entry , " homeDrive " , talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_dir_drive ( sam , str , PDB_SET ) ;
}
str = tldap_talloc_single_attribute ( entry , " scriptPath " , talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_logon_script ( sam , str , PDB_SET ) ;
}
str = tldap_talloc_single_attribute ( entry , " profilePath " ,
talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_profile_path ( sam , str , PDB_SET ) ;
}
str = tldap_talloc_single_attribute ( entry , " profilePath " ,
talloc_tos ( ) ) ;
if ( str ! = NULL ) {
pdb_set_profile_path ( sam , str , PDB_SET ) ;
}
if ( ! tldap_pull_binsid ( entry , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not pull SID \n " ) ) ;
goto fail ;
}
pdb_set_user_sid ( sam , & sid , PDB_SET ) ;
if ( ! tldap_pull_uint64 ( entry , " userAccountControl " , & n ) ) {
DEBUG ( 10 , ( " Could not pull userAccountControl \n " ) ) ;
goto fail ;
}
2009-06-12 17:20:48 +04:00
pdb_set_acct_ctrl ( sam , ds_uf2acb ( n ) , PDB_SET ) ;
2009-06-06 13:25:02 +04:00
if ( tldap_get_single_valueblob ( entry , " unicodePwd " , & blob ) ) {
if ( blob . length ! = NT_HASH_LEN ) {
DEBUG ( 0 , ( " Got NT hash of length %d, expected %d \n " ,
( int ) blob . length , NT_HASH_LEN ) ) ;
goto fail ;
}
pdb_set_nt_passwd ( sam , blob . data , PDB_SET ) ;
}
if ( tldap_get_single_valueblob ( entry , " dBCSPwd " , & blob ) ) {
if ( blob . length ! = LM_HASH_LEN ) {
DEBUG ( 0 , ( " Got LM hash of length %d, expected %d \n " ,
( int ) blob . length , LM_HASH_LEN ) ) ;
goto fail ;
}
pdb_set_lanman_passwd ( sam , blob . data , PDB_SET ) ;
}
if ( tldap_pull_uint64 ( entry , " primaryGroupID " , & n ) ) {
sid_compose ( & sid , & state - > domainsid , n ) ;
pdb_set_group_sid ( sam , & sid , PDB_SET ) ;
}
status = NT_STATUS_OK ;
fail :
TALLOC_FREE ( frame ) ;
return status ;
}
static bool pdb_ads_init_ads_from_sam ( struct pdb_ads_state * state ,
struct tldap_message * existing ,
TALLOC_CTX * mem_ctx ,
int * pnum_mods , struct tldap_mod * * pmods ,
struct samu * sam )
{
bool ret = true ;
2009-06-20 13:46:42 +04:00
DATA_BLOB blob ;
2009-06-06 13:25:02 +04:00
/* TODO: All fields :-) */
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " displayName " ,
2009-06-08 22:15:56 +04:00
" %s " , pdb_get_fullname ( sam ) ) ;
2009-06-06 13:25:02 +04:00
2009-06-20 13:46:42 +04:00
blob = data_blob_const ( pdb_get_nt_passwd ( sam ) , NT_HASH_LEN ) ;
2009-06-24 14:39:21 +04:00
if ( blob . data ! = NULL ) {
ret & = tldap_add_mod_blobs ( mem_ctx , pmods , TLDAP_MOD_REPLACE ,
" unicodePwd " , 1 , & blob ) ;
}
2009-06-06 13:25:02 +04:00
2009-06-20 13:46:42 +04:00
blob = data_blob_const ( pdb_get_lanman_passwd ( sam ) , NT_HASH_LEN ) ;
2009-06-24 14:39:21 +04:00
if ( blob . data ! = NULL ) {
ret & = tldap_add_mod_blobs ( mem_ctx , pmods , TLDAP_MOD_REPLACE ,
" dBCSPwd " , 1 , & blob ) ;
}
2009-06-10 00:09:14 +04:00
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " userAccountControl " ,
2009-06-12 17:20:48 +04:00
" %d " , ds_acb2uf ( pdb_get_acct_ctrl ( sam ) ) ) ;
2009-06-10 00:09:14 +04:00
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " homeDirectory " ,
" %s " , pdb_get_homedir ( sam ) ) ;
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " homeDrive " ,
" %s " , pdb_get_dir_drive ( sam ) ) ;
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " scriptPath " ,
" %s " , pdb_get_logon_script ( sam ) ) ;
ret & = tldap_make_mod_fmt (
existing , mem_ctx , pnum_mods , pmods , " profilePath " ,
" %s " , pdb_get_profile_path ( sam ) ) ;
2009-06-06 13:25:02 +04:00
return ret ;
}
2009-07-04 14:26:08 +04:00
static NTSTATUS pdb_ads_getsamupriv ( struct pdb_ads_state * state ,
const char * filter ,
TALLOC_CTX * mem_ctx ,
struct pdb_ads_samu_private * * presult )
2009-06-06 13:25:02 +04:00
{
const char * attrs [ ] = {
" lastLogon " , " lastLogoff " , " pwdLastSet " , " accountExpires " ,
" sAMAccountName " , " displayName " , " homeDirectory " ,
" homeDrive " , " scriptPath " , " profilePath " , " description " ,
" userWorkstations " , " comment " , " userParameters " , " objectSid " ,
" primaryGroupID " , " userAccountControl " , " logonHours " ,
" badPwdCount " , " logonCount " , " countryCode " , " codePage " ,
" unicodePwd " , " dBCSPwd " } ;
struct tldap_message * * users ;
int rc , count ;
2009-07-04 14:26:08 +04:00
struct pdb_ads_samu_private * result ;
result = talloc ( mem_ctx , struct pdb_ads_samu_private ) ;
if ( result = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-06 13:25:02 +04:00
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-07-04 14:26:08 +04:00
attrs , ARRAY_SIZE ( attrs ) , 0 , result ,
2009-06-28 17:30:08 +04:00
& users , " %s " , filter ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
2009-07-04 14:26:08 +04:00
TALLOC_FREE ( result ) ;
2009-06-06 13:25:02 +04:00
return NT_STATUS_LDAP ( rc ) ;
}
count = talloc_array_length ( users ) ;
if ( count ! = 1 ) {
DEBUG ( 10 , ( " Expected 1 user, got %d \n " , count ) ) ;
2009-07-04 14:26:08 +04:00
TALLOC_FREE ( result ) ;
2009-06-06 13:25:02 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2009-07-04 14:26:08 +04:00
result - > ldapmsg = users [ 0 ] ;
if ( ! tldap_entry_dn ( result - > ldapmsg , & result - > dn ) ) {
DEBUG ( 10 , ( " Could not extract dn \n " ) ) ;
TALLOC_FREE ( result ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
* presult = result ;
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_getsampwfilter ( struct pdb_methods * m ,
struct pdb_ads_state * state ,
struct samu * sam_acct ,
const char * filter )
{
struct pdb_ads_samu_private * priv ;
NTSTATUS status ;
status = pdb_ads_getsamupriv ( state , filter , sam_acct , & priv ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_getsamupriv failed: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
status = pdb_ads_init_sam_from_priv ( m , sam_acct , priv ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_init_sam_from_priv failed: %s \n " ,
nt_errstr ( status ) ) ) ;
TALLOC_FREE ( priv ) ;
return status ;
}
pdb_set_backend_private_data ( sam_acct , priv , NULL , m , PDB_SET ) ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_getsampwnam ( struct pdb_methods * m ,
struct samu * sam_acct ,
const char * username )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
char * filter ;
filter = talloc_asprintf (
talloc_tos ( ) , " (&(samaccountname=%s)(objectclass=user)) " ,
username ) ;
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
return pdb_ads_getsampwfilter ( m , state , sam_acct , filter ) ;
}
static NTSTATUS pdb_ads_getsampwsid ( struct pdb_methods * m ,
struct samu * sam_acct ,
const DOM_SID * sid )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
char * sidstr , * filter ;
sidstr = sid_binstring ( talloc_tos ( ) , sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
filter = talloc_asprintf (
talloc_tos ( ) , " (&(objectsid=%s)(objectclass=user)) " , sidstr ) ;
TALLOC_FREE ( sidstr ) ;
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
return pdb_ads_getsampwfilter ( m , state , sam_acct , filter ) ;
}
static NTSTATUS pdb_ads_create_user ( struct pdb_methods * m ,
TALLOC_CTX * tmp_ctx ,
const char * name , uint32 acct_flags ,
uint32 * rid )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-06 13:25:02 +04:00
const char * attrs [ 1 ] = { " objectSid " } ;
struct tldap_mod * mods = NULL ;
int num_mods = 0 ;
struct tldap_message * * user ;
struct dom_sid sid ;
char * dn ;
int rc ;
bool ok ;
dn = talloc_asprintf ( talloc_tos ( ) , " cn=%s,cn=users,%s " , name ,
state - > domaindn ) ;
if ( dn = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-06 13:25:02 +04:00
/* TODO: Create machines etc */
ok = true ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " objectClass " , " user " ) ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " samAccountName " , " %s " ,
name ) ;
if ( ! ok ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_add ( ld , dn , num_mods , mods , NULL , 0 , NULL , 0 ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_add failed %s \n " ,
2009-06-28 17:30:08 +04:00
tldap_errstr ( debug_ctx ( ) , ld , rc ) ) ) ;
2009-06-06 13:25:02 +04:00
TALLOC_FREE ( dn ) ;
return NT_STATUS_LDAP ( rc ) ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& user ,
" (&(objectclass=user)(samaccountname=%s)) " ,
name ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not find just created user %s: %s \n " ,
name , tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( talloc_array_length ( user ) ! = 1 ) {
DEBUG ( 10 , ( " Got %d users, expected one \n " ,
( int ) talloc_array_length ( user ) ) ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( ! tldap_pull_binsid ( user [ 0 ] , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not fetch objectSid from user %s \n " ,
name ) ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
sid_peek_rid ( & sid , rid ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_delete_user ( struct pdb_methods * m ,
TALLOC_CTX * tmp_ctx ,
struct samu * sam )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-10 13:48:31 +04:00
NTSTATUS status ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-10 13:48:31 +04:00
char * dn ;
2009-06-06 13:25:02 +04:00
int rc ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-10 13:48:31 +04:00
status = pdb_ads_sid2dn ( state , pdb_get_user_sid ( sam ) , talloc_tos ( ) ,
& dn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_delete ( ld , dn , NULL , 0 , NULL , 0 ) ;
2009-06-10 13:48:31 +04:00
TALLOC_FREE ( dn ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
2009-06-10 13:48:31 +04:00
DEBUG ( 10 , ( " ldap_delete for %s failed: %s \n " , dn ,
2009-06-28 17:30:08 +04:00
tldap_errstr ( debug_ctx ( ) , ld , rc ) ) ) ;
2009-06-06 13:25:02 +04:00
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_add_sam_account ( struct pdb_methods * m ,
struct samu * sampass )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_update_sam_account ( struct pdb_methods * m ,
struct samu * sam )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
struct pdb_ads_samu_private * priv = pdb_ads_get_samu_private ( m , sam ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-06 13:25:02 +04:00
struct tldap_mod * mods = NULL ;
int rc , num_mods = 0 ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-06 13:25:02 +04:00
if ( ! pdb_ads_init_ads_from_sam ( state , priv - > ldapmsg , talloc_tos ( ) ,
& num_mods , & mods , sam ) ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-10 00:09:41 +04:00
if ( num_mods = = 0 ) {
/* Nothing to do, just return success */
return NT_STATUS_OK ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_modify ( ld , priv - > dn , num_mods , mods , NULL , 0 ,
2009-06-06 23:06:33 +04:00
NULL , 0 ) ;
2009-06-28 17:30:08 +04:00
TALLOC_FREE ( mods ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_modify for %s failed: %s \n " , priv - > dn ,
2009-06-28 17:30:08 +04:00
tldap_errstr ( debug_ctx ( ) , ld , rc ) ) ) ;
2009-06-06 13:25:02 +04:00
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_delete_sam_account ( struct pdb_methods * m ,
struct samu * username )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_rename_sam_account ( struct pdb_methods * m ,
struct samu * oldname ,
const char * newname )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_update_login_attempts ( struct pdb_methods * m ,
struct samu * sam_acct ,
bool success )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
2009-06-07 21:09:41 +04:00
static NTSTATUS pdb_ads_getgrfilter ( struct pdb_methods * m , GROUP_MAP * map ,
const char * filter )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
const char * attrs [ 4 ] = { " objectSid " , " description " , " samAccountName " ,
" groupType " } ;
char * str ;
struct tldap_message * * group ;
uint32_t grouptype ;
int rc ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& group , " %s " , filter ) ;
2009-06-07 21:09:41 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( talloc_array_length ( group ) ! = 1 ) {
DEBUG ( 10 , ( " Expected 1 user, got %d \n " ,
2009-06-08 23:13:24 +04:00
( int ) talloc_array_length ( group ) ) ) ;
2009-06-07 21:09:41 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ! tldap_pull_binsid ( group [ 0 ] , " objectSid " , & map - > sid ) ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
map - > gid = pdb_ads_sid2gid ( & map - > sid ) ;
if ( ! tldap_pull_uint32 ( group [ 0 ] , " groupType " , & grouptype ) ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
switch ( grouptype ) {
case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP :
case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP :
map - > sid_name_use = SID_NAME_ALIAS ;
break ;
case GTYPE_SECURITY_GLOBAL_GROUP :
map - > sid_name_use = SID_NAME_DOM_GRP ;
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
str = tldap_talloc_single_attribute ( group [ 0 ] , " samAccountName " ,
talloc_tos ( ) ) ;
if ( str = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
fstrcpy ( map - > nt_name , str ) ;
TALLOC_FREE ( str ) ;
str = tldap_talloc_single_attribute ( group [ 0 ] , " description " ,
talloc_tos ( ) ) ;
if ( str ! = NULL ) {
fstrcpy ( map - > comment , str ) ;
TALLOC_FREE ( str ) ;
} else {
map - > comment [ 0 ] = ' \0 ' ;
}
TALLOC_FREE ( group ) ;
return NT_STATUS_OK ;
}
2009-06-06 13:25:02 +04:00
static NTSTATUS pdb_ads_getgrsid ( struct pdb_methods * m , GROUP_MAP * map ,
DOM_SID sid )
{
2009-06-07 21:09:41 +04:00
char * filter ;
NTSTATUS status ;
filter = talloc_asprintf ( talloc_tos ( ) ,
" (&(objectsid=%s)(objectclass=group)) " ,
sid_string_talloc ( talloc_tos ( ) , & sid ) ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = pdb_ads_getgrfilter ( m , map , filter ) ;
TALLOC_FREE ( filter ) ;
return status ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_getgrgid ( struct pdb_methods * m , GROUP_MAP * map ,
gid_t gid )
{
2009-06-07 21:09:41 +04:00
struct dom_sid sid ;
pdb_ads_gid_to_sid ( m , gid , & sid ) ;
return pdb_ads_getgrsid ( m , map , sid ) ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_getgrnam ( struct pdb_methods * m , GROUP_MAP * map ,
const char * name )
{
2009-06-07 21:09:41 +04:00
char * filter ;
NTSTATUS status ;
filter = talloc_asprintf ( talloc_tos ( ) ,
" (&(samaccountname=%s)(objectclass=group)) " ,
name ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = pdb_ads_getgrfilter ( m , map , filter ) ;
TALLOC_FREE ( filter ) ;
return status ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_create_dom_group ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx , const char * name ,
uint32 * rid )
{
2009-06-08 01:29:58 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-08 01:29:58 +04:00
const char * attrs [ 1 ] = { " objectSid " } ;
int num_mods = 0 ;
struct tldap_mod * mods = NULL ;
struct tldap_message * * alias ;
struct dom_sid sid ;
char * dn ;
int rc ;
bool ok = true ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-08 01:29:58 +04:00
dn = talloc_asprintf ( talloc_tos ( ) , " cn=%s,cn=users,%s " , name ,
state - > domaindn ) ;
if ( dn = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " samAccountName " , " %s " ,
name ) ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " objectClass " , " group " ) ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " groupType " ,
" %d " , ( int ) GTYPE_SECURITY_GLOBAL_GROUP ) ;
if ( ! ok ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_add ( ld , dn , num_mods , mods , NULL , 0 , NULL , 0 ) ;
2009-06-08 01:29:58 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_add failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-08 01:29:58 +04:00
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) , & alias ,
" (&(objectclass=group)(samaccountname=%s)) " , name ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not find just created alias %s: %s \n " ,
name , tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( talloc_array_length ( alias ) ! = 1 ) {
DEBUG ( 10 , ( " Got %d alias, expected one \n " ,
( int ) talloc_array_length ( alias ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( ! tldap_pull_binsid ( alias [ 0 ] , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not fetch objectSid from alias %s \n " ,
name ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
sid_peek_rid ( & sid , rid ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_delete_dom_group ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx , uint32 rid )
{
2009-06-09 16:46:55 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-09 16:46:55 +04:00
struct dom_sid sid ;
char * sidstr ;
struct tldap_message * * msg ;
char * dn ;
int rc ;
sid_compose ( & sid , & state - > domainsid , rid ) ;
sidstr = sid_binstring ( talloc_tos ( ) , & sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
NULL , 0 , 0 , talloc_tos ( ) , & msg ,
( " (&(objectSid=%s)(objectClass=group)) " ) ,
sidstr ) ;
2009-06-09 16:46:55 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
switch talloc_array_length ( msg ) {
case 0 :
return NT_STATUS_NO_SUCH_GROUP ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ! tldap_entry_dn ( msg [ 0 ] , & dn ) ) {
2009-06-28 17:30:08 +04:00
TALLOC_FREE ( msg ) ;
2009-06-09 16:46:55 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
TALLOC_FREE ( msg ) ;
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
rc = tldap_delete ( ld , dn , NULL , 0 , NULL , 0 ) ;
TALLOC_FREE ( msg ) ;
2009-06-09 16:46:55 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_delete failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_add_group_mapping_entry ( struct pdb_methods * m ,
GROUP_MAP * map )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_update_group_mapping_entry ( struct pdb_methods * m ,
GROUP_MAP * map )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_delete_group_mapping_entry ( struct pdb_methods * m ,
DOM_SID sid )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_enum_group_mapping ( struct pdb_methods * m ,
const DOM_SID * sid ,
enum lsa_SidType sid_name_use ,
GROUP_MAP * * pp_rmap ,
size_t * p_num_entries ,
bool unix_only )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_enum_group_members ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * group ,
2009-06-09 01:57:54 +04:00
uint32 * * pmembers ,
size_t * pnum_members )
2009-06-06 13:25:02 +04:00
{
2009-06-09 01:57:54 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
const char * attrs [ 1 ] = { " member " } ;
char * sidstr ;
struct tldap_message * * msg ;
int i , rc , num_members ;
DATA_BLOB * blobs ;
uint32_t * members ;
sidstr = sid_binstring ( talloc_tos ( ) , group ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " (objectsid=%s) " , sidstr ) ;
2009-06-09 01:57:54 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
switch talloc_array_length ( msg ) {
case 0 :
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
break ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
break ;
}
if ( ! tldap_entry_values ( msg [ 0 ] , " member " , & num_members , & blobs ) ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
members = talloc_array ( mem_ctx , uint32_t , num_members ) ;
if ( members = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_members ; i + + ) {
struct dom_sid sid ;
2009-06-28 17:30:08 +04:00
if ( ! pdb_ads_dnblob2sid ( state , & blobs [ i ] , & sid )
2009-06-09 01:57:54 +04:00
| | ! sid_peek_rid ( & sid , & members [ i ] ) ) {
TALLOC_FREE ( members ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
* pmembers = members ;
* pnum_members = num_members ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_enum_group_memberships ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
struct samu * user ,
DOM_SID * * pp_sids ,
gid_t * * pp_gids ,
size_t * p_num_groups )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
struct pdb_ads_samu_private * priv = pdb_ads_get_samu_private (
m , user ) ;
const char * attrs [ 1 ] = { " objectSid " } ;
struct tldap_message * * groups ;
int i , rc , count ;
size_t num_groups ;
struct dom_sid * group_sids ;
gid_t * gids ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) , & groups ,
" (&(member=%s)(grouptype=%d)(objectclass=group)) " ,
priv - > dn , GTYPE_SECURITY_GLOBAL_GROUP ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
count = talloc_array_length ( groups ) ;
group_sids = talloc_array ( mem_ctx , struct dom_sid , count ) ;
if ( group_sids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
gids = talloc_array ( mem_ctx , gid_t , count ) ;
if ( gids = = NULL ) {
TALLOC_FREE ( group_sids ) ;
return NT_STATUS_NO_MEMORY ;
}
num_groups = 0 ;
for ( i = 0 ; i < count ; i + + ) {
if ( ! tldap_pull_binsid ( groups [ i ] , " objectSid " ,
& group_sids [ num_groups ] ) ) {
continue ;
}
gids [ num_groups ] = pdb_ads_sid2gid ( & group_sids [ num_groups ] ) ;
num_groups + = 1 ;
if ( num_groups = = count ) {
break ;
}
}
* pp_sids = group_sids ;
* pp_gids = gids ;
* p_num_groups = num_groups ;
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_set_unix_primary_group ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
struct samu * user )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
2009-06-09 17:24:06 +04:00
static NTSTATUS pdb_ads_mod_groupmem ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
uint32 grouprid , uint32 memberrid ,
int mod_op )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-09 17:24:06 +04:00
struct dom_sid groupsid , membersid ;
char * groupdn , * memberdn ;
struct tldap_mod * mods ;
int rc ;
NTSTATUS status ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-09 17:24:06 +04:00
sid_compose ( & groupsid , & state - > domainsid , grouprid ) ;
sid_compose ( & membersid , & state - > domainsid , memberrid ) ;
status = pdb_ads_sid2dn ( state , & groupsid , talloc_tos ( ) , & groupdn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
status = pdb_ads_sid2dn ( state , & membersid , talloc_tos ( ) , & memberdn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_SUCH_USER ;
}
mods = NULL ;
if ( ! tldap_add_mod_str ( talloc_tos ( ) , & mods , mod_op ,
" member " , memberdn ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_modify ( ld , groupdn , 1 , mods , NULL , 0 , NULL , 0 ) ;
2009-06-09 17:24:06 +04:00
TALLOC_FREE ( frame ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_modify failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
if ( rc = = TLDAP_TYPE_OR_VALUE_EXISTS ) {
return NT_STATUS_MEMBER_IN_GROUP ;
}
if ( rc = = TLDAP_NO_SUCH_ATTRIBUTE ) {
return NT_STATUS_MEMBER_NOT_IN_GROUP ;
}
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
}
2009-06-06 13:25:02 +04:00
static NTSTATUS pdb_ads_add_groupmem ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
uint32 group_rid , uint32 member_rid )
{
2009-06-09 17:24:06 +04:00
return pdb_ads_mod_groupmem ( m , mem_ctx , group_rid , member_rid ,
TLDAP_MOD_ADD ) ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_del_groupmem ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
uint32 group_rid , uint32 member_rid )
{
2009-06-09 17:24:06 +04:00
return pdb_ads_mod_groupmem ( m , mem_ctx , group_rid , member_rid ,
TLDAP_MOD_DELETE ) ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_create_alias ( struct pdb_methods * m ,
const char * name , uint32 * rid )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-06 13:25:02 +04:00
const char * attrs [ 1 ] = { " objectSid " } ;
int num_mods = 0 ;
struct tldap_mod * mods = NULL ;
struct tldap_message * * alias ;
struct dom_sid sid ;
char * dn ;
int rc ;
bool ok = true ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-06 13:25:02 +04:00
dn = talloc_asprintf ( talloc_tos ( ) , " cn=%s,cn=users,%s " , name ,
state - > domaindn ) ;
if ( dn = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " samAccountName " , " %s " ,
name ) ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " objectClass " , " group " ) ;
ok & = tldap_make_mod_fmt (
NULL , talloc_tos ( ) , & num_mods , & mods , " groupType " ,
" %d " , ( int ) GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
if ( ! ok ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_add ( ld , dn , num_mods , mods , NULL , 0 , NULL , 0 ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_add failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) , & alias ,
" (&(objectclass=group)(samaccountname=%s)) " , name ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not find just created alias %s: %s \n " ,
name , tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( talloc_array_length ( alias ) ! = 1 ) {
DEBUG ( 10 , ( " Got %d alias, expected one \n " ,
( int ) talloc_array_length ( alias ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( ! tldap_pull_binsid ( alias [ 0 ] , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not fetch objectSid from alias %s \n " ,
name ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
sid_peek_rid ( & sid , rid ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_delete_alias ( struct pdb_methods * m ,
const DOM_SID * sid )
{
2009-06-08 01:32:36 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-08 01:32:36 +04:00
struct tldap_message * * alias ;
char * sidstr , * dn ;
int rc ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-08 01:32:36 +04:00
sidstr = sid_binstring ( talloc_tos ( ) , sid ) ;
if ( sidstr = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
NULL , 0 , 0 , talloc_tos ( ) , & alias ,
" (&(objectSid=%s)(objectclass=group) "
" (|(grouptype=%d)(grouptype=%d))) " ,
sidstr , GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
2009-06-08 01:32:36 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_LDAP ( rc ) ;
}
if ( talloc_array_length ( alias ) ! = 1 ) {
DEBUG ( 10 , ( " Expected 1 alias, got %d \n " ,
2009-06-08 23:13:24 +04:00
( int ) talloc_array_length ( alias ) ) ) ;
2009-06-08 01:32:36 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ! tldap_entry_dn ( alias [ 0 ] , & dn ) ) {
DEBUG ( 10 , ( " Could not get DN for alias %s \n " ,
sid_string_dbg ( sid ) ) ) ;
return NT_STATUS_INTERNAL_ERROR ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_delete ( ld , dn , NULL , 0 , NULL , 0 ) ;
2009-06-08 01:32:36 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_delete failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
TALLOC_FREE ( dn ) ;
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_set_aliasinfo ( struct pdb_methods * m ,
const DOM_SID * sid ,
struct acct_info * info )
{
2009-06-11 01:56:51 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-11 01:56:51 +04:00
const char * attrs [ 3 ] = { " objectSid " , " description " ,
" samAccountName " } ;
struct tldap_message * * msg ;
char * sidstr , * dn ;
int rc ;
struct tldap_mod * mods ;
int num_mods ;
bool ok ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-11 01:56:51 +04:00
sidstr = sid_binstring ( talloc_tos ( ) , sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " (&(objectSid=%s)(objectclass=group) "
" (|(grouptype=%d)(grouptype=%d))) " ,
sidstr , GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
2009-06-11 01:56:51 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
switch talloc_array_length ( msg ) {
case 0 :
return NT_STATUS_NO_SUCH_ALIAS ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ! tldap_entry_dn ( msg [ 0 ] , & dn ) ) {
TALLOC_FREE ( msg ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
mods = NULL ;
num_mods = 0 ;
ok = true ;
ok & = tldap_make_mod_fmt (
msg [ 0 ] , msg , & num_mods , & mods , " description " ,
" %s " , info - > acct_desc ) ;
ok & = tldap_make_mod_fmt (
msg [ 0 ] , msg , & num_mods , & mods , " samAccountName " ,
" %s " , info - > acct_name ) ;
if ( ! ok ) {
TALLOC_FREE ( msg ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( num_mods = = 0 ) {
/* no change */
TALLOC_FREE ( msg ) ;
return NT_STATUS_OK ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_modify ( ld , dn , num_mods , mods , NULL , 0 , NULL , 0 ) ;
2009-06-11 01:56:51 +04:00
TALLOC_FREE ( msg ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_modify failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
2009-06-08 22:37:50 +04:00
static NTSTATUS pdb_ads_sid2dn ( struct pdb_ads_state * state ,
const struct dom_sid * sid ,
TALLOC_CTX * mem_ctx , char * * pdn )
{
struct tldap_message * * msg ;
char * sidstr , * dn ;
int rc ;
sidstr = sid_binstring ( talloc_tos ( ) , sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
NULL , 0 , 0 , talloc_tos ( ) , & msg ,
" (objectsid=%s) " , sidstr ) ;
2009-06-08 22:37:50 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
switch talloc_array_length ( msg ) {
case 0 :
return NT_STATUS_NOT_FOUND ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ! tldap_entry_dn ( msg [ 0 ] , & dn ) ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
dn = talloc_strdup ( mem_ctx , dn ) ;
if ( dn = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
TALLOC_FREE ( msg ) ;
* pdn = dn ;
return NT_STATUS_OK ;
}
static NTSTATUS pdb_ads_mod_aliasmem ( struct pdb_methods * m ,
const DOM_SID * alias ,
const DOM_SID * member ,
int mod_op )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
2009-06-28 17:30:08 +04:00
struct tldap_context * ld ;
2009-06-08 22:37:50 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct tldap_mod * mods ;
int rc ;
char * aliasdn , * memberdn ;
NTSTATUS status ;
2009-06-28 17:30:08 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return NT_STATUS_LDAP ( TLDAP_SERVER_DOWN ) ;
}
2009-06-08 22:37:50 +04:00
status = pdb_ads_sid2dn ( state , alias , talloc_tos ( ) , & aliasdn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_sid2dn (%s) failed: %s \n " ,
sid_string_dbg ( alias ) , nt_errstr ( status ) ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_SUCH_ALIAS ;
}
status = pdb_ads_sid2dn ( state , member , talloc_tos ( ) , & memberdn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_sid2dn (%s) failed: %s \n " ,
sid_string_dbg ( member ) , nt_errstr ( status ) ) ) ;
TALLOC_FREE ( frame ) ;
return status ;
}
mods = NULL ;
if ( ! tldap_add_mod_str ( talloc_tos ( ) , & mods , mod_op ,
" member " , memberdn ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
rc = tldap_modify ( ld , aliasdn , 1 , mods , NULL , 0 , NULL , 0 ) ;
2009-06-08 22:37:50 +04:00
TALLOC_FREE ( frame ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_modify failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
if ( rc = = TLDAP_TYPE_OR_VALUE_EXISTS ) {
return NT_STATUS_MEMBER_IN_ALIAS ;
}
if ( rc = = TLDAP_NO_SUCH_ATTRIBUTE ) {
return NT_STATUS_MEMBER_NOT_IN_ALIAS ;
}
return NT_STATUS_LDAP ( rc ) ;
}
return NT_STATUS_OK ;
}
2009-06-06 13:25:02 +04:00
static NTSTATUS pdb_ads_add_aliasmem ( struct pdb_methods * m ,
const DOM_SID * alias ,
const DOM_SID * member )
{
2009-06-08 22:37:50 +04:00
return pdb_ads_mod_aliasmem ( m , alias , member , TLDAP_MOD_ADD ) ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_del_aliasmem ( struct pdb_methods * m ,
const DOM_SID * alias ,
const DOM_SID * member )
{
2009-06-08 22:37:50 +04:00
return pdb_ads_mod_aliasmem ( m , alias , member , TLDAP_MOD_DELETE ) ;
2009-06-06 13:25:02 +04:00
}
2009-06-28 17:30:08 +04:00
static bool pdb_ads_dnblob2sid ( struct pdb_ads_state * state , DATA_BLOB * dnblob ,
2009-06-08 22:04:49 +04:00
struct dom_sid * psid )
{
const char * attrs [ 1 ] = { " objectSid " } ;
struct tldap_message * * msg ;
char * dn ;
size_t len ;
int rc ;
bool ret ;
if ( ! convert_string_talloc ( talloc_tos ( ) , CH_UTF8 , CH_UNIX ,
dnblob - > data , dnblob - > length , & dn , & len ,
false ) ) {
return false ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , dn , TLDAP_SCOPE_BASE ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " (objectclass=*) " ) ;
2009-06-08 22:04:49 +04:00
TALLOC_FREE ( dn ) ;
if ( talloc_array_length ( msg ) ! = 1 ) {
DEBUG ( 10 , ( " Got %d objects, expected one \n " ,
( int ) talloc_array_length ( msg ) ) ) ;
TALLOC_FREE ( msg ) ;
return false ;
}
ret = tldap_pull_binsid ( msg [ 0 ] , " objectSid " , psid ) ;
TALLOC_FREE ( msg ) ;
return ret ;
}
2009-06-06 13:25:02 +04:00
static NTSTATUS pdb_ads_enum_aliasmem ( struct pdb_methods * m ,
2009-06-08 22:04:49 +04:00
const DOM_SID * alias ,
TALLOC_CTX * mem_ctx ,
DOM_SID * * pmembers ,
size_t * pnum_members )
2009-06-06 13:25:02 +04:00
{
2009-06-08 22:04:49 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
const char * attrs [ 1 ] = { " member " } ;
char * sidstr ;
struct tldap_message * * msg ;
int i , rc , num_members ;
DATA_BLOB * blobs ;
struct dom_sid * members ;
sidstr = sid_binstring ( talloc_tos ( ) , alias ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " (objectsid=%s) " , sidstr ) ;
2009-06-08 22:04:49 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
switch talloc_array_length ( msg ) {
case 0 :
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
break ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
break ;
}
if ( ! tldap_entry_values ( msg [ 0 ] , " member " , & num_members , & blobs ) ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
members = talloc_array ( mem_ctx , struct dom_sid , num_members ) ;
if ( members = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_members ; i + + ) {
2009-06-28 17:30:08 +04:00
if ( ! pdb_ads_dnblob2sid ( state , & blobs [ i ] , & members [ i ] ) ) {
2009-06-08 22:04:49 +04:00
TALLOC_FREE ( members ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
* pmembers = members ;
* pnum_members = num_members ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_enum_alias_memberships ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * domain_sid ,
const DOM_SID * members ,
size_t num_members ,
2009-06-11 20:03:11 +04:00
uint32_t * * palias_rids ,
size_t * pnum_alias_rids )
2009-06-06 13:25:02 +04:00
{
2009-06-11 20:03:11 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
const char * attrs [ 1 ] = { " objectSid " } ;
struct tldap_message * * msg ;
uint32_t * alias_rids = NULL ;
size_t num_alias_rids = 0 ;
int i , rc , count ;
bool got_members = false ;
char * filter ;
NTSTATUS status ;
/*
* TODO : Get the filter right so that we only get the aliases from
* either the SAM or BUILTIN
*/
filter = talloc_asprintf ( talloc_tos ( ) ,
" (&(|(grouptype=%d)(grouptype=%d)) "
" (objectclass=group)(| " ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_members ; i + + ) {
char * dn ;
status = pdb_ads_sid2dn ( state , & members [ i ] , talloc_tos ( ) , & dn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_sid2dn failed for %s: %s \n " ,
sid_string_dbg ( & members [ i ] ) ,
nt_errstr ( status ) ) ) ;
continue ;
}
filter = talloc_asprintf_append_buffer (
filter , " (member=%s) " , dn ) ;
TALLOC_FREE ( dn ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
got_members = true ;
}
if ( ! got_members ) {
goto done ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn , TLDAP_SCOPE_SUB ,
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " %s)) " , filter ) ;
2009-06-11 20:03:11 +04:00
TALLOC_FREE ( filter ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " tldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return NT_STATUS_LDAP ( rc ) ;
}
count = talloc_array_length ( msg ) ;
if ( count = = 0 ) {
goto done ;
}
alias_rids = talloc_array ( mem_ctx , uint32_t , count ) ;
if ( alias_rids = = NULL ) {
TALLOC_FREE ( msg ) ;
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
struct dom_sid sid ;
if ( ! tldap_pull_binsid ( msg [ i ] , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not pull SID for member %d \n " , i ) ) ;
continue ;
}
if ( sid_peek_check_rid ( domain_sid , & sid ,
& alias_rids [ num_alias_rids ] ) ) {
num_alias_rids + = 1 ;
}
}
done :
TALLOC_FREE ( msg ) ;
* palias_rids = alias_rids ;
* pnum_alias_rids = 0 ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_lookup_rids ( struct pdb_methods * m ,
const DOM_SID * domain_sid ,
int num_rids ,
uint32 * rids ,
2009-06-10 14:54:05 +04:00
const char * * names ,
enum lsa_SidType * lsa_attrs )
2009-06-06 13:25:02 +04:00
{
2009-06-10 14:54:05 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
const char * attrs [ 2 ] = { " sAMAccountType " , " sAMAccountName " } ;
int i , num_mapped ;
if ( num_rids = = 0 ) {
return NT_STATUS_NONE_MAPPED ;
}
num_mapped = 0 ;
for ( i = 0 ; i < num_rids ; i + + ) {
struct dom_sid sid ;
struct tldap_message * * msg ;
char * sidstr ;
uint32_t attr ;
int rc ;
lsa_attrs [ i ] = SID_NAME_UNKNOWN ;
sid_compose ( & sid , domain_sid , rids [ i ] ) ;
sidstr = sid_binstring ( talloc_tos ( ) , & sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt ( state , state - > domaindn ,
TLDAP_SCOPE_SUB , attrs ,
ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) ,
& msg , " (objectsid=%s) " , sidstr ) ;
2009-06-10 14:54:05 +04:00
TALLOC_FREE ( sidstr ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search failed %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
continue ;
}
switch talloc_array_length ( msg ) {
case 0 :
DEBUG ( 10 , ( " rid %d not found \n " , ( int ) rids [ i ] ) ) ;
continue ;
case 1 :
break ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
names [ i ] = tldap_talloc_single_attribute (
msg [ 0 ] , " samAccountName " , talloc_tos ( ) ) ;
if ( names [ i ] = = NULL ) {
DEBUG ( 10 , ( " no samAccountName \n " ) ) ;
continue ;
}
if ( ! tldap_pull_uint32 ( msg [ 0 ] , " samAccountType " , & attr ) ) {
DEBUG ( 10 , ( " no samAccountType " ) ) ;
continue ;
}
2009-06-12 17:20:48 +04:00
lsa_attrs [ i ] = ds_atype_map ( attr ) ;
2009-06-10 14:54:05 +04:00
num_mapped + = 1 ;
}
if ( num_mapped = = 0 ) {
return NT_STATUS_NONE_MAPPED ;
}
if ( num_mapped < num_rids ) {
return STATUS_SOME_UNMAPPED ;
}
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static NTSTATUS pdb_ads_lookup_names ( struct pdb_methods * m ,
const DOM_SID * domain_sid ,
int num_names ,
const char * * pp_names ,
uint32 * rids ,
enum lsa_SidType * attrs )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
static NTSTATUS pdb_ads_get_account_policy ( struct pdb_methods * m ,
2009-07-14 01:53:49 +04:00
enum pdb_policy_type type ,
uint32_t * value )
2009-06-06 13:25:02 +04:00
{
2009-07-14 01:53:49 +04:00
return account_policy_get ( type , value )
2009-06-06 13:25:02 +04:00
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS pdb_ads_set_account_policy ( struct pdb_methods * m ,
2009-07-14 01:53:49 +04:00
enum pdb_policy_type type ,
uint32_t value )
2009-06-06 13:25:02 +04:00
{
2009-07-14 01:53:49 +04:00
return account_policy_set ( type , value )
2009-06-06 13:25:02 +04:00
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS pdb_ads_get_seq_num ( struct pdb_methods * m ,
time_t * seq_num )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
struct pdb_ads_search_state {
uint32_t acct_flags ;
struct samr_displayentry * entries ;
uint32_t num_entries ;
ssize_t array_size ;
uint32_t current ;
} ;
static bool pdb_ads_next_entry ( struct pdb_search * search ,
struct samr_displayentry * entry )
{
struct pdb_ads_search_state * state = talloc_get_type_abort (
search - > private_data , struct pdb_ads_search_state ) ;
if ( state - > current = = state - > num_entries ) {
return false ;
}
entry - > idx = state - > entries [ state - > current ] . idx ;
entry - > rid = state - > entries [ state - > current ] . rid ;
entry - > acct_flags = state - > entries [ state - > current ] . acct_flags ;
entry - > account_name = talloc_strdup (
search , state - > entries [ state - > current ] . account_name ) ;
entry - > fullname = talloc_strdup (
search , state - > entries [ state - > current ] . fullname ) ;
entry - > description = talloc_strdup (
search , state - > entries [ state - > current ] . description ) ;
if ( ( entry - > account_name = = NULL ) | | ( entry - > fullname = = NULL )
| | ( entry - > description = = NULL ) ) {
DEBUG ( 0 , ( " talloc_strdup failed \n " ) ) ;
return false ;
}
state - > current + = 1 ;
return true ;
}
static void pdb_ads_search_end ( struct pdb_search * search )
{
struct pdb_ads_search_state * state = talloc_get_type_abort (
search - > private_data , struct pdb_ads_search_state ) ;
TALLOC_FREE ( state ) ;
}
2009-06-07 14:30:26 +04:00
static bool pdb_ads_search_filter ( struct pdb_methods * m ,
struct pdb_search * search ,
const char * filter ,
struct pdb_ads_search_state * * pstate )
2009-06-06 13:25:02 +04:00
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
struct pdb_ads_search_state * sstate ;
2009-06-07 14:04:56 +04:00
const char * attrs [ ] = { " objectSid " , " sAMAccountName " , " displayName " ,
" userAccountControl " , " description " } ;
2009-06-06 13:25:02 +04:00
struct tldap_message * * users ;
int i , rc , num_users ;
sstate = talloc_zero ( search , struct pdb_ads_search_state ) ;
if ( sstate = = NULL ) {
return false ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
attrs , ARRAY_SIZE ( attrs ) , 0 , talloc_tos ( ) , & users ,
2009-06-07 14:30:26 +04:00
" %s " , filter ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " ldap_search_ext_s failed: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
return false ;
}
num_users = talloc_array_length ( users ) ;
sstate - > entries = talloc_array ( sstate , struct samr_displayentry ,
num_users ) ;
if ( sstate - > entries = = NULL ) {
DEBUG ( 10 , ( " talloc failed \n " ) ) ;
return false ;
}
sstate - > num_entries = 0 ;
for ( i = 0 ; i < num_users ; i + + ) {
struct samr_displayentry * e ;
struct dom_sid sid ;
e = & sstate - > entries [ sstate - > num_entries ] ;
e - > idx = sstate - > num_entries ;
if ( ! tldap_pull_binsid ( users [ i ] , " objectSid " , & sid ) ) {
DEBUG ( 10 , ( " Could not pull sid \n " ) ) ;
continue ;
}
sid_peek_rid ( & sid , & e - > rid ) ;
e - > acct_flags = ACB_NORMAL ;
2009-06-07 14:04:56 +04:00
e - > account_name = tldap_talloc_single_attribute (
users [ i ] , " samAccountName " , sstate - > entries ) ;
if ( e - > account_name = = NULL ) {
return false ;
}
e - > fullname = tldap_talloc_single_attribute (
users [ i ] , " displayName " , sstate - > entries ) ;
if ( e - > fullname = = NULL ) {
e - > fullname = " " ;
}
e - > description = tldap_talloc_single_attribute (
users [ i ] , " description " , sstate - > entries ) ;
if ( e - > description = = NULL ) {
e - > description = " " ;
}
2009-06-06 13:25:02 +04:00
sstate - > num_entries + = 1 ;
if ( sstate - > num_entries > = num_users ) {
break ;
}
}
search - > private_data = sstate ;
search - > next_entry = pdb_ads_next_entry ;
search - > search_end = pdb_ads_search_end ;
2009-06-07 14:30:26 +04:00
* pstate = sstate ;
return true ;
}
static bool pdb_ads_search_users ( struct pdb_methods * m ,
struct pdb_search * search ,
uint32 acct_flags )
{
struct pdb_ads_search_state * sstate ;
bool ret ;
ret = pdb_ads_search_filter ( m , search , " (objectclass=user) " , & sstate ) ;
if ( ! ret ) {
return false ;
}
sstate - > acct_flags = acct_flags ;
2009-06-06 13:25:02 +04:00
return true ;
}
static bool pdb_ads_search_groups ( struct pdb_methods * m ,
struct pdb_search * search )
{
2009-06-07 14:30:26 +04:00
struct pdb_ads_search_state * sstate ;
char * filter ;
bool ret ;
filter = talloc_asprintf ( talloc_tos ( ) ,
" (&(grouptype=%d)(objectclass=group)) " ,
GTYPE_SECURITY_GLOBAL_GROUP ) ;
if ( filter = = NULL ) {
return false ;
}
ret = pdb_ads_search_filter ( m , search , filter , & sstate ) ;
TALLOC_FREE ( filter ) ;
if ( ! ret ) {
return false ;
}
sstate - > acct_flags = 0 ;
return true ;
2009-06-06 13:25:02 +04:00
}
static bool pdb_ads_search_aliases ( struct pdb_methods * m ,
struct pdb_search * search ,
const DOM_SID * sid )
{
2009-06-07 14:30:26 +04:00
struct pdb_ads_search_state * sstate ;
char * filter ;
bool ret ;
filter = talloc_asprintf (
talloc_tos ( ) , " (&(grouptype=%d)(objectclass=group)) " ,
sid_check_is_builtin ( sid )
? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
: GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
if ( filter = = NULL ) {
return false ;
}
ret = pdb_ads_search_filter ( m , search , filter , & sstate ) ;
TALLOC_FREE ( filter ) ;
if ( ! ret ) {
return false ;
}
sstate - > acct_flags = 0 ;
return true ;
2009-06-06 13:25:02 +04:00
}
static bool pdb_ads_uid_to_rid ( struct pdb_methods * m , uid_t uid ,
uint32 * rid )
{
return false ;
}
static bool pdb_ads_uid_to_sid ( struct pdb_methods * m , uid_t uid ,
DOM_SID * sid )
{
2009-06-07 21:09:41 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
sid_compose ( sid , & state - > domainsid , uid ) ;
return true ;
2009-06-06 13:25:02 +04:00
}
static bool pdb_ads_gid_to_sid ( struct pdb_methods * m , gid_t gid ,
DOM_SID * sid )
{
2009-06-07 21:09:41 +04:00
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
sid_compose ( sid , & state - > domainsid , gid ) ;
return true ;
2009-06-06 13:25:02 +04:00
}
static bool pdb_ads_sid_to_id ( struct pdb_methods * m , const DOM_SID * sid ,
union unid_t * id , enum lsa_SidType * type )
{
struct pdb_ads_state * state = talloc_get_type_abort (
m - > private_data , struct pdb_ads_state ) ;
struct tldap_message * * msg ;
char * sidstr ;
uint32_t rid ;
int rc ;
/*
* This is a big , big hack : Just hard - code the rid as uid / gid .
*/
sid_peek_rid ( sid , & rid ) ;
sidstr = sid_binstring ( talloc_tos ( ) , sid ) ;
if ( sidstr = = NULL ) {
return false ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
NULL , 0 , 0 , talloc_tos ( ) , & msg ,
" (&(objectsid=%s)(objectclass=user)) " , sidstr ) ;
if ( ( rc = = TLDAP_SUCCESS ) & & ( talloc_array_length ( msg ) > 0 ) ) {
id - > uid = rid ;
* type = SID_NAME_USER ;
TALLOC_FREE ( sidstr ) ;
return true ;
}
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
NULL , 0 , 0 , talloc_tos ( ) , & msg ,
" (&(objectsid=%s)(objectclass=group)) " , sidstr ) ;
if ( ( rc = = TLDAP_SUCCESS ) & & ( talloc_array_length ( msg ) > 0 ) ) {
id - > gid = rid ;
* type = SID_NAME_DOM_GRP ;
TALLOC_FREE ( sidstr ) ;
return true ;
}
TALLOC_FREE ( sidstr ) ;
return false ;
}
2009-06-28 19:36:12 +04:00
static uint32_t pdb_ads_capabilities ( struct pdb_methods * m )
2009-06-06 13:25:02 +04:00
{
2009-06-28 19:43:48 +04:00
return PDB_CAP_STORE_RIDS | PDB_CAP_ADS ;
2009-06-06 13:25:02 +04:00
}
static bool pdb_ads_new_rid ( struct pdb_methods * m , uint32 * rid )
{
return false ;
}
static bool pdb_ads_get_trusteddom_pw ( struct pdb_methods * m ,
const char * domain , char * * pwd ,
DOM_SID * sid ,
time_t * pass_last_set_time )
{
return false ;
}
static bool pdb_ads_set_trusteddom_pw ( struct pdb_methods * m ,
const char * domain , const char * pwd ,
const DOM_SID * sid )
{
return false ;
}
static bool pdb_ads_del_trusteddom_pw ( struct pdb_methods * m ,
const char * domain )
{
return false ;
}
static NTSTATUS pdb_ads_enum_trusteddoms ( struct pdb_methods * m ,
TALLOC_CTX * mem_ctx ,
uint32 * num_domains ,
struct trustdom_info * * * domains )
{
2009-07-09 17:58:10 +04:00
* num_domains = 0 ;
* domains = NULL ;
return NT_STATUS_OK ;
2009-06-06 13:25:02 +04:00
}
static void pdb_ads_init_methods ( struct pdb_methods * m )
{
m - > name = " ads " ;
2009-07-04 13:12:33 +04:00
m - > get_domain_info = pdb_ads_get_domain_info ;
2009-06-06 13:25:02 +04:00
m - > getsampwnam = pdb_ads_getsampwnam ;
m - > getsampwsid = pdb_ads_getsampwsid ;
m - > create_user = pdb_ads_create_user ;
m - > delete_user = pdb_ads_delete_user ;
m - > add_sam_account = pdb_ads_add_sam_account ;
m - > update_sam_account = pdb_ads_update_sam_account ;
m - > delete_sam_account = pdb_ads_delete_sam_account ;
m - > rename_sam_account = pdb_ads_rename_sam_account ;
m - > update_login_attempts = pdb_ads_update_login_attempts ;
m - > getgrsid = pdb_ads_getgrsid ;
m - > getgrgid = pdb_ads_getgrgid ;
m - > getgrnam = pdb_ads_getgrnam ;
m - > create_dom_group = pdb_ads_create_dom_group ;
m - > delete_dom_group = pdb_ads_delete_dom_group ;
m - > add_group_mapping_entry = pdb_ads_add_group_mapping_entry ;
m - > update_group_mapping_entry = pdb_ads_update_group_mapping_entry ;
m - > delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry ;
m - > enum_group_mapping = pdb_ads_enum_group_mapping ;
m - > enum_group_members = pdb_ads_enum_group_members ;
m - > enum_group_memberships = pdb_ads_enum_group_memberships ;
m - > set_unix_primary_group = pdb_ads_set_unix_primary_group ;
m - > add_groupmem = pdb_ads_add_groupmem ;
m - > del_groupmem = pdb_ads_del_groupmem ;
m - > create_alias = pdb_ads_create_alias ;
m - > delete_alias = pdb_ads_delete_alias ;
2009-06-11 01:56:20 +04:00
m - > get_aliasinfo = pdb_default_get_aliasinfo ;
2009-06-06 13:25:02 +04:00
m - > set_aliasinfo = pdb_ads_set_aliasinfo ;
m - > add_aliasmem = pdb_ads_add_aliasmem ;
m - > del_aliasmem = pdb_ads_del_aliasmem ;
m - > enum_aliasmem = pdb_ads_enum_aliasmem ;
m - > enum_alias_memberships = pdb_ads_enum_alias_memberships ;
m - > lookup_rids = pdb_ads_lookup_rids ;
m - > lookup_names = pdb_ads_lookup_names ;
m - > get_account_policy = pdb_ads_get_account_policy ;
m - > set_account_policy = pdb_ads_set_account_policy ;
m - > get_seq_num = pdb_ads_get_seq_num ;
m - > search_users = pdb_ads_search_users ;
m - > search_groups = pdb_ads_search_groups ;
m - > search_aliases = pdb_ads_search_aliases ;
m - > uid_to_rid = pdb_ads_uid_to_rid ;
m - > uid_to_sid = pdb_ads_uid_to_sid ;
m - > gid_to_sid = pdb_ads_gid_to_sid ;
m - > sid_to_id = pdb_ads_sid_to_id ;
2009-06-28 19:36:12 +04:00
m - > capabilities = pdb_ads_capabilities ;
2009-06-06 13:25:02 +04:00
m - > new_rid = pdb_ads_new_rid ;
m - > get_trusteddom_pw = pdb_ads_get_trusteddom_pw ;
m - > set_trusteddom_pw = pdb_ads_set_trusteddom_pw ;
m - > del_trusteddom_pw = pdb_ads_del_trusteddom_pw ;
m - > enum_trusteddoms = pdb_ads_enum_trusteddoms ;
}
static void free_private_data ( void * * vp )
{
struct pdb_ads_state * state = talloc_get_type_abort (
* vp , struct pdb_ads_state ) ;
TALLOC_FREE ( state - > ld ) ;
return ;
}
2009-06-12 17:02:01 +04:00
/*
this is used to catch debug messages from events
*/
static void s3_tldap_debug ( void * context , enum tldap_debug_level level ,
const char * fmt , va_list ap ) PRINTF_ATTRIBUTE ( 3 , 0 ) ;
static void s3_tldap_debug ( void * context , enum tldap_debug_level level ,
const char * fmt , va_list ap )
{
int samba_level = - 1 ;
char * s = NULL ;
switch ( level ) {
case TLDAP_DEBUG_FATAL :
samba_level = 0 ;
break ;
case TLDAP_DEBUG_ERROR :
samba_level = 1 ;
break ;
case TLDAP_DEBUG_WARNING :
samba_level = 2 ;
break ;
case TLDAP_DEBUG_TRACE :
2009-07-05 16:39:16 +04:00
samba_level = 11 ;
2009-06-12 17:02:01 +04:00
break ;
} ;
if ( vasprintf ( & s , fmt , ap ) = = - 1 ) {
return ;
}
DEBUG ( samba_level , ( " tldap: %s " , s ) ) ;
free ( s ) ;
}
2009-06-28 17:30:08 +04:00
static struct tldap_context * pdb_ads_ld ( struct pdb_ads_state * state )
2009-06-06 13:25:02 +04:00
{
NTSTATUS status ;
2009-06-28 17:30:08 +04:00
int fd ;
2009-06-06 13:25:02 +04:00
2009-06-28 17:30:08 +04:00
if ( tldap_connection_ok ( state - > ld ) ) {
return state - > ld ;
}
TALLOC_FREE ( state - > ld ) ;
2009-06-06 13:25:02 +04:00
2009-06-28 17:30:08 +04:00
status = open_socket_out (
( struct sockaddr_storage * ) ( void * ) & state - > socket_address ,
0 , 0 , & fd ) ;
2009-06-06 13:25:02 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-06-28 17:30:08 +04:00
DEBUG ( 10 , ( " Could not connect to %s: %s \n " ,
state - > socket_address . sun_path , nt_errstr ( status ) ) ) ;
return NULL ;
2009-06-06 13:25:02 +04:00
}
2009-06-29 18:31:31 +04:00
set_blocking ( fd , false ) ;
2009-06-06 13:25:02 +04:00
state - > ld = tldap_context_create ( state , fd ) ;
if ( state - > ld = = NULL ) {
close ( fd ) ;
2009-06-28 17:30:08 +04:00
return NULL ;
2009-06-06 13:25:02 +04:00
}
2009-06-12 17:02:01 +04:00
tldap_set_debug ( state - > ld , s3_tldap_debug , NULL ) ;
2009-06-06 13:25:02 +04:00
2009-06-28 17:30:08 +04:00
return state - > ld ;
}
int pdb_ads_search_fmt ( struct pdb_ads_state * state , const char * base ,
int scope , const char * attrs [ ] , int num_attrs ,
int attrsonly ,
TALLOC_CTX * mem_ctx , struct tldap_message * * * res ,
const char * fmt , . . . )
{
struct tldap_context * ld ;
va_list ap ;
int ret ;
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return TLDAP_SERVER_DOWN ;
}
va_start ( ap , fmt ) ;
ret = tldap_search_va ( ld , base , scope , attrs , num_attrs , attrsonly ,
mem_ctx , res , fmt , ap ) ;
va_end ( ap ) ;
if ( ret ! = TLDAP_SERVER_DOWN ) {
return ret ;
}
/* retry once */
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
return TLDAP_SERVER_DOWN ;
}
va_start ( ap , fmt ) ;
ret = tldap_search_va ( ld , base , scope , attrs , num_attrs , attrsonly ,
mem_ctx , res , fmt , ap ) ;
va_end ( ap ) ;
return ret ;
}
static NTSTATUS pdb_ads_connect ( struct pdb_ads_state * state ,
const char * location )
{
2009-06-30 00:28:19 +04:00
const char * domain_attrs [ 2 ] = { " objectSid " , " objectGUID " } ;
2009-06-28 17:30:08 +04:00
const char * ncname_attrs [ 1 ] = { " netbiosname " } ;
2009-06-30 12:39:04 +04:00
struct tldap_context * ld ;
struct tldap_message * rootdse , * * domain , * * ncname ;
2009-06-28 17:30:08 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
NTSTATUS status ;
int num_domains ;
int rc ;
ZERO_STRUCT ( state - > socket_address ) ;
state - > socket_address . sun_family = AF_UNIX ;
strncpy ( state - > socket_address . sun_path , location ,
sizeof ( state - > socket_address . sun_path ) - 1 ) ;
2009-06-30 12:39:04 +04:00
ld = pdb_ads_ld ( state ) ;
if ( ld = = NULL ) {
status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
goto done ;
}
rc = tldap_fetch_rootdse ( ld ) ;
2009-06-06 13:25:02 +04:00
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not retrieve rootdse: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
status = NT_STATUS_LDAP ( rc ) ;
goto done ;
}
2009-06-30 12:39:04 +04:00
rootdse = tldap_rootdse ( state - > ld ) ;
2009-06-06 13:25:02 +04:00
state - > domaindn = tldap_talloc_single_attribute (
2009-06-30 12:39:04 +04:00
rootdse , " defaultNamingContext " , state ) ;
2009-06-06 13:25:02 +04:00
if ( state - > domaindn = = NULL ) {
DEBUG ( 10 , ( " Could not get defaultNamingContext \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
DEBUG ( 10 , ( " defaultNamingContext = %s \n " , state - > domaindn ) ) ;
state - > configdn = tldap_talloc_single_attribute (
2009-06-30 12:39:04 +04:00
rootdse , " configurationNamingContext " , state ) ;
2009-06-06 13:25:02 +04:00
if ( state - > domaindn = = NULL ) {
DEBUG ( 10 , ( " Could not get configurationNamingContext \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
DEBUG ( 10 , ( " configurationNamingContext = %s \n " , state - > configdn ) ) ;
/*
* Figure out our domain ' s SID
*/
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > domaindn , TLDAP_SCOPE_BASE ,
2009-06-06 13:25:02 +04:00
domain_attrs , ARRAY_SIZE ( domain_attrs ) , 0 ,
talloc_tos ( ) , & domain , " (objectclass=*) " ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not retrieve domain: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
status = NT_STATUS_LDAP ( rc ) ;
goto done ;
}
num_domains = talloc_array_length ( domain ) ;
if ( num_domains ! = 1 ) {
DEBUG ( 10 , ( " Got %d domains, expected one \n " , num_domains ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
if ( ! tldap_pull_binsid ( domain [ 0 ] , " objectSid " , & state - > domainsid ) ) {
DEBUG ( 10 , ( " Could not retrieve domain SID \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
2009-06-30 00:28:19 +04:00
if ( ! tldap_pull_guid ( domain [ 0 ] , " objectGUID " , & state - > domainguid ) ) {
DEBUG ( 10 , ( " Could not retrieve domain GUID \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
2009-06-06 13:25:02 +04:00
DEBUG ( 10 , ( " Domain SID: %s \n " , sid_string_dbg ( & state - > domainsid ) ) ) ;
/*
* Figure out our domain ' s short name
*/
2009-06-28 17:30:08 +04:00
rc = pdb_ads_search_fmt (
state , state - > configdn , TLDAP_SCOPE_SUB ,
2009-06-06 13:25:02 +04:00
ncname_attrs , ARRAY_SIZE ( ncname_attrs ) , 0 ,
talloc_tos ( ) , & ncname , " (ncname=%s) " , state - > domaindn ) ;
if ( rc ! = TLDAP_SUCCESS ) {
DEBUG ( 10 , ( " Could not retrieve ncname: %s \n " ,
tldap_errstr ( debug_ctx ( ) , state - > ld , rc ) ) ) ;
status = NT_STATUS_LDAP ( rc ) ;
goto done ;
}
if ( talloc_array_length ( ncname ) ! = 1 ) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
state - > netbiosname = tldap_talloc_single_attribute (
ncname [ 0 ] , " netbiosname " , state ) ;
if ( state - > netbiosname = = NULL ) {
DEBUG ( 10 , ( " Could not get netbiosname \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto done ;
}
DEBUG ( 10 , ( " netbiosname: %s \n " , state - > netbiosname ) ) ;
if ( ! strequal ( lp_workgroup ( ) , state - > netbiosname ) ) {
DEBUG ( 1 , ( " ADS is different domain (%s) than ours (%s) \n " ,
state - > netbiosname , lp_workgroup ( ) ) ) ;
status = NT_STATUS_NO_SUCH_DOMAIN ;
goto done ;
}
secrets_store_domain_sid ( state - > netbiosname , & state - > domainsid ) ;
status = NT_STATUS_OK ;
done :
TALLOC_FREE ( frame ) ;
return status ;
}
static NTSTATUS pdb_init_ads ( struct pdb_methods * * pdb_method ,
const char * location )
{
struct pdb_methods * m ;
struct pdb_ads_state * state ;
char * tmp = NULL ;
NTSTATUS status ;
m = talloc ( talloc_autofree_context ( ) , struct pdb_methods ) ;
if ( m = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-06-28 17:30:08 +04:00
state = talloc_zero ( m , struct pdb_ads_state ) ;
2009-06-06 13:25:02 +04:00
if ( state = = NULL ) {
goto nomem ;
}
m - > private_data = state ;
m - > free_private_data = free_private_data ;
pdb_ads_init_methods ( m ) ;
if ( location = = NULL ) {
tmp = talloc_asprintf ( talloc_tos ( ) , " /%s/ldap_priv/ldapi " ,
lp_private_dir ( ) ) ;
location = tmp ;
}
if ( location = = NULL ) {
goto nomem ;
}
status = pdb_ads_connect ( state , location ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " pdb_ads_connect failed: %s \n " , nt_errstr ( status ) ) ) ;
goto fail ;
}
* pdb_method = m ;
return NT_STATUS_OK ;
nomem :
status = NT_STATUS_NO_MEMORY ;
fail :
TALLOC_FREE ( m ) ;
return status ;
}
NTSTATUS pdb_ads_init ( void ) ;
NTSTATUS pdb_ads_init ( void )
{
return smb_register_passdb ( PASSDB_INTERFACE_VERSION , " ads " ,
pdb_init_ads ) ;
}