2001-12-03 09:04:18 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-12-03 09:04:18 +03:00
Winbind ADS backend functions
Copyright ( C ) Andrew Tridgell 2001
2003-04-23 15:54:56 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2003
2001-12-03 09:04:18 +03: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 .
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2001-12-03 09:04:18 +03:00
# include "winbindd.h"
# ifdef HAVE_ADS
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2001-12-05 10:05:53 +03:00
/*
return our ads connections structure for a domain . We keep the connection
open to make things faster
*/
static ADS_STRUCT * ads_cached_connection ( struct winbindd_domain * domain )
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS status ;
2001-12-05 10:05:53 +03:00
if ( domain - > private ) {
return ( ADS_STRUCT * ) domain - > private ;
}
2001-12-11 01:10:16 +03:00
/* we don't want this to affect the users ccache */
2003-02-20 01:50:05 +03:00
setenv ( " KRB5CCNAME " , " MEMORY:winbind_ccache " , 1 ) ;
2001-12-11 01:10:16 +03:00
2002-08-17 21:00:51 +04:00
ads = ads_init ( domain - > alt_name , domain - > name , NULL ) ;
2001-12-05 10:05:53 +03:00
if ( ! ads ) {
DEBUG ( 1 , ( " ads_init for domain %s failed \n " , domain - > name ) ) ;
return NULL ;
}
2001-12-08 14:18:56 +03:00
/* the machine acct password might have change - fetch it every time */
2002-08-17 21:00:51 +04:00
SAFE_FREE ( ads - > auth . password ) ;
2003-04-21 18:09:03 +04:00
ads - > auth . password = secrets_fetch_machine_password ( lp_workgroup ( ) , NULL , NULL ) ;
2002-08-17 21:00:51 +04:00
2003-09-04 23:45:04 +04:00
SAFE_FREE ( ads - > auth . realm ) ;
ads - > auth . realm = strdup ( lp_realm ( ) ) ;
2001-12-08 14:18:56 +03:00
2001-12-19 15:21:12 +03:00
status = ads_connect ( ads ) ;
2002-08-17 21:00:51 +04:00
if ( ! ADS_ERR_OK ( status ) | | ! ads - > config . realm ) {
2003-06-10 07:50:38 +04:00
extern struct winbindd_methods msrpc_methods , cache_methods ;
2001-12-19 15:21:12 +03:00
DEBUG ( 1 , ( " ads_connect for domain %s failed: %s \n " ,
domain - > name , ads_errstr ( status ) ) ) ;
2001-12-05 10:05:53 +03:00
ads_destroy ( & ads ) ;
2001-12-19 15:38:52 +03:00
/* if we get ECONNREFUSED then it might be a NT4
server , fall back to MSRPC */
if ( status . error_type = = ADS_ERROR_SYSTEM & &
2002-09-25 19:19:00 +04:00
status . err . rc = = ECONNREFUSED ) {
2001-12-19 15:38:52 +03:00
DEBUG ( 1 , ( " Trying MSRPC methods \n " ) ) ;
2003-06-10 07:50:38 +04:00
if ( domain - > methods = = & cache_methods ) {
domain - > backend = & msrpc_methods ;
} else {
domain - > methods = & msrpc_methods ;
}
2001-12-19 15:38:52 +03:00
}
2001-12-05 10:05:53 +03:00
return NULL ;
}
domain - > private = ( void * ) ads ;
return ads ;
}
2002-07-15 14:35:28 +04:00
2001-12-03 09:04:18 +03:00
/* Query display info for a realm. This is the basic user list fn */
2001-12-03 14:32:55 +03:00
static NTSTATUS query_user_list ( struct winbindd_domain * domain ,
2001-12-03 09:04:18 +03:00
TALLOC_CTX * mem_ctx ,
2001-12-11 03:03:58 +03:00
uint32 * num_entries ,
2001-12-03 14:32:55 +03:00
WINBIND_USERINFO * * info )
2001-12-03 09:04:18 +03:00
{
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2002-07-15 14:35:28 +04:00
const char * attrs [ ] = { " userPrincipalName " ,
" sAMAccountName " ,
" name " , " objectSid " , " primaryGroupID " ,
2001-12-09 09:10:02 +03:00
" sAMAccountType " , NULL } ;
2001-12-19 15:21:12 +03:00
int i , count ;
ADS_STATUS rc ;
2001-12-05 09:16:33 +03:00
void * res = NULL ;
void * msg = NULL ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2003-09-06 22:02:19 +04:00
2001-12-11 01:10:16 +03:00
* num_entries = 0 ;
2001-12-03 14:32:55 +03:00
DEBUG ( 3 , ( " ads: query_user_list \n " ) ) ;
2001-12-03 09:04:18 +03:00
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2001-12-03 09:04:18 +03:00
2003-09-06 22:02:19 +04:00
rc = ads_search_retry ( ads , & res , " (objectCategory=user) " , attrs ) ;
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! res ) {
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " query_user_list ads_search: %s \n " , ads_errstr ( rc ) ) ) ;
2003-09-05 08:46:44 +04:00
goto done ;
2003-09-06 22:02:19 +04:00
}
2001-12-03 09:04:18 +03:00
count = ads_count_replies ( ads , res ) ;
if ( count = = 0 ) {
2001-12-03 14:32:55 +03:00
DEBUG ( 1 , ( " query_user_list: No users found \n " ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-03 09:04:18 +03:00
}
2002-04-11 18:30:31 +04:00
( * info ) = talloc_zero ( mem_ctx , count * sizeof ( * * info ) ) ;
2001-12-05 09:16:33 +03:00
if ( ! * info ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2001-12-03 09:04:18 +03:00
i = 0 ;
for ( msg = ads_first_entry ( ads , res ) ; msg ; msg = ads_next_entry ( ads , msg ) ) {
char * name , * gecos ;
DOM_SID sid ;
2003-04-23 15:54:56 +04:00
DOM_SID * sid2 ;
DOM_SID * group_sid ;
uint32 group ;
2001-12-09 09:10:02 +03:00
uint32 atype ;
2001-12-03 09:04:18 +03:00
2001-12-09 09:10:02 +03:00
if ( ! ads_pull_uint32 ( ads , msg , " sAMAccountType " , & atype ) | |
ads_atype_map ( atype ) ! = SID_NAME_USER ) {
DEBUG ( 1 , ( " Not a user account? atype=0x%x \n " , atype ) ) ;
continue ;
}
2001-12-03 09:04:18 +03:00
2002-10-01 22:26:00 +04:00
name = ads_pull_username ( ads , mem_ctx , msg ) ;
2001-12-03 09:04:18 +03:00
gecos = ads_pull_string ( ads , mem_ctx , msg , " name " ) ;
if ( ! ads_pull_sid ( ads , msg , " objectSid " , & sid ) ) {
DEBUG ( 1 , ( " No sid for %s !? \n " , name ) ) ;
continue ;
}
if ( ! ads_pull_uint32 ( ads , msg , " primaryGroupID " , & group ) ) {
DEBUG ( 1 , ( " No primary group for %s !? \n " , name ) ) ;
continue ;
}
2003-04-23 15:54:56 +04:00
sid2 = talloc ( mem_ctx , sizeof ( * sid2 ) ) ;
if ( ! sid2 ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
2001-12-03 09:04:18 +03:00
}
2003-04-23 15:54:56 +04:00
sid_copy ( sid2 , & sid ) ;
group_sid = rid_to_talloced_sid ( domain , mem_ctx , group ) ;
2001-12-03 09:04:18 +03:00
( * info ) [ i ] . acct_name = name ;
( * info ) [ i ] . full_name = gecos ;
2003-04-23 15:54:56 +04:00
( * info ) [ i ] . user_sid = sid2 ;
( * info ) [ i ] . group_sid = group_sid ;
2001-12-03 09:04:18 +03:00
i + + ;
}
( * num_entries ) = i ;
2001-12-05 09:16:33 +03:00
status = NT_STATUS_OK ;
2001-12-03 09:04:18 +03:00
2001-12-09 09:10:02 +03:00
DEBUG ( 3 , ( " ads query_user_list gave %d entries \n " , ( * num_entries ) ) ) ;
2001-12-05 09:16:33 +03:00
done :
2003-09-05 08:46:44 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2001-12-03 09:04:18 +03:00
2001-12-05 09:16:33 +03:00
return status ;
2001-12-03 09:04:18 +03:00
}
/* list all domain groups */
static NTSTATUS enum_dom_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2001-12-11 04:04:13 +03:00
uint32 * num_entries ,
2001-12-03 09:04:18 +03:00
struct acct_info * * info )
{
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2002-07-15 14:35:28 +04:00
const char * attrs [ ] = { " userPrincipalName " , " sAMAccountName " ,
" name " , " objectSid " ,
2001-12-03 09:04:18 +03:00
" sAMAccountType " , NULL } ;
2001-12-19 15:21:12 +03:00
int i , count ;
ADS_STATUS rc ;
2001-12-05 09:16:33 +03:00
void * res = NULL ;
void * msg = NULL ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2002-11-15 20:57:21 +03:00
uint32 group_flags ;
2001-12-03 09:04:18 +03:00
2001-12-11 01:10:16 +03:00
* num_entries = 0 ;
2001-12-03 09:04:18 +03:00
DEBUG ( 3 , ( " ads: enum_dom_groups \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2001-12-03 09:04:18 +03:00
2003-09-06 22:02:19 +04:00
rc = ads_search_retry ( ads , & res , " (objectCategory=group) " , attrs ) ;
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! res ) {
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " enum_dom_groups ads_search: %s \n " , ads_errstr ( rc ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2003-09-06 22:02:19 +04:00
}
2001-12-03 09:04:18 +03:00
count = ads_count_replies ( ads , res ) ;
if ( count = = 0 ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 1 , ( " enum_dom_groups: No groups found \n " ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-03 09:04:18 +03:00
}
2002-04-11 18:30:31 +04:00
( * info ) = talloc_zero ( mem_ctx , count * sizeof ( * * info ) ) ;
2001-12-05 09:16:33 +03:00
if ( ! * info ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2001-12-03 09:04:18 +03:00
i = 0 ;
2002-11-15 20:57:21 +03:00
group_flags = ATYPE_GLOBAL_GROUP ;
2003-06-23 09:10:07 +04:00
/* only grab domain local groups for our domain */
if ( domain - > native_mode & & strequal ( lp_realm ( ) , domain - > alt_name ) )
2002-11-15 20:57:21 +03:00
group_flags | = ATYPE_LOCAL_GROUP ;
2001-12-03 09:04:18 +03:00
for ( msg = ads_first_entry ( ads , res ) ; msg ; msg = ads_next_entry ( ads , msg ) ) {
char * name , * gecos ;
DOM_SID sid ;
uint32 rid ;
uint32 account_type ;
2002-11-15 20:57:21 +03:00
if ( ! ads_pull_uint32 ( ads , msg , " sAMAccountType " , & account_type ) | | ! ( account_type & group_flags ) )
continue ;
2002-10-01 22:26:00 +04:00
name = ads_pull_username ( ads , mem_ctx , msg ) ;
2001-12-03 09:04:18 +03:00
gecos = ads_pull_string ( ads , mem_ctx , msg , " name " ) ;
if ( ! ads_pull_sid ( ads , msg , " objectSid " , & sid ) ) {
DEBUG ( 1 , ( " No sid for %s !? \n " , name ) ) ;
continue ;
}
2002-07-15 14:35:28 +04:00
if ( ! sid_peek_check_rid ( & domain - > sid , & sid , & rid ) ) {
2001-12-03 09:04:18 +03:00
DEBUG ( 1 , ( " No rid for %s !? \n " , name ) ) ;
continue ;
}
fstrcpy ( ( * info ) [ i ] . acct_name , name ) ;
fstrcpy ( ( * info ) [ i ] . acct_desc , gecos ) ;
( * info ) [ i ] . rid = rid ;
i + + ;
}
( * num_entries ) = i ;
2001-12-05 09:16:33 +03:00
status = NT_STATUS_OK ;
2001-12-09 09:10:02 +03:00
DEBUG ( 3 , ( " ads enum_dom_groups gave %d entries \n " , ( * num_entries ) ) ) ;
2001-12-05 09:16:33 +03:00
done :
2003-09-05 08:46:44 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2001-12-03 09:04:18 +03:00
2001-12-05 09:16:33 +03:00
return status ;
2001-12-03 09:04:18 +03:00
}
2002-11-15 20:57:21 +03:00
/* list all domain local groups */
static NTSTATUS enum_local_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_entries ,
struct acct_info * * info )
{
/*
* This is a stub function only as we returned the domain
2003-06-23 09:10:07 +04:00
* local groups in enum_dom_groups ( ) if the domain - > native field
2002-11-15 20:57:21 +03:00
* was true . This is a simple performance optimization when
* using LDAP .
*
* if we ever need to enumerate domain local groups separately ,
* then this the optimization in enum_dom_groups ( ) will need
* to be split out
*/
* num_entries = 0 ;
return NT_STATUS_OK ;
}
2001-12-03 11:17:46 +03:00
/* convert a single name to a sid in a domain */
static NTSTATUS name_to_sid ( struct winbindd_domain * domain ,
2003-04-23 15:54:56 +04:00
TALLOC_CTX * mem_ctx ,
2001-12-03 11:17:46 +03:00
const char * name ,
DOM_SID * sid ,
enum SID_NAME_USE * type )
{
2002-10-01 22:26:00 +04:00
ADS_STRUCT * ads ;
2001-12-05 09:16:33 +03:00
2001-12-03 11:17:46 +03:00
DEBUG ( 3 , ( " ads: name_to_sid \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
return NT_STATUS_UNSUCCESSFUL ;
}
return ads_name_to_sid ( ads , name , sid , type ) ;
2001-12-05 07:48:51 +03:00
}
/* convert a sid to a user or group name */
static NTSTATUS sid_to_name ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
DOM_SID * sid ,
char * * name ,
enum SID_NAME_USE * type )
{
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2001-12-05 07:48:51 +03:00
DEBUG ( 3 , ( " ads: sid_to_name \n " ) ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
return NT_STATUS_UNSUCCESSFUL ;
}
2001-12-05 07:48:51 +03:00
2003-09-06 22:02:19 +04:00
return ads_sid_to_name ( ads , mem_ctx , sid , name , type ) ;
2001-12-03 11:17:46 +03:00
}
2001-12-05 07:48:51 +03:00
2003-04-23 15:54:56 +04:00
/* convert a DN to a name, SID and name type
2002-07-15 14:35:28 +04:00
this might become a major speed bottleneck if groups have
lots of users , in which case we could cache the results
*/
static BOOL dn_lookup ( ADS_STRUCT * ads , TALLOC_CTX * mem_ctx ,
const char * dn ,
2003-04-23 15:54:56 +04:00
char * * name , uint32 * name_type , DOM_SID * sid )
2002-07-15 14:35:28 +04:00
{
2003-06-30 09:44:05 +04:00
char * ldap_exp ;
2002-07-15 14:35:28 +04:00
void * res = NULL ;
const char * attrs [ ] = { " userPrincipalName " , " sAMAccountName " ,
" objectSid " , " sAMAccountType " , NULL } ;
ADS_STATUS rc ;
uint32 atype ;
2003-02-20 01:50:05 +03:00
char * escaped_dn = escape_ldap_string_alloc ( dn ) ;
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: dn_lookup \n " ) ) ;
2003-02-20 01:50:05 +03:00
if ( ! escaped_dn ) {
return False ;
}
2002-07-15 14:35:28 +04:00
2003-10-13 18:03:06 +04:00
asprintf ( & ldap_exp , " (distinguishedName=%s) " , escaped_dn ) ;
2003-06-30 09:44:05 +04:00
rc = ads_search_retry ( ads , & res , ldap_exp , attrs ) ;
SAFE_FREE ( ldap_exp ) ;
2003-02-20 01:50:05 +03:00
SAFE_FREE ( escaped_dn ) ;
2003-09-05 09:57:24 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! res ) {
2002-07-15 14:35:28 +04:00
goto failed ;
}
2002-10-01 22:26:00 +04:00
( * name ) = ads_pull_username ( ads , mem_ctx , res ) ;
2002-07-15 14:35:28 +04:00
if ( ! ads_pull_uint32 ( ads , res , " sAMAccountType " , & atype ) ) {
goto failed ;
}
( * name_type ) = ads_atype_map ( atype ) ;
2003-04-23 15:54:56 +04:00
if ( ! ads_pull_sid ( ads , res , " objectSid " , sid ) ) {
2002-07-15 14:35:28 +04:00
goto failed ;
}
2003-09-06 22:02:19 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2002-07-15 14:35:28 +04:00
return True ;
failed :
2003-09-06 22:02:19 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2002-07-15 14:35:28 +04:00
return False ;
}
2001-12-05 07:48:51 +03:00
/* Lookup user information from a rid */
2001-12-04 09:17:39 +03:00
static NTSTATUS query_user ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * sid ,
2001-12-04 09:17:39 +03:00
WINBIND_USERINFO * info )
{
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2002-07-15 14:35:28 +04:00
const char * attrs [ ] = { " userPrincipalName " ,
" sAMAccountName " ,
2003-04-23 15:54:56 +04:00
" name " ,
2001-12-09 09:10:02 +03:00
" primaryGroupID " , NULL } ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
int count ;
2001-12-05 09:16:33 +03:00
void * msg = NULL ;
2003-06-30 09:44:05 +04:00
char * ldap_exp ;
2001-12-05 07:48:51 +03:00
char * sidstr ;
2003-04-23 15:54:56 +04:00
uint32 group_rid ;
2001-12-05 09:16:33 +03:00
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2003-04-23 15:54:56 +04:00
DOM_SID * sid2 ;
fstring sid_string ;
2001-12-04 09:17:39 +03:00
DEBUG ( 3 , ( " ads: query_user \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
sidstr = sid_binstring ( sid ) ;
asprintf ( & ldap_exp , " (objectSid=%s) " , sidstr ) ;
rc = ads_search_retry ( ads , & msg , ldap_exp , attrs ) ;
free ( ldap_exp ) ;
free ( sidstr ) ;
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! msg ) {
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " query_user(sid=%s) ads_search: %s \n " , sid_to_string ( sid_string , sid ) , ads_errstr ( rc ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2003-09-06 22:02:19 +04:00
}
2001-12-04 09:17:39 +03:00
count = ads_count_replies ( ads , msg ) ;
if ( count ! = 1 ) {
2003-04-23 15:54:56 +04:00
DEBUG ( 1 , ( " query_user(sid=%s): Not found \n " , sid_to_string ( sid_string , sid ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-04 09:17:39 +03:00
}
2002-10-01 22:26:00 +04:00
info - > acct_name = ads_pull_username ( ads , mem_ctx , msg ) ;
2001-12-04 09:17:39 +03:00
info - > full_name = ads_pull_string ( ads , mem_ctx , msg , " name " ) ;
2003-04-23 15:54:56 +04:00
if ( ! ads_pull_uint32 ( ads , msg , " primaryGroupID " , & group_rid ) ) {
DEBUG ( 1 , ( " No primary group for %s !? \n " , sid_to_string ( sid_string , sid ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-04 09:17:39 +03:00
}
2003-04-23 15:54:56 +04:00
sid2 = talloc ( mem_ctx , sizeof ( * sid2 ) ) ;
if ( ! sid2 ) {
status = NT_STATUS_NO_MEMORY ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-04 09:17:39 +03:00
}
2003-04-23 15:54:56 +04:00
sid_copy ( sid2 , sid ) ;
info - > user_sid = sid2 ;
info - > group_sid = rid_to_talloced_sid ( domain , mem_ctx , group_rid ) ;
2001-12-04 09:17:39 +03:00
2001-12-05 09:16:33 +03:00
status = NT_STATUS_OK ;
2001-12-09 09:10:02 +03:00
DEBUG ( 3 , ( " ads query_user gave %s \n " , info - > acct_name ) ) ;
2001-12-05 09:16:33 +03:00
done :
2003-09-05 08:46:44 +04:00
if ( msg )
ads_msgfree ( ads , msg ) ;
2001-12-04 09:17:39 +03:00
2001-12-05 09:16:33 +03:00
return status ;
2001-12-04 09:17:39 +03:00
}
2003-04-23 15:54:56 +04:00
/* Lookup groups a user is a member of - alternate method, for when
tokenGroups are not available . */
static NTSTATUS lookup_usergroups_alt ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const char * user_dn ,
DOM_SID * primary_group ,
uint32 * num_groups , DOM_SID * * * user_gids )
{
ADS_STATUS rc ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
int count ;
void * res = NULL ;
void * msg = NULL ;
2003-06-30 09:44:05 +04:00
char * ldap_exp ;
2003-04-23 15:54:56 +04:00
ADS_STRUCT * ads ;
const char * group_attrs [ ] = { " objectSid " , NULL } ;
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: lookup_usergroups_alt \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2003-04-23 15:54:56 +04:00
2003-09-06 22:02:19 +04:00
/* buggy server, no tokenGroups. Instead lookup what groups this user
is a member of by DN search on member */
if ( asprintf ( & ldap_exp , " (&(member=%s)(objectClass=group)) " , user_dn ) = = - 1 ) {
DEBUG ( 1 , ( " lookup_usergroups(dn=%s) asprintf failed! \n " , user_dn ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
rc = ads_search_retry ( ads , & res , ldap_exp , group_attrs ) ;
free ( ldap_exp ) ;
2003-09-05 08:46:44 +04:00
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! res ) {
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " lookup_usergroups ads_search member=%s: %s \n " , user_dn , ads_errstr ( rc ) ) ) ;
return ads_ntstatus ( rc ) ;
}
2003-04-23 15:54:56 +04:00
count = ads_count_replies ( ads , res ) ;
if ( count = = 0 ) {
DEBUG ( 5 , ( " lookup_usergroups: No supp groups found \n " ) ) ;
status = ads_ntstatus ( rc ) ;
goto done ;
}
( * user_gids ) = talloc_zero ( mem_ctx , sizeof ( * * user_gids ) * ( count + 1 ) ) ;
( * user_gids ) [ 0 ] = primary_group ;
* num_groups = 1 ;
for ( msg = ads_first_entry ( ads , res ) ; msg ; msg = ads_next_entry ( ads , msg ) ) {
DOM_SID group_sid ;
if ( ! ads_pull_sid ( ads , msg , " objectSid " , & group_sid ) ) {
DEBUG ( 1 , ( " No sid for this group ?!? \n " ) ) ;
continue ;
}
if ( sid_equal ( & group_sid , primary_group ) ) continue ;
( * user_gids ) [ * num_groups ] = talloc ( mem_ctx , sizeof ( * * * user_gids ) ) ;
if ( ! ( * user_gids ) [ * num_groups ] ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
sid_copy ( ( * user_gids ) [ * num_groups ] , & group_sid ) ;
( * num_groups ) + + ;
}
status = NT_STATUS_OK ;
DEBUG ( 3 , ( " ads lookup_usergroups (alt) for dn=%s \n " , user_dn ) ) ;
done :
2003-09-05 08:46:44 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2003-04-23 15:54:56 +04:00
return status ;
}
2001-12-05 09:16:33 +03:00
2001-12-04 09:46:53 +03:00
/* Lookup groups a user is a member of. */
static NTSTATUS lookup_usergroups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * sid ,
uint32 * num_groups , DOM_SID * * * user_gids )
2001-12-04 09:46:53 +03:00
{
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2001-12-04 15:10:05 +03:00
const char * attrs [ ] = { " distinguishedName " , NULL } ;
const char * attrs2 [ ] = { " tokenGroups " , " primaryGroupID " , NULL } ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
int count ;
2001-12-05 09:16:33 +03:00
void * msg = NULL ;
2003-06-30 09:44:05 +04:00
char * ldap_exp ;
2001-12-04 15:10:05 +03:00
char * user_dn ;
DOM_SID * sids ;
int i ;
2003-04-23 15:54:56 +04:00
DOM_SID * primary_group ;
uint32 primary_group_rid ;
2001-12-05 07:48:51 +03:00
char * sidstr ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-05 09:16:33 +03:00
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2001-12-04 15:10:05 +03:00
DEBUG ( 3 , ( " ads: lookup_usergroups \n " ) ) ;
2003-04-23 15:54:56 +04:00
* num_groups = 0 ;
2001-12-05 07:48:51 +03:00
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ( sidstr = sid_binstring ( sid ) ) ) {
DEBUG ( 1 , ( " lookup_usergroups(sid=%s) sid_binstring returned NULL \n " , sid_to_string ( sid_string , sid ) ) ) ;
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
if ( asprintf ( & ldap_exp , " (objectSid=%s) " , sidstr ) = = - 1 ) {
2003-04-23 15:54:56 +04:00
free ( sidstr ) ;
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " lookup_usergroups(sid=%s) asprintf failed! \n " , sid_to_string ( sid_string , sid ) ) ) ;
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2003-04-23 15:54:56 +04:00
2003-09-06 22:02:19 +04:00
rc = ads_search_retry ( ads , & msg , ldap_exp , attrs ) ;
free ( ldap_exp ) ;
free ( sidstr ) ;
2003-04-23 15:54:56 +04:00
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! msg ) {
2003-09-06 22:02:19 +04:00
DEBUG ( 1 , ( " lookup_usergroups(sid=%s) ads_search: %s \n " , sid_to_string ( sid_string , sid ) , ads_errstr ( rc ) ) ) ;
goto done ;
}
2001-12-04 15:10:05 +03:00
user_dn = ads_pull_string ( ads , mem_ctx , msg , " distinguishedName " ) ;
2003-04-23 15:54:56 +04:00
if ( ! user_dn ) {
DEBUG ( 1 , ( " lookup_usergroups(sid=%s) ads_search did not return a a distinguishedName! \n " , sid_to_string ( sid_string , sid ) ) ) ;
2003-09-06 22:02:19 +04:00
if ( msg )
ads_msgfree ( ads , msg ) ;
2003-04-23 15:54:56 +04:00
goto done ;
}
2001-12-04 15:10:05 +03:00
2003-09-06 22:02:19 +04:00
if ( msg )
ads_msgfree ( ads , msg ) ;
2001-12-05 10:11:26 +03:00
2001-12-08 14:18:56 +03:00
rc = ads_search_retry_dn ( ads , & msg , user_dn , attrs2 ) ;
2003-09-07 00:00:16 +04:00
if ( ! ADS_ERR_OK ( rc ) | | ! msg ) {
2003-04-23 15:54:56 +04:00
DEBUG ( 1 , ( " lookup_usergroups(sid=%s) ads_search tokenGroups: %s \n " , sid_to_string ( sid_string , sid ) , ads_errstr ( rc ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-04 15:10:05 +03:00
}
2003-04-23 15:54:56 +04:00
if ( ! ads_pull_uint32 ( ads , msg , " primaryGroupID " , & primary_group_rid ) ) {
DEBUG ( 1 , ( " %s: No primary group for sid=%s !? \n " , domain - > name , sid_to_string ( sid_string , sid ) ) ) ;
2001-12-05 09:16:33 +03:00
goto done ;
2001-12-04 15:10:05 +03:00
}
2003-04-23 15:54:56 +04:00
primary_group = rid_to_talloced_sid ( domain , mem_ctx , primary_group_rid ) ;
2001-12-04 15:10:05 +03:00
2003-04-23 15:54:56 +04:00
count = ads_pull_sids ( ads , mem_ctx , msg , " tokenGroups " , & sids ) ;
2003-09-06 22:02:19 +04:00
if ( msg )
ads_msgfree ( ads , msg ) ;
2003-04-23 15:54:56 +04:00
/* there must always be at least one group in the token,
unless we are talking to a buggy Win2k server */
if ( count = = 0 ) {
return lookup_usergroups_alt ( domain , mem_ctx , user_dn ,
primary_group ,
num_groups , user_gids ) ;
}
( * user_gids ) = talloc_zero ( mem_ctx , sizeof ( * * user_gids ) * ( count + 1 ) ) ;
( * user_gids ) [ 0 ] = primary_group ;
* num_groups = 1 ;
for ( i = 0 ; i < count ; i + + ) {
if ( sid_equal ( & sids [ i ] , primary_group ) ) continue ;
( * user_gids ) [ * num_groups ] = talloc ( mem_ctx , sizeof ( * * * user_gids ) ) ;
if ( ! ( * user_gids ) [ * num_groups ] ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
sid_copy ( ( * user_gids ) [ * num_groups ] , & sids [ i ] ) ;
2001-12-04 15:10:05 +03:00
( * num_groups ) + + ;
}
2001-12-05 09:16:33 +03:00
status = NT_STATUS_OK ;
2003-04-23 15:54:56 +04:00
DEBUG ( 3 , ( " ads lookup_usergroups for sid=%s \n " , sid_to_string ( sid_string , sid ) ) ) ;
2001-12-05 09:16:33 +03:00
done :
return status ;
2001-12-04 09:46:53 +03:00
}
2002-07-15 14:35:28 +04:00
/*
find the members of a group , given a group rid and domain
*/
2001-12-05 07:48:51 +03:00
static NTSTATUS lookup_groupmem ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * group_sid , uint32 * num_names ,
DOM_SID * * * sid_mem , char * * * names ,
2001-12-05 07:48:51 +03:00
uint32 * * name_types )
{
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
int count ;
2002-07-15 14:35:28 +04:00
void * res = NULL ;
2001-12-05 09:16:33 +03:00
ADS_STRUCT * ads = NULL ;
2003-06-30 09:44:05 +04:00
char * ldap_exp ;
2001-12-05 09:16:33 +03:00
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
char * sidstr ;
2004-01-02 00:10:35 +03:00
const char * attrs [ ] = { " member " , NULL } ;
2002-07-15 14:35:28 +04:00
char * * members ;
int i , num_members ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-05 08:35:45 +03:00
2003-06-10 04:55:37 +04:00
DEBUG ( 10 , ( " ads: lookup_groupmem %s sid=%s \n " , domain - > name , sid_string_static ( group_sid ) ) ) ;
2001-12-05 08:35:45 +03:00
* num_names = 0 ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
goto done ;
}
2002-07-15 14:35:28 +04:00
2003-09-06 22:02:19 +04:00
sidstr = sid_binstring ( group_sid ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
/* search for all members of the group */
asprintf ( & ldap_exp , " (objectSid=%s) " , sidstr ) ;
2004-01-02 00:10:35 +03:00
rc = ads_search_retry ( ads , & res , ldap_exp , attrs ) ;
free ( ldap_exp ) ;
free ( sidstr ) ;
2003-09-05 08:46:44 +04:00
2004-01-02 00:10:35 +03:00
if ( ! ADS_ERR_OK ( rc ) | | ! res ) {
DEBUG ( 1 , ( " query_user_list ads_search: %s \n " , ads_errstr ( rc ) ) ) ;
goto done ;
}
2004-01-01 23:30:50 +03:00
2004-01-02 00:10:35 +03:00
count = ads_count_replies ( ads , res ) ;
if ( count = = 0 ) {
status = NT_STATUS_OK ;
goto done ;
}
2004-01-01 23:30:50 +03:00
2004-01-02 00:10:35 +03:00
members = ads_pull_strings ( ads , mem_ctx , res , " member " ) ;
if ( ! members ) {
/* no members? ok ... */
status = NT_STATUS_OK ;
goto done ;
2004-01-01 23:30:50 +03:00
}
2004-01-02 00:10:35 +03:00
2002-07-15 14:35:28 +04:00
/* now we need to turn a list of members into rids, names and name types
the problem is that the members are in the form of distinguised names
*/
2004-01-02 00:10:35 +03:00
for ( i = 0 ; members [ i ] ; i + + ) /* noop */ ;
num_members = i ;
2001-12-05 08:35:45 +03:00
2003-04-23 15:54:56 +04:00
( * sid_mem ) = talloc_zero ( mem_ctx , sizeof ( * * sid_mem ) * num_members ) ;
( * name_types ) = talloc_zero ( mem_ctx , sizeof ( * * name_types ) * num_members ) ;
( * names ) = talloc_zero ( mem_ctx , sizeof ( * * names ) * num_members ) ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_members ; i + + ) {
2003-04-23 15:54:56 +04:00
uint32 name_type ;
2002-07-15 14:35:28 +04:00
char * name ;
2003-04-23 15:54:56 +04:00
DOM_SID sid ;
2002-07-15 14:35:28 +04:00
2003-04-23 15:54:56 +04:00
if ( dn_lookup ( ads , mem_ctx , members [ i ] , & name , & name_type , & sid ) ) {
2002-07-15 14:35:28 +04:00
( * names ) [ * num_names ] = name ;
( * name_types ) [ * num_names ] = name_type ;
2003-04-23 15:54:56 +04:00
( * sid_mem ) [ * num_names ] = talloc ( mem_ctx , sizeof ( * * * sid_mem ) ) ;
if ( ! ( * sid_mem ) [ * num_names ] ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
sid_copy ( ( * sid_mem ) [ * num_names ] , & sid ) ;
2002-07-15 14:35:28 +04:00
( * num_names ) + + ;
2001-12-05 08:35:45 +03:00
}
}
2001-12-05 09:16:33 +03:00
status = NT_STATUS_OK ;
2003-04-23 15:54:56 +04:00
DEBUG ( 3 , ( " ads lookup_groupmem for sid=%s \n " , sid_to_string ( sid_string , group_sid ) ) ) ;
2001-12-05 09:16:33 +03:00
done :
2003-09-06 22:02:19 +04:00
if ( res )
ads_msgfree ( ads , res ) ;
2001-12-05 08:35:45 +03:00
2001-12-05 09:16:33 +03:00
return status ;
2001-12-05 07:48:51 +03:00
}
2002-07-15 14:35:28 +04:00
2001-12-05 10:52:44 +03:00
/* find the sequence number for a domain */
2001-12-10 02:59:42 +03:00
static NTSTATUS sequence_number ( struct winbindd_domain * domain , uint32 * seq )
2001-12-05 10:52:44 +03:00
{
ADS_STRUCT * ads = NULL ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-12-05 10:52:44 +03:00
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: fetch sequence_number for %s \n " , domain - > name ) ) ;
2001-12-10 02:59:42 +03:00
* seq = DOM_SEQUENCE_NONE ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
return NT_STATUS_UNSUCCESSFUL ;
}
2001-12-05 10:52:44 +03:00
2003-09-06 22:02:19 +04:00
rc = ads_USN ( ads , seq ) ;
2003-10-04 01:43:09 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ADS_ERR_OK ( rc ) ) {
2003-10-04 01:43:09 +04:00
/* its a dead connection ; don't destroy it
through since ads_USN ( ) has already done
that indirectly */
2003-09-06 22:02:19 +04:00
domain - > private = NULL ;
}
2001-12-19 15:21:12 +03:00
return ads_ntstatus ( rc ) ;
2001-12-05 10:52:44 +03:00
}
2001-12-10 05:25:19 +03:00
/* get a list of trusted domains */
static NTSTATUS trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_domains ,
char * * * names ,
2002-08-17 21:00:51 +04:00
char * * * alt_names ,
2001-12-10 05:25:19 +03:00
DOM_SID * * dom_sids )
{
2003-07-31 09:43:47 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
DS_DOMAIN_TRUSTS * domains = NULL ;
int count = 0 ;
int i ;
struct cli_state * cli = NULL ;
/* i think we only need our forest and downlevel trusted domains */
uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND ;
2003-09-05 21:57:45 +04:00
char * contact_domain_name ;
2001-12-19 11:44:23 +03:00
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: trusted_domains \n " ) ) ;
2001-12-10 05:25:19 +03:00
* num_domains = 0 ;
2003-07-31 09:43:47 +04:00
* alt_names = NULL ;
* names = NULL ;
* dom_sids = NULL ;
2003-09-05 21:57:45 +04:00
contact_domain_name = * domain - > alt_name ? domain - > alt_name : domain - > name ;
if ( ! NT_STATUS_IS_OK ( result = cm_fresh_connection ( contact_domain_name , PI_NETLOGON , & cli ) ) ) {
2003-07-31 09:43:47 +04:00
DEBUG ( 5 , ( " trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s) \n " ,
2003-09-05 21:57:45 +04:00
contact_domain_name , nt_errstr ( result ) ) ) ;
2003-07-31 09:43:47 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
if ( NT_STATUS_IS_OK ( result ) )
2003-08-15 08:42:05 +04:00
result = cli_ds_enum_domain_trusts ( cli , mem_ctx , cli - > desthost , flags , & domains , ( unsigned int * ) & count ) ;
2003-07-31 09:43:47 +04:00
if ( NT_STATUS_IS_OK ( result ) & & count ) {
/* Allocate memory for trusted domain names and sids */
2001-12-19 11:44:23 +03:00
2003-07-31 09:43:47 +04:00
if ( ! ( * names = ( char * * ) talloc ( mem_ctx , sizeof ( char * ) * count ) ) ) {
DEBUG ( 0 , ( " trusted_domains: out of memory \n " ) ) ;
result = NT_STATUS_NO_MEMORY ;
goto done ;
}
2003-06-23 09:10:07 +04:00
2003-07-31 09:43:47 +04:00
if ( ! ( * alt_names = ( char * * ) talloc ( mem_ctx , sizeof ( char * ) * count ) ) ) {
DEBUG ( 0 , ( " trusted_domains: out of memory \n " ) ) ;
result = NT_STATUS_NO_MEMORY ;
goto done ;
}
if ( ! ( * dom_sids = ( DOM_SID * ) talloc ( mem_ctx , sizeof ( DOM_SID ) * count ) ) ) {
DEBUG ( 0 , ( " trusted_domains: out of memory \n " ) ) ;
result = NT_STATUS_NO_MEMORY ;
goto done ;
}
/* Copy across names and sids */
for ( i = 0 ; i < count ; i + + ) {
fstring tmp ;
fstring tmp2 ;
( * names ) [ i ] = NULL ;
( * alt_names ) [ i ] = NULL ;
ZERO_STRUCT ( ( * dom_sids ) [ i ] ) ;
if ( domains [ i ] . netbios_ptr ) {
unistr2_to_ascii ( tmp , & domains [ i ] . netbios_domain , sizeof ( tmp ) - 1 ) ;
( * names ) [ i ] = talloc_strdup ( mem_ctx , tmp ) ;
}
if ( domains [ i ] . dns_ptr ) {
unistr2_to_ascii ( tmp2 , & domains [ i ] . dns_domain , sizeof ( tmp2 ) - 1 ) ;
( * alt_names ) [ i ] = talloc_strdup ( mem_ctx , tmp2 ) ;
}
/* sometimes we will get back a NULL SID from this call */
if ( domains [ i ] . sid_ptr )
sid_copy ( & ( * dom_sids ) [ i ] , & domains [ i ] . sid . sid ) ;
}
* num_domains = count ;
2003-06-23 09:10:07 +04:00
}
2001-12-19 11:44:23 +03:00
2003-07-31 09:43:47 +04:00
done :
SAFE_FREE ( domains ) ;
/* remove connection; This is a special case to the \NETLOGON pipe */
if ( cli )
cli_shutdown ( cli ) ;
2001-12-19 11:44:23 +03:00
2003-07-31 09:43:47 +04:00
return result ;
2001-12-10 05:25:19 +03:00
}
/* find the domain sid for a domain */
static NTSTATUS domain_sid ( struct winbindd_domain * domain , DOM_SID * sid )
{
2001-12-21 02:35:14 +03:00
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-12-10 05:25:19 +03:00
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: domain_sid \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-06-23 09:10:07 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
return NT_STATUS_UNSUCCESSFUL ;
}
2001-12-10 05:25:19 +03:00
2003-09-06 22:02:19 +04:00
rc = ads_domain_sid ( ads , sid ) ;
2001-12-10 05:25:19 +03:00
2003-09-06 22:02:19 +04:00
if ( ! ADS_ERR_OK ( rc ) ) {
2003-10-04 01:43:09 +04:00
/* its a dead connection; don't destroy it though
since that has already been done indirectly
by ads_domain_sid ( ) */
2003-09-06 22:02:19 +04:00
domain - > private = NULL ;
}
2002-03-09 22:36:53 +03:00
2001-12-21 02:35:14 +03:00
return ads_ntstatus ( rc ) ;
2001-12-10 05:25:19 +03:00
}
2002-08-17 21:00:51 +04:00
/* find alternate names list for the domain - for ADS this is the
netbios name */
static NTSTATUS alternate_name ( struct winbindd_domain * domain )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
TALLOC_CTX * ctx ;
char * workgroup ;
2003-06-10 04:55:37 +04:00
DEBUG ( 3 , ( " ads: alternate_name \n " ) ) ;
2003-09-06 22:02:19 +04:00
ads = ads_cached_connection ( domain ) ;
2003-09-05 08:46:44 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ads ) {
domain - > last_status = NT_STATUS_SERVER_DISABLED ;
return NT_STATUS_UNSUCCESSFUL ;
}
2002-08-17 21:00:51 +04:00
2003-09-06 22:02:19 +04:00
if ( ! ( ctx = talloc_init ( " alternate_name " ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
2002-08-17 21:00:51 +04:00
2003-09-06 22:02:19 +04:00
rc = ads_workgroup_name ( ads , ctx , & workgroup ) ;
2002-08-17 21:00:51 +04:00
2003-09-06 22:02:19 +04:00
if ( ADS_ERR_OK ( rc ) ) {
fstrcpy ( domain - > name , workgroup ) ;
fstrcpy ( domain - > alt_name , ads - > config . realm ) ;
strupper_m ( domain - > alt_name ) ;
strupper_m ( domain - > name ) ;
}
2002-08-17 21:00:51 +04:00
talloc_destroy ( ctx ) ;
return ads_ntstatus ( rc ) ;
}
2001-12-03 14:11:14 +03:00
/* the ADS backend methods are exposed via this structure */
2001-12-03 09:04:18 +03:00
struct winbindd_methods ads_methods = {
2001-12-10 09:05:21 +03:00
True ,
2001-12-03 14:32:55 +03:00
query_user_list ,
2001-12-03 11:17:46 +03:00
enum_dom_groups ,
2002-11-15 20:57:21 +03:00
enum_local_groups ,
2001-12-03 14:11:14 +03:00
name_to_sid ,
2001-12-05 07:48:51 +03:00
sid_to_name ,
2001-12-04 09:46:53 +03:00
query_user ,
2001-12-05 07:48:51 +03:00
lookup_usergroups ,
2001-12-05 10:52:44 +03:00
lookup_groupmem ,
2001-12-10 05:25:19 +03:00
sequence_number ,
trusted_domains ,
2002-08-17 21:00:51 +04:00
domain_sid ,
alternate_name
2001-12-03 09:04:18 +03:00
} ;
# endif