2009-09-08 05:49:28 +04:00
/*
Unix SMB / CIFS implementation .
useful utilities for the DRS server
Copyright ( C ) Andrew Tridgell 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"
# include "rpc_server/dcerpc_server.h"
# include "dsdb/samdb/samdb.h"
2009-09-20 02:08:19 +04:00
# include "libcli/security/security.h"
2010-09-20 08:49:39 +04:00
# include "libcli/security/session.h"
2009-09-20 02:53:22 +04:00
# include "param/param.h"
2010-01-16 02:36:40 +03:00
# include "auth/session.h"
2011-03-19 02:43:34 +03:00
# include "rpc_server/drsuapi/dcesrv_drsuapi.h"
2009-09-08 05:49:28 +04:00
2017-09-06 07:37:34 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_DRS_REPL
2009-09-09 15:00:01 +04:00
int drsuapi_search_with_extended_dn ( struct ldb_context * ldb ,
2009-09-23 04:07:33 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_result * * _res ,
struct ldb_dn * basedn ,
enum ldb_scope scope ,
const char * const * attrs ,
2009-09-24 02:47:14 +04:00
const char * filter )
2009-09-09 15:00:01 +04:00
{
int ret ;
struct ldb_request * req ;
TALLOC_CTX * tmp_ctx ;
struct ldb_result * res ;
tmp_ctx = talloc_new ( mem_ctx ) ;
res = talloc_zero ( tmp_ctx , struct ldb_result ) ;
if ( ! res ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
ret = ldb_build_search_req ( & req , ldb , tmp_ctx ,
basedn ,
scope ,
filter ,
attrs ,
NULL ,
res ,
ldb_search_default_callback ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( tmp_ctx ) ;
return ret ;
}
ret = ldb_request_add_control ( req , LDB_CONTROL_EXTENDED_DN_OID , true , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2010-09-20 00:20:08 +04:00
ret = ldb_request_add_control ( req , LDB_CONTROL_SHOW_RECYCLED_OID , true , NULL ) ;
2009-09-24 18:12:14 +04:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2009-12-19 04:24:09 +03:00
ret = ldb_request_add_control ( req , LDB_CONTROL_REVEAL_INTERNALS , false , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2009-09-09 15:00:01 +04:00
ret = ldb_request ( ldb , req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
talloc_free ( req ) ;
2009-09-24 18:12:14 +04:00
* _res = talloc_steal ( mem_ctx , res ) ;
2009-09-09 15:00:01 +04:00
return ret ;
}
2010-04-22 10:48:01 +04:00
WERROR drs_security_level_check ( struct dcesrv_call_state * dce_call ,
const char * call ,
2010-08-17 08:12:21 +04:00
enum security_user_level minimum_level ,
const struct dom_sid * domain_sid )
2009-09-20 02:08:19 +04:00
{
2018-11-03 03:19:51 +03:00
struct auth_session_info * session_info =
dcesrv_call_session_info ( dce_call ) ;
2010-01-16 02:36:40 +03:00
enum security_user_level level ;
2010-07-16 08:32:42 +04:00
if ( lpcfg_parm_bool ( dce_call - > conn - > dce_ctx - > lp_ctx , NULL ,
2009-09-20 06:39:42 +04:00
" drs " , " disable_sec_check " , false ) ) {
2009-09-20 02:08:19 +04:00
return WERR_OK ;
}
2018-11-03 03:19:51 +03:00
level = security_session_user_level ( session_info , domain_sid ) ;
2010-04-22 10:48:01 +04:00
if ( level < minimum_level ) {
2009-10-06 11:58:41 +04:00
if ( call ) {
2010-01-16 02:36:40 +03:00
DEBUG ( 0 , ( " %s refused for security token (level=%u) \n " ,
call , ( unsigned ) level ) ) ;
2018-11-03 03:19:51 +03:00
security_token_debug ( DBGC_DRS_REPL , 2 , session_info - > security_token ) ;
2009-10-06 11:58:41 +04:00
}
2009-09-20 02:08:19 +04:00
return WERR_DS_DRA_ACCESS_DENIED ;
}
return WERR_OK ;
}
s4: Handle DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING in getncchanges
When this flag is specified in the request these attributes are treated as
secret: currentValue, dBCSPwd, initialAuthIncoming, initialAuthOutgoing,
lmPwdHistory, ntPwdHistory, priorValue, supplementalCredentials,
trustAuthIncoming, trustAuthOutgoing, unicodePwd
Their value is changed to NULL and the meta_data.originating_change_time to 0
2009-09-24 03:51:55 +04:00
void drsuapi_process_secret_attribute ( struct drsuapi_DsReplicaAttribute * attr ,
struct drsuapi_DsReplicaMetaData * meta_data )
{
if ( attr - > value_ctr . num_values = = 0 ) {
return ;
}
switch ( attr - > attid ) {
2010-10-29 03:22:35 +04:00
case DRSUAPI_ATTID_dBCSPwd :
case DRSUAPI_ATTID_unicodePwd :
case DRSUAPI_ATTID_ntPwdHistory :
case DRSUAPI_ATTID_lmPwdHistory :
case DRSUAPI_ATTID_supplementalCredentials :
case DRSUAPI_ATTID_priorValue :
case DRSUAPI_ATTID_currentValue :
case DRSUAPI_ATTID_trustAuthOutgoing :
case DRSUAPI_ATTID_trustAuthIncoming :
case DRSUAPI_ATTID_initialAuthOutgoing :
case DRSUAPI_ATTID_initialAuthIncoming :
s4: Handle DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING in getncchanges
When this flag is specified in the request these attributes are treated as
secret: currentValue, dBCSPwd, initialAuthIncoming, initialAuthOutgoing,
lmPwdHistory, ntPwdHistory, priorValue, supplementalCredentials,
trustAuthIncoming, trustAuthOutgoing, unicodePwd
Their value is changed to NULL and the meta_data.originating_change_time to 0
2009-09-24 03:51:55 +04:00
/*set value to null*/
attr - > value_ctr . num_values = 0 ;
talloc_free ( attr - > value_ctr . values ) ;
attr - > value_ctr . values = NULL ;
meta_data - > originating_change_time = 0 ;
return ;
default :
return ;
}
}
2010-09-27 08:14:45 +04:00
2010-09-30 02:46:23 +04:00
/*
check security on a DN , with logging of errors
*/
static WERROR drs_security_access_check_log ( struct ldb_context * sam_ctx ,
TALLOC_CTX * mem_ctx ,
struct security_token * token ,
struct ldb_dn * dn ,
const char * ext_right )
2010-09-27 08:14:45 +04:00
{
int ret ;
if ( ! dn ) {
2010-09-30 02:46:23 +04:00
DEBUG ( 3 , ( " drs_security_access_check: Null dn provided, access is denied for %s \n " ,
ext_right ) ) ;
2010-09-27 08:14:45 +04:00
return WERR_DS_DRA_ACCESS_DENIED ;
}
ret = dsdb_check_access_on_dn ( sam_ctx ,
mem_ctx ,
dn ,
token ,
SEC_ADS_CONTROL_ACCESS ,
ext_right ) ;
if ( ret = = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS ) {
2010-09-30 02:46:23 +04:00
DEBUG ( 3 , ( " %s refused for security token on %s \n " ,
ext_right , ldb_dn_get_linearized ( dn ) ) ) ;
2018-05-21 04:53:01 +03:00
security_token_debug ( DBGC_DRS_REPL , 3 , token ) ;
2010-09-30 02:46:23 +04:00
return WERR_DS_DRA_ACCESS_DENIED ;
2010-09-27 08:14:45 +04:00
} else if ( ret ! = LDB_SUCCESS ) {
2013-09-09 01:57:27 +04:00
DEBUG ( 1 , ( " Failed to perform access check on %s: %s \n " , ldb_dn_get_linearized ( dn ) , ldb_strerror ( ret ) ) ) ;
2010-09-27 08:14:45 +04:00
return WERR_DS_DRA_INTERNAL_ERROR ;
}
return WERR_OK ;
}
2010-09-30 02:46:23 +04:00
/*
check security on a object identifier
*/
WERROR drs_security_access_check ( struct ldb_context * sam_ctx ,
TALLOC_CTX * mem_ctx ,
struct security_token * token ,
struct drsuapi_DsReplicaObjectIdentifier * nc ,
const char * ext_right )
{
2022-12-11 23:47:36 +03:00
struct ldb_dn * dn ;
2010-09-30 02:46:23 +04:00
WERROR werr ;
2022-12-11 23:47:36 +03:00
int ret ;
ret = drs_ObjectIdentifier_to_dn_and_nc_root ( mem_ctx ,
sam_ctx ,
nc ,
& dn ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_DRA_BAD_DN ;
}
2010-09-30 02:46:23 +04:00
werr = drs_security_access_check_log ( sam_ctx , mem_ctx , token , dn , ext_right ) ;
talloc_free ( dn ) ;
return werr ;
}
/*
check security on the NC root of a object identifier
*/
WERROR drs_security_access_check_nc_root ( struct ldb_context * sam_ctx ,
TALLOC_CTX * mem_ctx ,
struct security_token * token ,
struct drsuapi_DsReplicaObjectIdentifier * nc ,
const char * ext_right )
{
2022-12-11 23:47:36 +03:00
struct ldb_dn * nc_root ;
2010-09-30 02:46:23 +04:00
WERROR werr ;
int ret ;
2022-12-11 23:47:36 +03:00
ret = drs_ObjectIdentifier_to_dn_and_nc_root ( mem_ctx ,
sam_ctx ,
nc ,
NULL ,
& nc_root ) ;
2010-09-30 02:46:23 +04:00
if ( ret ! = LDB_SUCCESS ) {
2022-12-11 23:47:36 +03:00
return WERR_DS_DRA_BAD_NC ;
2010-09-30 02:46:23 +04:00
}
2022-12-11 23:47:36 +03:00
2010-09-30 02:46:23 +04:00
werr = drs_security_access_check_log ( sam_ctx , mem_ctx , token , nc_root , ext_right ) ;
2022-12-11 23:47:36 +03:00
talloc_free ( nc_root ) ;
2010-09-30 02:46:23 +04:00
return werr ;
}