2004-10-14 13:56:04 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the drsuapi pipe
DsCrackNames ( )
Copyright ( C ) Stefan Metzmacher 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-01 13:30:34 +03:00
# include "librpc/gen_ndr/ndr_drsuapi.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2004-10-14 13:56:04 +04:00
# include "rpc_server/common/common.h"
# include "rpc_server/drsuapi/dcesrv_drsuapi.h"
2004-11-16 13:56:51 +03:00
# include "lib/ldb/include/ldb.h"
2004-10-14 13:56:04 +04:00
2004-10-15 15:08:14 +04:00
static WERROR DsCrackNameOneName ( struct drsuapi_bind_state * b_state , TALLOC_CTX * mem_ctx ,
2005-02-10 08:09:35 +03:00
uint32_t format_flags , uint32_t format_offered , uint32_t format_desired ,
2004-11-16 17:43:28 +03:00
const char * name , struct drsuapi_DsNameInfo1 * info1 )
2004-10-14 13:56:04 +04:00
{
2004-11-16 13:56:51 +03:00
int ret ;
2004-11-16 17:43:28 +03:00
const char * domain_filter = NULL ;
2004-11-16 13:56:51 +03:00
const char * const * domain_attrs ;
2004-11-16 17:43:28 +03:00
struct ldb_message * * domain_res = NULL ;
const char * result_basedn = NULL ;
2004-11-16 13:56:51 +03:00
const char * result_filter = NULL ;
const char * const * result_attrs ;
2004-11-16 17:43:28 +03:00
struct ldb_message * * result_res = NULL ;
2004-11-16 13:56:51 +03:00
2004-10-14 13:56:04 +04:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR ;
info1 - > dns_domain_name = NULL ;
info1 - > result_name = NULL ;
2004-11-16 17:43:28 +03:00
if ( ! name ) {
return WERR_INVALID_PARAM ;
}
/* TODO: - fill the correct names in all cases!
* - handle format_flags
*/
/* here we need to set the domain_filter and/or the result_filter */
2004-10-14 13:56:04 +04:00
switch ( format_offered ) {
case DRSUAPI_DS_NAME_FORMAT_CANONICAL : {
char * str ;
2005-08-03 11:24:42 +04:00
str = talloc_strdup ( mem_ctx , name ) ;
2004-10-15 15:08:14 +04:00
WERR_TALLOC_CHECK ( str ) ;
2005-08-03 11:24:42 +04:00
if ( strlen ( str ) = = 0 | | str [ strlen ( str ) - 1 ] ! = ' / ' ) {
info1 - > status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR ;
2004-10-15 15:08:14 +04:00
return WERR_OK ;
2004-10-14 13:56:04 +04:00
}
2005-08-03 11:24:42 +04:00
str [ strlen ( str ) - 1 ] = ' \0 ' ;
2004-10-14 13:56:04 +04:00
2005-08-03 11:24:42 +04:00
domain_filter = talloc_asprintf ( mem_ctx ,
" (&(&(&(dnsRoot=%s)(objectclass=crossRef)))(nETBIOSName=*)(ncName=*)) " ,
str ) ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( domain_filter ) ;
break ;
}
case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT : {
char * p ;
char * domain ;
const char * account = NULL ;
domain = talloc_strdup ( mem_ctx , name ) ;
WERR_TALLOC_CHECK ( domain ) ;
p = strchr ( domain , ' \\ ' ) ;
if ( ! p ) {
/* invalid input format */
info1 - > status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR ;
return WERR_OK ;
}
p [ 0 ] = ' \0 ' ;
if ( p [ 1 ] ) {
account = & p [ 1 ] ;
}
2005-08-03 09:28:06 +04:00
domain_filter = talloc_asprintf ( mem_ctx ,
" (&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*)) " ,
domain ) ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( domain_filter ) ;
if ( account ) {
result_filter = talloc_asprintf ( mem_ctx , " (sAMAccountName=%s) " ,
account ) ;
WERR_TALLOC_CHECK ( result_filter ) ;
2004-10-14 13:56:04 +04:00
}
2004-11-16 13:56:51 +03:00
talloc_free ( domain ) ;
break ;
2004-10-14 13:56:04 +04:00
}
default : {
info1 - > status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND ;
2004-10-15 15:08:14 +04:00
return WERR_OK ;
2004-10-14 13:56:04 +04:00
}
}
2004-11-16 17:43:28 +03:00
/* here we need to set the attrs lists for domain and result lookups */
2004-11-16 13:56:51 +03:00
switch ( format_desired ) {
case DRSUAPI_DS_NAME_FORMAT_FQDN_1779 : {
2005-08-03 09:28:06 +04:00
const char * const _domain_attrs [ ] = { " ncName " , " dnsRoot " , NULL } ;
2004-11-16 13:56:51 +03:00
const char * const _result_attrs [ ] = { " dn " , NULL } ;
domain_attrs = _domain_attrs ;
result_attrs = _result_attrs ;
break ;
}
case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT : {
2005-08-03 09:28:06 +04:00
const char * const _domain_attrs [ ] = { " ncName " , " dnsRoot " , " nETBIOSName " , NULL } ;
2004-11-16 13:56:51 +03:00
const char * const _result_attrs [ ] = { " sAMAccountName " , NULL } ;
domain_attrs = _domain_attrs ;
result_attrs = _result_attrs ;
break ;
}
case DRSUAPI_DS_NAME_FORMAT_GUID : {
2005-08-03 09:28:06 +04:00
const char * const _domain_attrs [ ] = { " ncName " , " dnsRoot " , NULL } ;
2004-11-16 13:56:51 +03:00
const char * const _result_attrs [ ] = { " objectGUID " , NULL } ;
domain_attrs = _domain_attrs ;
result_attrs = _result_attrs ;
break ;
}
default :
return WERR_OK ;
}
2004-11-16 17:43:28 +03:00
/* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( b_state - > sam_ctx , mem_ctx , NULL , & domain_res , domain_attrs ,
2004-11-16 13:56:51 +03:00
" %s " , domain_filter ) ;
switch ( ret ) {
2004-11-16 17:43:28 +03:00
case 1 :
2004-11-16 13:56:51 +03:00
break ;
2004-11-16 17:43:28 +03:00
case 0 :
2004-11-16 13:56:51 +03:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND ;
return WERR_OK ;
2004-11-16 17:43:28 +03:00
case - 1 :
2004-11-16 13:56:51 +03:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR ;
return WERR_OK ;
default :
info1 - > status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE ;
return WERR_OK ;
}
2005-08-03 09:28:06 +04:00
info1 - > dns_domain_name = samdb_result_string ( domain_res [ 0 ] , " dnsRoot " , NULL ) ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( info1 - > dns_domain_name ) ;
info1 - > status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY ;
if ( result_filter ) {
2005-08-03 09:28:06 +04:00
result_basedn = samdb_result_string ( domain_res [ 0 ] , " ncName " , NULL ) ;
2004-11-16 17:43:28 +03:00
2005-03-23 04:30:43 +03:00
ret = gendb_search ( b_state - > sam_ctx , mem_ctx , result_basedn , & result_res ,
2004-11-16 13:56:51 +03:00
result_attrs , " %s " , result_filter ) ;
switch ( ret ) {
case 1 :
break ;
case 0 :
return WERR_OK ;
case - 1 :
info1 - > status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR ;
return WERR_OK ;
default :
info1 - > status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE ;
return WERR_OK ;
}
} else {
result_res = domain_res ;
}
2004-11-16 17:43:28 +03:00
/* here we can use result_res[0] and domain_res[0] */
2004-11-16 13:56:51 +03:00
switch ( format_desired ) {
case DRSUAPI_DS_NAME_FORMAT_FQDN_1779 : {
2005-08-03 09:28:06 +04:00
info1 - > result_name = result_res [ 0 ] - > dn ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( info1 - > result_name ) ;
2004-11-16 17:43:28 +03:00
2004-11-16 13:56:51 +03:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_OK ;
return WERR_OK ;
}
case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT : {
2004-11-16 17:43:28 +03:00
const char * _dom ;
2004-11-16 13:56:51 +03:00
const char * _acc = " " ;
2004-11-16 17:43:28 +03:00
2005-08-03 09:28:06 +04:00
_dom = samdb_result_string ( domain_res [ 0 ] , " nETBIOSName " , NULL ) ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( _dom ) ;
2004-11-16 17:43:28 +03:00
2004-11-16 13:56:51 +03:00
if ( result_filter ) {
_acc = samdb_result_string ( result_res [ 0 ] , " sAMAccountName " , NULL ) ;
WERR_TALLOC_CHECK ( _acc ) ;
}
2004-11-16 17:43:28 +03:00
2004-11-16 13:56:51 +03:00
info1 - > result_name = talloc_asprintf ( mem_ctx , " %s \\ %s " , _dom , _acc ) ;
WERR_TALLOC_CHECK ( info1 - > result_name ) ;
2004-11-16 17:43:28 +03:00
2004-11-16 13:56:51 +03:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_OK ;
return WERR_OK ;
}
case DRSUAPI_DS_NAME_FORMAT_GUID : {
2005-07-12 15:45:29 +04:00
struct GUID guid ;
2004-11-16 17:43:28 +03:00
2005-07-12 15:45:29 +04:00
guid = samdb_result_guid ( result_res [ 0 ] , " objectGUID " ) ;
info1 - > result_name = GUID_string2 ( mem_ctx , & guid ) ;
2004-11-16 13:56:51 +03:00
WERR_TALLOC_CHECK ( info1 - > result_name ) ;
2004-11-16 17:43:28 +03:00
2004-11-16 13:56:51 +03:00
info1 - > status = DRSUAPI_DS_NAME_STATUS_OK ;
return WERR_OK ;
}
default :
return WERR_OK ;
}
2004-10-15 15:08:14 +04:00
return WERR_INVALID_PARAM ;
2004-10-14 13:56:04 +04:00
}
/*
drsuapi_DsCrackNames
*/
2004-10-15 15:08:14 +04:00
WERROR dcesrv_drsuapi_DsCrackNames ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-14 13:56:04 +04:00
struct drsuapi_DsCrackNames * r )
{
2004-10-15 15:08:14 +04:00
WERROR status ;
2004-10-14 13:56:04 +04:00
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * h ;
r - > out . level = r - > in . level ;
ZERO_STRUCT ( r - > out . ctr ) ;
2004-10-15 15:08:14 +04:00
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
2004-10-14 13:56:04 +04:00
b_state = h - > data ;
switch ( r - > in . level ) {
case 1 : {
2004-11-16 17:43:28 +03:00
struct drsuapi_DsNameCtr1 * ctr1 ;
2004-10-14 13:56:04 +04:00
struct drsuapi_DsNameInfo1 * names ;
int count ;
int i ;
2005-01-27 10:08:20 +03:00
ctr1 = talloc ( mem_ctx , struct drsuapi_DsNameCtr1 ) ;
2004-11-16 17:43:28 +03:00
WERR_TALLOC_CHECK ( ctr1 ) ;
2004-10-14 13:56:04 +04:00
count = r - > in . req . req1 . count ;
2005-01-27 10:08:20 +03:00
names = talloc_array ( mem_ctx , struct drsuapi_DsNameInfo1 , count ) ;
2004-10-15 15:08:14 +04:00
WERR_TALLOC_CHECK ( names ) ;
2004-10-14 13:56:04 +04:00
for ( i = 0 ; i < count ; i + + ) {
status = DsCrackNameOneName ( b_state , mem_ctx ,
2004-11-16 17:43:28 +03:00
r - > in . req . req1 . format_flags ,
2004-10-14 13:56:04 +04:00
r - > in . req . req1 . format_offered ,
r - > in . req . req1 . format_desired ,
r - > in . req . req1 . names [ i ] . str ,
& names [ i ] ) ;
2004-10-15 15:08:14 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2004-10-14 13:56:04 +04:00
return status ;
}
}
2004-11-16 17:43:28 +03:00
ctr1 - > count = count ;
ctr1 - > array = names ;
r - > out . ctr . ctr1 = ctr1 ;
2004-10-14 13:56:04 +04:00
2004-10-15 15:08:14 +04:00
return WERR_OK ;
2004-10-14 13:56:04 +04:00
}
}
2004-10-15 15:08:14 +04:00
return WERR_UNKNOWN_LEVEL ;
2004-10-14 13:56:04 +04:00
}