2007-08-20 13:47:13 +04:00
/*
2006-02-04 01:19:41 +03:00
* Unix SMB / CIFS implementation .
* Group Policy Object Support
2007-07-17 13:39:39 +04:00
* Copyright ( C ) Guenther Deschner 2005 , 2007
2007-08-20 13:47:13 +04:00
*
2006-02-04 01:19:41 +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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2006-02-04 01:19:41 +03:00
* ( at your option ) any later version .
2007-08-20 13:47:13 +04:00
*
2006-02-04 01:19:41 +03:00
* 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 .
2007-08-20 13:47:13 +04:00
*
2006-02-04 01:19:41 +03:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
2009-03-01 18:25:57 +03:00
# include "libgpo/gpo.h"
2010-05-10 02:07:10 +04:00
# if _SAMBA_BUILD_ == 4
2009-04-20 11:57:00 +04:00
# include "libgpo/gpo_s4.h"
2009-03-01 16:06:36 +03:00
# include "source4/libgpo/ads_convenience.h"
# endif
2006-02-04 01:19:41 +03:00
2006-09-29 03:04:17 +04:00
/****************************************************************
parse the raw extension string into a GP_EXT structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool ads_parse_gp_ext ( TALLOC_CTX * mem_ctx ,
2007-08-14 18:47:08 +04:00
const char * extension_raw ,
struct GP_EXT * * gp_ext )
2006-02-04 01:19:41 +03:00
{
2008-02-29 16:51:37 +03:00
bool ret = false ;
2007-07-09 19:48:17 +04:00
struct GP_EXT * ext = NULL ;
2007-08-14 18:47:08 +04:00
char * * ext_list = NULL ;
2006-10-25 00:12:38 +04:00
char * * ext_strings = NULL ;
2006-02-04 01:19:41 +03:00
int i ;
2007-07-09 19:48:17 +04:00
if ( ! extension_raw ) {
goto parse_error ;
}
2006-02-04 01:19:41 +03:00
DEBUG ( 20 , ( " ads_parse_gp_ext: %s \n " , extension_raw ) ) ;
2009-03-01 18:25:57 +03:00
ext = talloc_zero ( mem_ctx , struct GP_EXT ) ;
2007-07-09 19:48:17 +04:00
if ( ! ext ) {
goto parse_error ;
}
2009-03-01 18:25:57 +03:00
ext_list = str_list_make ( mem_ctx , extension_raw , " ] " ) ;
2007-08-14 18:47:08 +04:00
if ( ! ext_list ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
for ( i = 0 ; ext_list [ i ] ! = NULL ; i + + ) {
/* no op */
}
2007-07-09 19:48:17 +04:00
ext - > num_exts = i ;
2007-08-14 18:47:08 +04:00
2007-07-09 19:48:17 +04:00
if ( ext - > num_exts ) {
2009-03-01 18:25:57 +03:00
ext - > extensions = talloc_zero_array ( mem_ctx , char * ,
2007-08-14 18:47:08 +04:00
ext - > num_exts ) ;
2009-03-01 18:25:57 +03:00
ext - > extensions_guid = talloc_zero_array ( mem_ctx , char * ,
2007-08-14 18:47:08 +04:00
ext - > num_exts ) ;
2009-03-01 18:25:57 +03:00
ext - > snapins = talloc_zero_array ( mem_ctx , char * ,
2007-08-14 18:47:08 +04:00
ext - > num_exts ) ;
2009-03-01 18:25:57 +03:00
ext - > snapins_guid = talloc_zero_array ( mem_ctx , char * ,
2007-08-14 18:47:08 +04:00
ext - > num_exts ) ;
2007-04-30 06:51:26 +04:00
}
2006-02-04 01:19:41 +03:00
2007-07-09 19:48:17 +04:00
ext - > gp_extension = talloc_strdup ( mem_ctx , extension_raw ) ;
2007-08-14 18:47:08 +04:00
if ( ! ext - > extensions | | ! ext - > extensions_guid | |
! ext - > snapins | | ! ext - > snapins_guid | |
! ext - > gp_extension ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
for ( i = 0 ; ext_list [ i ] ! = NULL ; i + + ) {
int k ;
char * p , * q ;
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
DEBUGADD ( 10 , ( " extension #%d \n " , i ) ) ;
p = ext_list [ i ] ;
if ( p [ 0 ] = = ' [ ' ) {
p + + ;
}
2009-03-01 18:25:57 +03:00
ext_strings = str_list_make ( mem_ctx , p , " } " ) ;
2006-02-04 01:19:41 +03:00
if ( ext_strings = = NULL ) {
goto parse_error ;
}
for ( k = 0 ; ext_strings [ k ] ! = NULL ; k + + ) {
/* no op */
}
q = ext_strings [ 0 ] ;
if ( q [ 0 ] = = ' { ' ) {
q + + ;
}
2007-08-14 18:47:08 +04:00
ext - > extensions [ i ] = talloc_strdup ( mem_ctx ,
cse_gpo_guid_string_to_name ( q ) ) ;
2007-07-09 19:48:17 +04:00
ext - > extensions_guid [ i ] = talloc_strdup ( mem_ctx , q ) ;
2006-02-04 01:19:41 +03:00
/* we might have no name for the guid */
2007-07-09 19:48:17 +04:00
if ( ext - > extensions_guid [ i ] = = NULL ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
for ( k = 1 ; ext_strings [ k ] ! = NULL ; k + + ) {
char * m = ext_strings [ k ] ;
if ( m [ 0 ] = = ' { ' ) {
m + + ;
}
2007-08-14 18:47:08 +04:00
/* FIXME: theoretically there could be more than one
* snapin per extension */
ext - > snapins [ i ] = talloc_strdup ( mem_ctx ,
cse_snapin_gpo_guid_string_to_name ( m ) ) ;
2007-07-09 19:48:17 +04:00
ext - > snapins_guid [ i ] = talloc_strdup ( mem_ctx , m ) ;
2006-02-04 01:19:41 +03:00
/* we might have no name for the guid */
2007-07-09 19:48:17 +04:00
if ( ext - > snapins_guid [ i ] = = NULL ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
}
}
2007-07-09 19:48:17 +04:00
* gp_ext = ext ;
2008-02-29 16:51:37 +03:00
ret = true ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
parse_error :
2009-03-01 18:25:57 +03:00
talloc_free ( ext_list ) ;
talloc_free ( ext_strings ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
return ret ;
2006-02-04 01:19:41 +03:00
}
2007-08-20 13:47:13 +04:00
# ifdef HAVE_LDAP
2006-09-29 03:04:17 +04:00
/****************************************************************
parse the raw link string into a GP_LINK structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 18:47:08 +04:00
static ADS_STATUS gpo_parse_gplink ( TALLOC_CTX * mem_ctx ,
2007-07-09 19:48:17 +04:00
const char * gp_link_raw ,
2007-08-14 18:47:08 +04:00
uint32_t options ,
2007-07-09 19:48:17 +04:00
struct GP_LINK * gp_link )
2006-02-04 01:19:41 +03:00
{
2007-08-20 13:47:13 +04:00
ADS_STATUS status = ADS_ERROR_NT ( NT_STATUS_NO_MEMORY ) ;
2006-02-04 01:19:41 +03:00
char * * link_list ;
int i ;
2007-08-14 18:47:08 +04:00
ZERO_STRUCTP ( gp_link ) ;
2007-07-09 19:48:17 +04:00
DEBUG ( 10 , ( " gpo_parse_gplink: gPLink: %s \n " , gp_link_raw ) ) ;
2006-02-04 01:19:41 +03:00
2008-11-07 05:53:00 +03:00
link_list = str_list_make_v3 ( mem_ctx , gp_link_raw , " ] " ) ;
2007-08-14 18:47:08 +04:00
if ( ! link_list ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
for ( i = 0 ; link_list [ i ] ! = NULL ; i + + ) {
/* no op */
}
gp_link - > gp_opts = options ;
gp_link - > num_links = i ;
2007-08-14 18:47:08 +04:00
2007-04-30 06:51:26 +04:00
if ( gp_link - > num_links ) {
2009-03-01 18:25:57 +03:00
gp_link - > link_names = talloc_zero_array ( mem_ctx , char * ,
2007-08-14 18:47:08 +04:00
gp_link - > num_links ) ;
2009-03-01 18:25:57 +03:00
gp_link - > link_opts = talloc_zero_array ( mem_ctx , uint32_t ,
2007-08-14 18:47:08 +04:00
gp_link - > num_links ) ;
2007-04-30 06:51:26 +04:00
}
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
gp_link - > gp_link = talloc_strdup ( mem_ctx , gp_link_raw ) ;
2007-08-14 18:47:08 +04:00
if ( ! gp_link - > link_names | | ! gp_link - > link_opts | | ! gp_link - > gp_link ) {
2006-02-04 01:19:41 +03:00
goto parse_error ;
}
for ( i = 0 ; link_list [ i ] ! = NULL ; i + + ) {
char * p , * q ;
2007-07-09 19:48:17 +04:00
DEBUGADD ( 10 , ( " gpo_parse_gplink: processing link #%d \n " , i ) ) ;
2006-02-04 01:19:41 +03:00
q = link_list [ i ] ;
if ( q [ 0 ] = = ' [ ' ) {
q + + ;
} ;
p = strchr ( q , ' ; ' ) ;
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
if ( p = = NULL ) {
goto parse_error ;
}
gp_link - > link_names [ i ] = talloc_strdup ( mem_ctx , q ) ;
if ( gp_link - > link_names [ i ] = = NULL ) {
goto parse_error ;
}
gp_link - > link_names [ i ] [ PTR_DIFF ( p , q ) ] = 0 ;
gp_link - > link_opts [ i ] = atoi ( p + 1 ) ;
2007-08-14 18:47:08 +04:00
DEBUGADD ( 10 , ( " gpo_parse_gplink: link: %s \n " ,
gp_link - > link_names [ i ] ) ) ;
DEBUGADD ( 10 , ( " gpo_parse_gplink: opt: %d \n " ,
gp_link - > link_opts [ i ] ) ) ;
2006-02-04 01:19:41 +03:00
}
2007-08-14 18:47:08 +04:00
status = ADS_SUCCESS ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
parse_error :
2009-03-01 18:25:57 +03:00
talloc_free ( link_list ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
return status ;
2006-02-04 01:19:41 +03:00
}
2006-09-29 03:04:17 +04:00
/****************************************************************
helper call to get a GP_LINK structure from a linkdn
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-04 01:19:41 +03:00
ADS_STATUS ads_get_gpo_link ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
const char * link_dn ,
struct GP_LINK * gp_link_struct )
{
ADS_STATUS status ;
const char * attrs [ ] = { " gPLink " , " gPOptions " , NULL } ;
2006-09-22 13:00:59 +04:00
LDAPMessage * res = NULL ;
2006-02-04 01:19:41 +03:00
const char * gp_link ;
2007-08-14 18:47:08 +04:00
uint32_t gp_options ;
2006-02-04 01:19:41 +03:00
ZERO_STRUCTP ( gp_link_struct ) ;
status = ads_search_dn ( ads , & res , link_dn , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo_link: search failed with %s \n " ,
ads_errstr ( status ) ) ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
if ( ads_count_replies ( ads , res ) ! = 1 ) {
DEBUG ( 10 , ( " ads_get_gpo_link: no result \n " ) ) ;
ads_msgfree ( ads , res ) ;
return ADS_ERROR ( LDAP_NO_SUCH_OBJECT ) ;
}
2007-08-14 18:47:08 +04:00
gp_link = ads_pull_string ( ads , mem_ctx , res , " gPLink " ) ;
2006-02-04 01:19:41 +03:00
if ( gp_link = = NULL ) {
DEBUG ( 10 , ( " ads_get_gpo_link: no 'gPLink' attribute found \n " ) ) ;
ads_msgfree ( ads , res ) ;
2007-08-14 18:47:08 +04:00
return ADS_ERROR ( LDAP_NO_SUCH_ATTRIBUTE ) ;
2006-02-04 01:19:41 +03:00
}
2007-07-09 19:48:17 +04:00
/* perfectly legal to have no options */
2006-02-04 01:19:41 +03:00
if ( ! ads_pull_uint32 ( ads , res , " gPOptions " , & gp_options ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo_link: "
" no 'gPOptions' attribute found \n " ) ) ;
2006-02-04 01:19:41 +03:00
gp_options = 0 ;
}
ads_msgfree ( ads , res ) ;
2007-08-14 18:47:08 +04:00
return gpo_parse_gplink ( mem_ctx , gp_link , gp_options , gp_link_struct ) ;
2006-02-04 01:19:41 +03:00
}
2006-09-29 03:04:17 +04:00
/****************************************************************
helper call to add a gp link
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 18:47:08 +04:00
ADS_STATUS ads_add_gpo_link ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
const char * link_dn ,
const char * gpo_dn ,
uint32_t gpo_opt )
2006-02-04 01:19:41 +03:00
{
ADS_STATUS status ;
const char * attrs [ ] = { " gPLink " , NULL } ;
2006-09-22 13:00:59 +04:00
LDAPMessage * res = NULL ;
2006-02-04 01:19:41 +03:00
const char * gp_link , * gp_link_new ;
ADS_MODLIST mods ;
/* although ADS allows to set anything here, we better check here if
* the gpo_dn is sane */
if ( ! strnequal ( gpo_dn , " LDAP://CN={ " , strlen ( " LDAP://CN={ " ) ) ! = 0 ) {
2007-08-14 18:47:08 +04:00
return ADS_ERROR ( LDAP_INVALID_DN_SYNTAX ) ;
2006-02-04 01:19:41 +03:00
}
status = ads_search_dn ( ads , & res , link_dn , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_add_gpo_link: search failed with %s \n " ,
ads_errstr ( status ) ) ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
if ( ads_count_replies ( ads , res ) ! = 1 ) {
DEBUG ( 10 , ( " ads_add_gpo_link: no result \n " ) ) ;
2006-09-26 20:27:18 +04:00
ads_msgfree ( ads , res ) ;
2006-02-04 01:19:41 +03:00
return ADS_ERROR ( LDAP_NO_SUCH_OBJECT ) ;
}
2007-08-14 18:47:08 +04:00
gp_link = ads_pull_string ( ads , mem_ctx , res , " gPLink " ) ;
2006-02-04 01:19:41 +03:00
if ( gp_link = = NULL ) {
2007-08-14 18:47:08 +04:00
gp_link_new = talloc_asprintf ( mem_ctx , " [%s;%d] " ,
gpo_dn , gpo_opt ) ;
2006-02-04 01:19:41 +03:00
} else {
2007-08-14 18:47:08 +04:00
gp_link_new = talloc_asprintf ( mem_ctx , " %s[%s;%d] " ,
gp_link , gpo_dn , gpo_opt ) ;
2006-02-04 01:19:41 +03:00
}
2006-09-26 20:27:18 +04:00
ads_msgfree ( ads , res ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gp_link_new ) ;
2006-02-04 01:19:41 +03:00
mods = ads_init_mods ( mem_ctx ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( mods ) ;
2006-02-04 01:19:41 +03:00
status = ads_mod_str ( mem_ctx , & mods , " gPLink " , gp_link_new ) ;
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
2007-08-14 18:47:08 +04:00
return ads_gen_mod ( ads , link_dn , mods ) ;
2006-02-04 01:19:41 +03:00
}
2006-09-29 03:04:17 +04:00
/****************************************************************
helper call to delete add a gp link
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-04 01:19:41 +03:00
/* untested & broken */
2007-08-14 18:47:08 +04:00
ADS_STATUS ads_delete_gpo_link ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
const char * link_dn ,
2006-02-04 01:19:41 +03:00
const char * gpo_dn )
{
ADS_STATUS status ;
const char * attrs [ ] = { " gPLink " , NULL } ;
2006-09-22 13:00:59 +04:00
LDAPMessage * res = NULL ;
2006-02-04 01:19:41 +03:00
const char * gp_link , * gp_link_new = NULL ;
ADS_MODLIST mods ;
/* check for a sane gpo_dn */
if ( gpo_dn [ 0 ] ! = ' [ ' ) {
DEBUG ( 10 , ( " ads_delete_gpo_link: first char not: [ \n " ) ) ;
return ADS_ERROR ( LDAP_INVALID_DN_SYNTAX ) ;
}
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
if ( gpo_dn [ strlen ( gpo_dn ) ] ! = ' ] ' ) {
DEBUG ( 10 , ( " ads_delete_gpo_link: last char not: ] \n " ) ) ;
return ADS_ERROR ( LDAP_INVALID_DN_SYNTAX ) ;
}
status = ads_search_dn ( ads , & res , link_dn , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_delete_gpo_link: search failed with %s \n " ,
ads_errstr ( status ) ) ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
if ( ads_count_replies ( ads , res ) ! = 1 ) {
DEBUG ( 10 , ( " ads_delete_gpo_link: no result \n " ) ) ;
2006-09-26 20:27:18 +04:00
ads_msgfree ( ads , res ) ;
2006-02-04 01:19:41 +03:00
return ADS_ERROR ( LDAP_NO_SUCH_OBJECT ) ;
}
2007-08-14 18:47:08 +04:00
gp_link = ads_pull_string ( ads , mem_ctx , res , " gPLink " ) ;
2006-02-04 01:19:41 +03:00
if ( gp_link = = NULL ) {
return ADS_ERROR ( LDAP_NO_SUCH_ATTRIBUTE ) ;
}
/* find link to delete */
2007-08-14 18:47:08 +04:00
/* gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link,
gpo_dn , gpo_opt ) ; */
2006-02-04 01:19:41 +03:00
2006-09-26 20:27:18 +04:00
ads_msgfree ( ads , res ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gp_link_new ) ;
2006-02-04 01:19:41 +03:00
mods = ads_init_mods ( mem_ctx ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( mods ) ;
2006-02-04 01:19:41 +03:00
status = ads_mod_str ( mem_ctx , & mods , " gPLink " , gp_link_new ) ;
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
2007-08-14 18:47:08 +04:00
return ads_gen_mod ( ads , link_dn , mods ) ;
2006-02-04 01:19:41 +03:00
}
2006-09-29 03:04:17 +04:00
/****************************************************************
parse a GROUP_POLICY_OBJECT structure from an LDAPMessage result
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-24 07:15:58 +04:00
ADS_STATUS ads_parse_gpo ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
LDAPMessage * res ,
const char * gpo_dn ,
struct GROUP_POLICY_OBJECT * gpo )
2006-02-04 01:19:41 +03:00
{
ZERO_STRUCTP ( gpo ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( res ) ;
2006-02-04 01:19:41 +03:00
if ( gpo_dn ) {
gpo - > ds_path = talloc_strdup ( mem_ctx , gpo_dn ) ;
} else {
2009-03-18 09:35:03 +03:00
gpo - > ds_path = ads_get_dn ( ads , mem_ctx , res ) ;
2006-02-04 01:19:41 +03:00
}
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > ds_path ) ;
2006-02-04 01:19:41 +03:00
if ( ! ads_pull_uint32 ( ads , res , " versionNumber " , & gpo - > version ) ) {
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
if ( ! ads_pull_uint32 ( ads , res , " flags " , & gpo - > options ) ) {
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
2007-08-14 18:47:08 +04:00
gpo - > file_sys_path = ads_pull_string ( ads , mem_ctx , res ,
" gPCFileSysPath " ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > file_sys_path ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
gpo - > display_name = ads_pull_string ( ads , mem_ctx , res ,
" displayName " ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > display_name ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
gpo - > name = ads_pull_string ( ads , mem_ctx , res ,
" name " ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > name ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
gpo - > machine_extensions = ads_pull_string ( ads , mem_ctx , res ,
" gPCMachineExtensionNames " ) ;
gpo - > user_extensions = ads_pull_string ( ads , mem_ctx , res ,
" gPCUserExtensionNames " ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
ads_pull_sd ( ads , mem_ctx , res , " ntSecurityDescriptor " ,
& gpo - > security_descriptor ) ;
2007-05-11 16:41:11 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > security_descriptor ) ;
2006-02-04 01:19:41 +03:00
return ADS_ERROR ( LDAP_SUCCESS ) ;
}
2006-09-29 03:04:17 +04:00
/****************************************************************
2009-04-07 21:58:47 +04:00
get a GROUP_POLICY_OBJECT structure based on different input parameters
2006-09-29 03:04:17 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-04 01:19:41 +03:00
ADS_STATUS ads_get_gpo ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
const char * gpo_dn ,
const char * display_name ,
const char * guid_name ,
struct GROUP_POLICY_OBJECT * gpo )
{
ADS_STATUS status ;
2006-09-22 13:00:59 +04:00
LDAPMessage * res = NULL ;
2006-02-04 01:19:41 +03:00
char * dn ;
const char * filter ;
2007-08-14 18:47:08 +04:00
const char * attrs [ ] = {
" cn " ,
" displayName " ,
" flags " ,
" gPCFileSysPath " ,
" gPCFunctionalityVersion " ,
" gPCMachineExtensionNames " ,
" gPCUserExtensionNames " ,
" gPCWQLFilter " ,
" name " ,
" ntSecurityDescriptor " ,
" versionNumber " ,
NULL } ;
uint32_t sd_flags = DACL_SECURITY_INFORMATION ;
2006-02-04 01:19:41 +03:00
ZERO_STRUCTP ( gpo ) ;
if ( ! gpo_dn & & ! display_name & & ! guid_name ) {
return ADS_ERROR ( LDAP_NO_SUCH_OBJECT ) ;
}
if ( gpo_dn ) {
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
if ( strnequal ( gpo_dn , " LDAP:// " , strlen ( " LDAP:// " ) ) ! = 0 ) {
gpo_dn = gpo_dn + strlen ( " LDAP:// " ) ;
}
2007-08-14 18:47:08 +04:00
status = ads_search_retry_dn_sd_flags ( ads , & res ,
2007-05-11 16:52:48 +04:00
sd_flags ,
gpo_dn , attrs ) ;
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
} else if ( display_name | | guid_name ) {
2007-08-14 18:47:08 +04:00
filter = talloc_asprintf ( mem_ctx ,
" (&(objectclass=groupPolicyContainer)(%s=%s)) " ,
display_name ? " displayName " : " name " ,
display_name ? display_name : guid_name ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( filter ) ;
2006-02-04 01:19:41 +03:00
2007-05-11 16:52:48 +04:00
status = ads_do_search_all_sd_flags ( ads , ads - > config . bind_path ,
2007-08-14 18:47:08 +04:00
LDAP_SCOPE_SUBTREE , filter ,
2007-05-11 16:52:48 +04:00
attrs , sd_flags , & res ) ;
2006-02-04 01:19:41 +03:00
}
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo: search failed with %s \n " ,
ads_errstr ( status ) ) ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
if ( ads_count_replies ( ads , res ) ! = 1 ) {
DEBUG ( 10 , ( " ads_get_gpo: no result \n " ) ) ;
2006-09-25 03:44:00 +04:00
ads_msgfree ( ads , res ) ;
2006-02-04 01:19:41 +03:00
return ADS_ERROR ( LDAP_NO_SUCH_OBJECT ) ;
}
2009-03-18 09:35:03 +03:00
dn = ads_get_dn ( ads , mem_ctx , res ) ;
2006-02-04 01:19:41 +03:00
if ( dn = = NULL ) {
2006-09-25 03:44:00 +04:00
ads_msgfree ( ads , res ) ;
2006-02-04 01:19:41 +03:00
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
status = ads_parse_gpo ( ads , mem_ctx , res , dn , gpo ) ;
2006-09-25 03:44:00 +04:00
ads_msgfree ( ads , res ) ;
2009-03-18 09:35:03 +03:00
TALLOC_FREE ( dn ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
2006-09-29 03:04:17 +04:00
/****************************************************************
add a gplink to the GROUP_POLICY_OBJECT linked list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-07-09 19:48:17 +04:00
static ADS_STATUS add_gplink_to_gpo_list ( ADS_STRUCT * ads ,
2007-08-14 18:47:08 +04:00
TALLOC_CTX * mem_ctx ,
2007-07-09 19:48:17 +04:00
struct GROUP_POLICY_OBJECT * * gpo_list ,
const char * link_dn ,
struct GP_LINK * gp_link ,
enum GPO_LINK_TYPE link_type ,
2007-10-19 04:40:25 +04:00
bool only_add_forced_gpos ,
2009-03-01 20:44:58 +03:00
const NT_USER_TOKEN * token )
2006-02-04 01:19:41 +03:00
{
ADS_STATUS status ;
int i ;
for ( i = 0 ; i < gp_link - > num_links ; i + + ) {
struct GROUP_POLICY_OBJECT * new_gpo = NULL ;
if ( gp_link - > link_opts [ i ] & GPO_LINK_OPT_DISABLED ) {
DEBUG ( 10 , ( " skipping disabled GPO \n " ) ) ;
continue ;
}
if ( only_add_forced_gpos ) {
2007-08-14 18:47:08 +04:00
if ( ! ( gp_link - > link_opts [ i ] & GPO_LINK_OPT_ENFORCED ) ) {
DEBUG ( 10 , ( " skipping nonenforced GPO link "
" because GPOPTIONS_BLOCK_INHERITANCE "
" has been set \n " ) ) ;
2006-02-04 01:19:41 +03:00
continue ;
} else {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " adding enforced GPO link although "
" the GPOPTIONS_BLOCK_INHERITANCE "
" has been set \n " ) ) ;
2006-02-04 01:19:41 +03:00
}
}
2007-05-11 19:08:05 +04:00
new_gpo = TALLOC_ZERO_P ( mem_ctx , struct GROUP_POLICY_OBJECT ) ;
2006-09-29 03:04:17 +04:00
ADS_ERROR_HAVE_NO_MEMORY ( new_gpo ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
status = ads_get_gpo ( ads , mem_ctx , gp_link - > link_names [ i ] ,
NULL , NULL , new_gpo ) ;
2006-02-04 01:19:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " failed to get gpo: %s \n " ,
gp_link - > link_names [ i ] ) ) ;
2006-02-04 01:19:41 +03:00
return status ;
}
2007-08-14 18:47:08 +04:00
status = ADS_ERROR_NT ( gpo_apply_security_filtering ( new_gpo ,
token ) ) ;
2007-05-11 19:08:05 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " skipping GPO \" %s \" as object "
" has no access to it \n " ,
2007-05-11 19:08:05 +04:00
new_gpo - > display_name ) ) ;
2009-03-01 18:25:57 +03:00
talloc_free ( new_gpo ) ;
2007-05-11 19:08:05 +04:00
continue ;
}
2006-02-04 01:19:41 +03:00
new_gpo - > link = link_dn ;
2007-08-14 18:47:08 +04:00
new_gpo - > link_type = link_type ;
2006-02-04 01:19:41 +03:00
DLIST_ADD ( * gpo_list , new_gpo ) ;
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " add_gplink_to_gplist: added GPLINK #%d %s "
" to GPO list \n " , i , gp_link - > link_names [ i ] ) ) ;
2006-02-04 01:19:41 +03:00
}
return ADS_ERROR ( LDAP_SUCCESS ) ;
}
2007-05-11 17:33:37 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-07-17 13:39:39 +04:00
ADS_STATUS ads_get_sid_token ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
const char * dn ,
2009-03-01 20:44:58 +03:00
NT_USER_TOKEN * * token )
2007-05-11 17:33:37 +04:00
{
ADS_STATUS status ;
DOM_SID object_sid ;
DOM_SID primary_group_sid ;
DOM_SID * ad_token_sids ;
size_t num_ad_token_sids = 0 ;
DOM_SID * token_sids ;
size_t num_token_sids = 0 ;
2009-03-01 20:44:58 +03:00
NT_USER_TOKEN * new_token = NULL ;
2007-05-11 17:33:37 +04:00
int i ;
2007-08-14 18:47:08 +04:00
status = ads_get_tokensids ( ads , mem_ctx , dn ,
2007-05-11 17:33:37 +04:00
& object_sid , & primary_group_sid ,
& ad_token_sids , & num_ad_token_sids ) ;
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
token_sids = TALLOC_ARRAY ( mem_ctx , DOM_SID , 1 ) ;
ADS_ERROR_HAVE_NO_MEMORY ( token_sids ) ;
2008-01-09 02:11:31 +03:00
status = ADS_ERROR_NT ( add_sid_to_array_unique ( mem_ctx ,
& primary_group_sid ,
& token_sids ,
& num_token_sids ) ) ;
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
2007-07-17 13:39:39 +04:00
}
2007-05-11 17:33:37 +04:00
for ( i = 0 ; i < num_ad_token_sids ; i + + ) {
2007-08-14 18:47:08 +04:00
2007-05-11 17:33:37 +04:00
if ( sid_check_is_in_builtin ( & ad_token_sids [ i ] ) ) {
continue ;
}
2008-01-09 02:11:31 +03:00
status = ADS_ERROR_NT ( add_sid_to_array_unique ( mem_ctx ,
& ad_token_sids [ i ] ,
& token_sids ,
& num_token_sids ) ) ;
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
2007-05-11 17:33:37 +04:00
}
}
2008-02-29 16:51:37 +03:00
new_token = create_local_nt_token ( mem_ctx , & object_sid , false ,
2007-07-17 13:39:39 +04:00
num_token_sids , token_sids ) ;
ADS_ERROR_HAVE_NO_MEMORY ( new_token ) ;
2007-05-11 17:33:37 +04:00
* token = new_token ;
2007-07-17 13:39:39 +04:00
debug_nt_user_token ( DBGC_CLASS , 5 , * token ) ;
2007-05-11 17:33:37 +04:00
return ADS_ERROR_LDAP ( LDAP_SUCCESS ) ;
}
2007-08-14 18:47:08 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static ADS_STATUS add_local_policy_to_gpo_list ( TALLOC_CTX * mem_ctx ,
struct GROUP_POLICY_OBJECT * * gpo_list ,
enum GPO_LINK_TYPE link_type )
{
struct GROUP_POLICY_OBJECT * gpo = NULL ;
ADS_ERROR_HAVE_NO_MEMORY ( gpo_list ) ;
gpo = TALLOC_ZERO_P ( mem_ctx , struct GROUP_POLICY_OBJECT ) ;
ADS_ERROR_HAVE_NO_MEMORY ( gpo ) ;
gpo - > name = talloc_strdup ( mem_ctx , " Local Policy " ) ;
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > name ) ;
gpo - > display_name = talloc_strdup ( mem_ctx , " Local Policy " ) ;
ADS_ERROR_HAVE_NO_MEMORY ( gpo - > display_name ) ;
gpo - > link_type = link_type ;
DLIST_ADD ( * gpo_list , gpo ) ;
return ADS_ERROR_NT ( NT_STATUS_OK ) ;
}
2006-09-29 03:04:17 +04:00
/****************************************************************
get the full list of GROUP_POLICY_OBJECTs for a given dn
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 18:47:08 +04:00
ADS_STATUS ads_get_gpo_list ( ADS_STRUCT * ads ,
TALLOC_CTX * mem_ctx ,
2006-02-04 01:19:41 +03:00
const char * dn ,
2007-08-14 18:47:08 +04:00
uint32_t flags ,
2009-03-01 20:44:58 +03:00
const NT_USER_TOKEN * token ,
2006-02-04 01:19:41 +03:00
struct GROUP_POLICY_OBJECT * * gpo_list )
{
/* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
ADS_STATUS status ;
struct GP_LINK gp_link ;
const char * parent_dn , * site_dn , * tmp_dn ;
2008-02-29 16:51:37 +03:00
bool add_only_forced_gpos = false ;
2006-02-04 01:19:41 +03:00
ZERO_STRUCTP ( gpo_list ) ;
2007-07-17 13:39:39 +04:00
if ( ! dn ) {
2009-03-01 16:06:36 +03:00
return ADS_ERROR_NT ( NT_STATUS_INVALID_PARAMETER ) ;
2007-07-17 13:39:39 +04:00
}
2009-09-02 23:21:26 +04:00
if ( ! ads_set_sasl_wrap_flags ( ads , ADS_AUTH_SASL_SIGN ) ) {
return ADS_ERROR ( LDAP_INVALID_CREDENTIALS ) ;
}
2006-02-04 01:19:41 +03:00
DEBUG ( 10 , ( " ads_get_gpo_list: getting GPO list for [%s] \n " , dn ) ) ;
2007-08-14 18:47:08 +04:00
/* (L)ocal */
status = add_local_policy_to_gpo_list ( mem_ctx , gpo_list ,
2008-03-18 23:30:34 +03:00
GP_LINK_LOCAL ) ;
2007-05-11 17:37:51 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
2006-02-04 01:19:41 +03:00
/* (S)ite */
/* are site GPOs valid for users as well ??? */
if ( flags & GPO_LIST_FLAG_MACHINE ) {
2007-08-14 18:47:08 +04:00
status = ads_site_dn_for_machine ( ads , mem_ctx ,
ads - > config . ldap_server_name ,
& site_dn ) ;
2006-02-04 01:19:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo_list: query SITE: [%s] for GPOs \n " ,
site_dn ) ) ;
2006-02-04 01:19:41 +03:00
status = ads_get_gpo_link ( ads , mem_ctx , site_dn , & gp_link ) ;
if ( ADS_ERR_OK ( status ) ) {
2007-07-09 19:48:17 +04:00
2006-02-04 01:19:41 +03:00
if ( DEBUGLEVEL > = 100 ) {
dump_gplink ( ads , mem_ctx , & gp_link ) ;
}
2007-07-09 19:48:17 +04:00
2007-08-14 18:47:08 +04:00
status = add_gplink_to_gpo_list ( ads , mem_ctx , gpo_list ,
site_dn , & gp_link ,
GP_LINK_SITE ,
2007-05-11 17:37:51 +04:00
add_only_forced_gpos ,
token ) ;
2006-02-04 01:19:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
2007-07-09 19:48:17 +04:00
2006-02-04 01:19:41 +03:00
if ( flags & GPO_LIST_FLAG_SITEONLY ) {
return ADS_ERROR ( LDAP_SUCCESS ) ;
}
2007-07-09 19:48:17 +04:00
2006-02-04 01:19:41 +03:00
/* inheritance can't be blocked at the site level */
}
}
tmp_dn = dn ;
2007-08-14 18:47:08 +04:00
while ( ( parent_dn = ads_parent_dn ( tmp_dn ) ) & &
( ! strequal ( parent_dn , ads_parent_dn ( ads - > config . bind_path ) ) ) ) {
2006-02-04 01:19:41 +03:00
/* (D)omain */
/* An account can just be a member of one domain */
if ( strncmp ( parent_dn , " DC= " , strlen ( " DC= " ) ) = = 0 ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo_list: query DC: [%s] for GPOs \n " ,
parent_dn ) ) ;
2006-02-04 01:19:41 +03:00
2007-08-14 18:47:08 +04:00
status = ads_get_gpo_link ( ads , mem_ctx , parent_dn ,
& gp_link ) ;
2006-02-04 01:19:41 +03:00
if ( ADS_ERR_OK ( status ) ) {
2007-08-14 18:47:08 +04:00
2006-02-04 01:19:41 +03:00
if ( DEBUGLEVEL > = 100 ) {
dump_gplink ( ads , mem_ctx , & gp_link ) ;
}
/* block inheritance from now on */
2007-08-14 18:47:08 +04:00
if ( gp_link . gp_opts &
GPOPTIONS_BLOCK_INHERITANCE ) {
2008-02-29 16:51:37 +03:00
add_only_forced_gpos = true ;
2006-02-04 01:19:41 +03:00
}
2007-08-14 18:47:08 +04:00
status = add_gplink_to_gpo_list ( ads ,
mem_ctx ,
gpo_list ,
parent_dn ,
& gp_link ,
GP_LINK_DOMAIN ,
add_only_forced_gpos ,
token ) ;
2006-02-04 01:19:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
}
}
tmp_dn = parent_dn ;
}
/* reset dn again */
tmp_dn = dn ;
2007-08-14 18:47:08 +04:00
while ( ( parent_dn = ads_parent_dn ( tmp_dn ) ) & &
( ! strequal ( parent_dn , ads_parent_dn ( ads - > config . bind_path ) ) ) ) {
2006-02-04 01:19:41 +03:00
/* (O)rganizational(U)nit */
/* An account can be a member of more OUs */
if ( strncmp ( parent_dn , " OU= " , strlen ( " OU= " ) ) = = 0 ) {
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " ads_get_gpo_list: query OU: [%s] for GPOs \n " ,
parent_dn ) ) ;
status = ads_get_gpo_link ( ads , mem_ctx , parent_dn ,
& gp_link ) ;
2006-02-04 01:19:41 +03:00
if ( ADS_ERR_OK ( status ) ) {
if ( DEBUGLEVEL > = 100 ) {
dump_gplink ( ads , mem_ctx , & gp_link ) ;
}
/* block inheritance from now on */
2007-08-14 18:47:08 +04:00
if ( gp_link . gp_opts &
GPOPTIONS_BLOCK_INHERITANCE ) {
2008-02-29 16:51:37 +03:00
add_only_forced_gpos = true ;
2006-02-04 01:19:41 +03:00
}
2007-08-14 18:47:08 +04:00
status = add_gplink_to_gpo_list ( ads ,
mem_ctx ,
gpo_list ,
parent_dn ,
& gp_link ,
GP_LINK_OU ,
add_only_forced_gpos ,
token ) ;
2006-02-04 01:19:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
return status ;
}
}
}
tmp_dn = parent_dn ;
} ;
return ADS_ERROR ( LDAP_SUCCESS ) ;
}
2006-09-22 13:34:25 +04:00
# endif /* HAVE_LDAP */