2011-06-24 18:59:24 +04:00
# delegation management
#
# Copyright Matthieu Patou mat@samba.org 2010
# Copyright Stefan Metzmacher metze@samba.org 2011
# Copyright Bjoern Baumbach bb@sernet.de 2011
#
# 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/>.
#
import samba . getopt as options
import ldb
from samba import provision
from samba import dsdb
from samba . samdb import SamDB
from samba . auth import system_session
2011-09-07 19:11:38 +04:00
from samba . netcmd . common import _get_user_realm_domain
2011-06-24 18:59:24 +04:00
from samba . netcmd import (
Command ,
CommandError ,
SuperCommand ,
Option
)
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation_show ( Command ) :
""" Show the delegation setting of an account. """
2011-10-14 01:27:22 +04:00
2011-10-21 19:35:36 +04:00
synopsis = " % prog <accountname> [options] "
2011-06-24 18:59:24 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
2011-06-24 18:59:24 +04:00
takes_args = [ " accountname " ]
def run ( self , accountname , credopts = None , sambaopts = None , versionopts = None ) :
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
paths = provision . provision_paths_from_lp ( lp , lp . get ( " realm " ) )
sam = SamDB ( paths . samdb , session_info = system_session ( ) ,
credentials = creds , lp = lp )
# TODO once I understand how, use the domain info to naildown
# to the correct domain
( cleanedaccount , realm , domain ) = _get_user_realm_domain ( accountname )
2011-10-21 19:49:29 +04:00
res = sam . search ( expression = " sAMAccountName= %s " %
ldb . binary_encode ( cleanedaccount ) ,
scope = ldb . SCOPE_SUBTREE ,
attrs = [ " userAccountControl " , " msDS-AllowedToDelegateTo " ] )
if len ( res ) == 0 :
raise CommandError ( " Unable to find account name ' %s ' " % accountname )
assert ( len ( res ) == 1 )
2011-06-24 18:59:24 +04:00
uac = int ( res [ 0 ] . get ( " userAccountControl " ) [ 0 ] )
allowed = res [ 0 ] . get ( " msDS-AllowedToDelegateTo " )
2011-10-13 02:19:51 +04:00
self . outf . write ( " Account-DN: %s \n " % str ( res [ 0 ] . dn ) )
self . outf . write ( " UF_TRUSTED_FOR_DELEGATION: %s \n "
% bool ( uac & dsdb . UF_TRUSTED_FOR_DELEGATION ) )
self . outf . write ( " UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s \n " %
bool ( uac & dsdb . UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION ) )
2011-06-24 18:59:24 +04:00
2011-10-13 02:19:51 +04:00
if allowed is not None :
2011-06-24 18:59:24 +04:00
for a in allowed :
2011-10-13 02:19:51 +04:00
self . outf . write ( " msDS-AllowedToDelegateTo: %s \n " % a )
2011-06-24 18:59:24 +04:00
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation_for_any_service ( Command ) :
""" Set/unset UF_TRUSTED_FOR_DELEGATION for an account. """
2011-09-02 21:10:05 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <accountname> [(on|off)] [options] "
2011-06-24 18:59:24 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
2011-06-24 18:59:24 +04:00
takes_args = [ " accountname " , " onoff " ]
def run ( self , accountname , onoff , credopts = None , sambaopts = None , versionopts = None ) :
on = False
if onoff == " on " :
on = True
elif onoff == " off " :
on = False
else :
2011-10-21 19:57:34 +04:00
raise CommandError ( " invalid argument: ' %s ' (choose from ' on ' , ' off ' ) " % onoff )
2011-06-24 18:59:24 +04:00
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
paths = provision . provision_paths_from_lp ( lp , lp . get ( " realm " ) )
sam = SamDB ( paths . samdb , session_info = system_session ( ) ,
credentials = creds , lp = lp )
# TODO once I understand how, use the domain info to naildown
# to the correct domain
( cleanedaccount , realm , domain ) = _get_user_realm_domain ( accountname )
2011-09-13 02:19:45 +04:00
search_filter = " sAMAccountName= %s " % ldb . binary_encode ( cleanedaccount )
2011-06-24 18:59:24 +04:00
flag = dsdb . UF_TRUSTED_FOR_DELEGATION
try :
2011-10-21 20:05:07 +04:00
sam . toggle_userAccountFlags ( search_filter , flag ,
flags_str = " Trusted-for-Delegation " ,
on = on , strict = True )
2011-06-24 18:59:24 +04:00
except Exception , err :
raise CommandError ( err )
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation_for_any_protocol ( Command ) :
""" Set/unset UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (S4U2Proxy) for an account. """
2011-09-02 21:10:05 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <accountname> [(on|off)] [options] "
2011-06-24 18:59:24 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
2011-06-24 18:59:24 +04:00
takes_args = [ " accountname " , " onoff " ]
def run ( self , accountname , onoff , credopts = None , sambaopts = None , versionopts = None ) :
on = False
if onoff == " on " :
on = True
elif onoff == " off " :
on = False
else :
2011-10-21 19:57:34 +04:00
raise CommandError ( " invalid argument: ' %s ' (choose from ' on ' , ' off ' ) " % onoff )
2011-06-24 18:59:24 +04:00
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
paths = provision . provision_paths_from_lp ( lp , lp . get ( " realm " ) )
sam = SamDB ( paths . samdb , session_info = system_session ( ) ,
credentials = creds , lp = lp )
# TODO once I understand how, use the domain info to naildown
# to the correct domain
( cleanedaccount , realm , domain ) = _get_user_realm_domain ( accountname )
2011-09-13 02:19:45 +04:00
search_filter = " sAMAccountName= %s " % ldb . binary_encode ( cleanedaccount )
2011-06-24 18:59:24 +04:00
flag = dsdb . UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
try :
2011-10-21 20:05:07 +04:00
sam . toggle_userAccountFlags ( search_filter , flag ,
flags_str = " Trusted-to-Authenticate-for-Delegation " ,
on = on , strict = True )
2011-06-24 18:59:24 +04:00
except Exception , err :
raise CommandError ( err )
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation_add_service ( Command ) :
""" Add a service principal as msDS-AllowedToDelegateTo """
2011-09-02 21:10:05 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <accountname> <principal> [options] "
2011-06-24 18:59:24 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
2011-06-24 18:59:24 +04:00
takes_args = [ " accountname " , " principal " ]
def run ( self , accountname , principal , credopts = None , sambaopts = None , versionopts = None ) :
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
paths = provision . provision_paths_from_lp ( lp , lp . get ( " realm " ) )
sam = SamDB ( paths . samdb , session_info = system_session ( ) ,
credentials = creds , lp = lp )
# TODO once I understand how, use the domain info to naildown
# to the correct domain
( cleanedaccount , realm , domain ) = _get_user_realm_domain ( accountname )
2011-10-21 19:49:29 +04:00
res = sam . search ( expression = " sAMAccountName= %s " %
ldb . binary_encode ( cleanedaccount ) ,
scope = ldb . SCOPE_SUBTREE ,
attrs = [ " msDS-AllowedToDelegateTo " ] )
if len ( res ) == 0 :
raise CommandError ( " Unable to find account name ' %s ' " % accountname )
assert ( len ( res ) == 1 )
2011-06-24 18:59:24 +04:00
msg = ldb . Message ( )
msg . dn = res [ 0 ] . dn
msg [ " msDS-AllowedToDelegateTo " ] = ldb . MessageElement ( [ principal ] ,
2011-10-21 19:49:29 +04:00
ldb . FLAG_MOD_ADD ,
" msDS-AllowedToDelegateTo " )
2011-06-24 18:59:24 +04:00
try :
sam . modify ( msg )
except Exception , err :
raise CommandError ( err )
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation_del_service ( Command ) :
2011-09-02 21:10:05 +04:00
""" Delete a service principal as msDS-AllowedToDelegateTo """
2011-10-14 01:27:22 +04:00
synopsis = " % prog <accountname> <principal> [options] "
2011-06-24 18:59:24 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
2011-06-24 18:59:24 +04:00
takes_args = [ " accountname " , " principal " ]
def run ( self , accountname , principal , credopts = None , sambaopts = None , versionopts = None ) :
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp )
paths = provision . provision_paths_from_lp ( lp , lp . get ( " realm " ) )
sam = SamDB ( paths . samdb , session_info = system_session ( ) ,
credentials = creds , lp = lp )
# TODO once I understand how, use the domain info to naildown
# to the correct domain
( cleanedaccount , realm , domain ) = _get_user_realm_domain ( accountname )
2011-10-21 19:49:29 +04:00
res = sam . search ( expression = " sAMAccountName= %s " %
ldb . binary_encode ( cleanedaccount ) ,
scope = ldb . SCOPE_SUBTREE ,
attrs = [ " msDS-AllowedToDelegateTo " ] )
if len ( res ) == 0 :
raise CommandError ( " Unable to find account name ' %s ' " % accountname )
assert ( len ( res ) == 1 )
2011-06-24 18:59:24 +04:00
msg = ldb . Message ( )
msg . dn = res [ 0 ] . dn
msg [ " msDS-AllowedToDelegateTo " ] = ldb . MessageElement ( [ principal ] ,
2011-10-21 19:49:29 +04:00
ldb . FLAG_MOD_DELETE ,
" msDS-AllowedToDelegateTo " )
2011-06-24 18:59:24 +04:00
try :
sam . modify ( msg )
except Exception , err :
raise CommandError ( err )
2011-09-02 21:10:05 +04:00
2011-06-24 18:59:24 +04:00
class cmd_delegation ( SuperCommand ) :
2011-09-02 21:10:05 +04:00
""" Delegation management """
2011-06-24 18:59:24 +04:00
subcommands = { }
subcommands [ " show " ] = cmd_delegation_show ( )
subcommands [ " for-any-service " ] = cmd_delegation_for_any_service ( )
subcommands [ " for-any-protocol " ] = cmd_delegation_for_any_protocol ( )
subcommands [ " add-service " ] = cmd_delegation_add_service ( )
subcommands [ " del-service " ] = cmd_delegation_del_service ( )