2010-06-07 20:10:28 +04:00
# Adds a new user to a Samba4 server
# Copyright Jelmer Vernooij 2008
#
# Based on the original in EJS:
# Copyright Andrew Tridgell 2005
#
# 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
from samba . netcmd import Command , SuperCommand , CommandError , Option
import ldb
2012-05-02 00:17:33 +04:00
from samba . ndr import ndr_unpack
from samba . dcerpc import security
2010-06-07 20:10:28 +04:00
from getpass import getpass
from samba . auth import system_session
from samba . samdb import SamDB
from samba . dsdb import (
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ,
GTYPE_SECURITY_GLOBAL_GROUP ,
GTYPE_SECURITY_UNIVERSAL_GROUP ,
GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP ,
GTYPE_DISTRIBUTION_GLOBAL_GROUP ,
GTYPE_DISTRIBUTION_UNIVERSAL_GROUP ,
)
security_group = dict ( { " Domain " : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP , " Global " : GTYPE_SECURITY_GLOBAL_GROUP , " Universal " : GTYPE_SECURITY_UNIVERSAL_GROUP } )
distribution_group = dict ( { " Domain " : GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP , " Global " : GTYPE_DISTRIBUTION_GLOBAL_GROUP , " Universal " : GTYPE_DISTRIBUTION_UNIVERSAL_GROUP } )
class cmd_group_add ( Command ) :
2012-10-08 14:32:58 +04:00
""" Creates a new AD group.
2011-11-10 01:33:37 +04:00
This command creates a new Active Directory group . The groupname specified on the command is a unique sAMAccountName .
An Active Directory group may contain user and computer accounts as well as other groups . An administrator creates a group and adds members to that group so they can be managed as a single entity . This helps to simplify security and system administration .
Groups may also be used to establish email distribution lists , using - - group - type = Distribution .
Groups are located in domains in organizational units ( OUs ) . The group ' s scope is a characteristic of the group that designates the extent to which the group is applied within the domain tree or forest.
The group location ( OU ) , type ( security or distribution ) and scope may all be specified on the samba - tool command when the group is created .
The command may be run from the root userid or another authorized userid . The
- H or - - URL = option can be used to execute the command on a remote server .
Example1 :
samba - tool group add Group1 - H ldap : / / samba . samdom . example . com - - description = ' Simple group '
Example1 adds a new group with the name Group1 added to the Users container on a remote LDAP server . The - U parameter is used to pass the userid and password of a user that exists on the remote server and is authorized to issue the command on that server . It defaults to the security type and global scope .
Example2 :
sudo samba - tool group add Group2 - - group - type = Distribution
Example2 adds a new distribution group to the local server . The command is run under root using the sudo command .
"""
2010-06-07 20:10:28 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <groupname> [options] "
2010-06-07 20:10:28 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" versionopts " : options . VersionOptions ,
" credopts " : options . CredentialsOptions ,
}
2010-06-07 20:10:28 +04:00
takes_options = [
2011-07-25 19:56:10 +04:00
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
2010-06-07 20:10:28 +04:00
Option ( " --groupou " ,
2011-09-13 02:20:17 +04:00
help = " Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created " ,
type = str ) ,
2010-06-07 20:10:28 +04:00
Option ( " --group-scope " , type = " choice " , choices = [ " Domain " , " Global " , " Universal " ] ,
help = " Group scope (Domain | Global | Universal) " ) ,
Option ( " --group-type " , type = " choice " , choices = [ " Security " , " Distribution " ] ,
help = " Group type (Security | Distribution) " ) ,
Option ( " --description " , help = " Group ' s description " , type = str ) ,
Option ( " --mail-address " , help = " Group ' s email address " , type = str ) ,
Option ( " --notes " , help = " Groups ' s notes " , type = str ) ,
]
takes_args = [ " groupname " ]
def run ( self , groupname , credopts = None , sambaopts = None ,
versionopts = None , H = None , groupou = None , group_scope = None ,
group_type = None , description = None , mail_address = None , notes = None ) :
2010-06-08 23:33:56 +04:00
if ( group_type or " Security " ) == " Security " :
2012-07-03 05:27:21 +04:00
gtype = security_group . get ( group_scope , GTYPE_SECURITY_GLOBAL_GROUP )
2010-06-07 20:10:28 +04:00
else :
2012-07-03 05:27:21 +04:00
gtype = distribution_group . get ( group_scope , GTYPE_DISTRIBUTION_GLOBAL_GROUP )
2010-06-07 20:10:28 +04:00
lp = sambaopts . get_loadparm ( )
2010-12-08 00:20:54 +03:00
creds = credopts . get_credentials ( lp , fallback_machine = True )
2010-06-07 20:10:28 +04:00
try :
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
samdb . newgroup ( groupname , groupou = groupou , grouptype = gtype ,
description = description , mailaddress = mail_address , notes = notes )
2010-11-29 06:15:57 +03:00
except Exception , e :
2011-10-13 02:36:44 +04:00
# FIXME: catch more specific exception
2010-11-29 06:15:57 +03:00
raise CommandError ( ' Failed to create group " %s " ' % groupname , e )
2011-10-13 02:36:44 +04:00
self . outf . write ( " Added group %s \n " % groupname )
2010-06-07 20:10:28 +04:00
2010-06-08 23:33:56 +04:00
2010-06-07 20:10:28 +04:00
class cmd_group_delete ( Command ) :
2012-10-08 14:32:58 +04:00
""" Deletes an AD group.
2011-11-10 01:33:37 +04:00
The command deletes an existing AD group from the Active Directory domain . The groupname specified on the command is the sAMAccountName .
Deleting a group is a permanent operation . When a group is deleted , all permissions and rights that users in the group had inherited from the group account are deleted as well .
The command may be run from the root userid or another authorized userid . The - H or - - URL option can be used to execute the command on a remote server .
Example1 :
samba - tool group delete Group1 - H ldap : / / samba . samdom . example . com - Uadministrator % passw0rd
Example1 shows how to delete an AD group from a remote LDAP server . The - U parameter is used to pass the userid and password of a user that exists on the remote server and is authorized to issue the command on that server .
Example2 :
sudo samba - tool group delete Group2
Example2 deletes group Group2 from the local server . The command is run under root using the sudo command .
"""
2010-06-07 20:10:28 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <groupname> [options] "
2010-06-07 20:10:28 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" versionopts " : options . VersionOptions ,
" credopts " : options . CredentialsOptions ,
}
2010-06-07 20:10:28 +04:00
takes_options = [
2011-07-25 19:56:10 +04:00
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
2010-06-07 20:10:28 +04:00
]
takes_args = [ " groupname " ]
def run ( self , groupname , credopts = None , sambaopts = None , versionopts = None , H = None ) :
lp = sambaopts . get_loadparm ( )
2010-12-08 00:20:54 +03:00
creds = credopts . get_credentials ( lp , fallback_machine = True )
2010-06-07 20:10:28 +04:00
try :
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
samdb . deletegroup ( groupname )
2010-11-29 06:15:57 +03:00
except Exception , e :
2011-10-13 02:36:44 +04:00
# FIXME: catch more specific exception
2010-11-29 06:15:57 +03:00
raise CommandError ( ' Failed to remove group " %s " ' % groupname , e )
2011-10-13 02:36:44 +04:00
self . outf . write ( " Deleted group %s \n " % groupname )
2010-06-07 20:10:28 +04:00
2010-06-08 23:33:56 +04:00
2010-06-07 20:10:28 +04:00
class cmd_group_add_members ( Command ) :
2012-10-08 14:32:58 +04:00
""" Add members to an AD group.
2011-11-10 01:33:37 +04:00
This command adds one or more members to an existing Active Directory group . The command accepts one or more group member names seperated by commas . A group member may be a user or computer account or another Active Directory group .
When a member is added to a group the member may inherit permissions and rights from the group . Likewise , when permission or rights of a group are changed , the changes may reflect in the members through inheritance .
Example1 :
samba - tool group addmembers supergroup Group1 , Group2 , User1 - H ldap : / / samba . samdom . example . com - Uadministrator % passw0rd
Example1 shows how to add two groups , Group1 and Group2 and one user account , User1 , to the existing AD group named supergroup . The command will be run on a remote server specified with the - H . The - U parameter is used to pass the userid and password of a user authorized to issue the command on the remote server .
Example2 :
sudo samba - tool group addmembers supergroup User2
Example2 shows how to add a single user account , User2 , to the supergroup AD group . It uses the sudo command to run as root when issuing the command .
"""
2010-06-07 20:10:28 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <groupname> <listofmembers> [options] "
2010-06-07 20:10:28 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" versionopts " : options . VersionOptions ,
" credopts " : options . CredentialsOptions ,
}
2010-06-07 20:10:28 +04:00
takes_options = [
2011-07-25 19:56:10 +04:00
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
2010-06-07 20:10:28 +04:00
]
takes_args = [ " groupname " , " listofmembers " ]
def run ( self , groupname , listofmembers , credopts = None , sambaopts = None ,
versionopts = None , H = None ) :
lp = sambaopts . get_loadparm ( )
2010-12-08 00:20:54 +03:00
creds = credopts . get_credentials ( lp , fallback_machine = True )
2010-06-07 20:10:28 +04:00
try :
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
2012-06-19 14:43:08 +04:00
groupmembers = listofmembers . split ( ' , ' )
samdb . add_remove_group_members ( groupname , groupmembers ,
add_members_operation = True )
2010-11-29 06:15:57 +03:00
except Exception , e :
2011-10-13 02:36:44 +04:00
# FIXME: catch more specific exception
raise CommandError ( ' Failed to add members " %s " to group " %s " ' % (
listofmembers , groupname ) , e )
self . outf . write ( " Added members to group %s \n " % groupname )
2010-06-07 20:10:28 +04:00
2010-06-08 23:33:56 +04:00
2010-06-07 20:10:28 +04:00
class cmd_group_remove_members ( Command ) :
2012-10-08 14:32:58 +04:00
""" Remove members from an AD group.
2011-11-10 01:33:37 +04:00
This command removes one or more members from an existing Active Directory group . The command accepts one or more group member names seperated by commas . A group member may be a user or computer account or another Active Directory group that is a member of the group specified on the command .
When a member is removed from a group , inherited permissions and rights will no longer apply to the member .
Example1 :
samba - tool group removemembers supergroup Group1 - H ldap : / / samba . samdom . example . com - Uadministrator % passw0rd
Example1 shows how to remove Group1 from supergroup . The command will run on the remote server specified on the - H parameter . The - U parameter is used to pass the userid and password of a user authorized to issue the command on the remote server .
Example2 :
sudo samba - tool group removemembers supergroup User1
Example2 shows how to remove a single user account , User2 , from the supergroup AD group . It uses the sudo command to run as root when issuing the command .
"""
2010-06-07 20:10:28 +04:00
2011-10-14 01:27:22 +04:00
synopsis = " % prog <groupname> <listofmembers> [options] "
2010-06-07 20:10:28 +04:00
2012-02-06 19:33:38 +04:00
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" versionopts " : options . VersionOptions ,
" credopts " : options . CredentialsOptions ,
}
2010-06-07 20:10:28 +04:00
takes_options = [
2011-07-25 19:56:10 +04:00
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
2010-06-07 20:10:28 +04:00
]
takes_args = [ " groupname " , " listofmembers " ]
def run ( self , groupname , listofmembers , credopts = None , sambaopts = None ,
versionopts = None , H = None ) :
lp = sambaopts . get_loadparm ( )
2010-12-08 00:20:54 +03:00
creds = credopts . get_credentials ( lp , fallback_machine = True )
2010-06-07 20:10:28 +04:00
try :
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
2012-06-19 14:43:08 +04:00
samdb . add_remove_group_members ( groupname , listofmembers . split ( " , " ) ,
add_members_operation = False )
2010-11-29 06:15:57 +03:00
except Exception , e :
2011-10-13 02:36:44 +04:00
# FIXME: Catch more specific exception
2010-11-29 06:15:57 +03:00
raise CommandError ( ' Failed to remove members " %s " from group " %s " ' % ( listofmembers , groupname ) , e )
2011-10-13 02:36:44 +04:00
self . outf . write ( " Removed members from group %s \n " % groupname )
2010-06-07 20:10:28 +04:00
2012-05-02 00:17:33 +04:00
2012-03-09 01:39:24 +04:00
class cmd_group_list ( Command ) :
2012-10-08 14:32:58 +04:00
""" List all groups. """
2012-03-09 01:39:24 +04:00
synopsis = " % prog [options] "
takes_options = [
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
]
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
def run ( self , sambaopts = None , credopts = None , versionopts = None , H = None ) :
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp , fallback_machine = True )
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
domain_dn = samdb . domain_dn ( )
res = samdb . search ( domain_dn , scope = ldb . SCOPE_SUBTREE ,
expression = ( " (objectClass=group) " ) ,
attrs = [ " samaccountname " ] )
if ( len ( res ) == 0 ) :
return
for msg in res :
self . outf . write ( " %s \n " % msg . get ( " samaccountname " , idx = 0 ) )
2010-06-08 23:33:56 +04:00
2012-05-02 00:17:33 +04:00
class cmd_group_list_members ( Command ) :
2012-10-08 14:32:58 +04:00
""" List all members of an AD group.
2012-05-02 00:17:33 +04:00
This command lists members from an existing Active Directory group . The command accepts one group name .
Example1 :
samba - tool group listmembers \" Domain Users \" -H ldap://samba.samdom.example.com -Uadministrator % passw0rd
"""
synopsis = " % prog <groupname> [options] "
takes_options = [
Option ( " -H " , " --URL " , help = " LDB URL for database or target server " , type = str ,
metavar = " URL " , dest = " H " ) ,
]
takes_optiongroups = {
" sambaopts " : options . SambaOptions ,
" credopts " : options . CredentialsOptions ,
" versionopts " : options . VersionOptions ,
}
takes_args = [ " groupname " ]
def run ( self , groupname , credopts = None , sambaopts = None , versionopts = None , H = None ) :
lp = sambaopts . get_loadparm ( )
creds = credopts . get_credentials ( lp , fallback_machine = True )
try :
samdb = SamDB ( url = H , session_info = system_session ( ) ,
credentials = creds , lp = lp )
search_filter = " (&(objectClass=group)(samaccountname= %s )) " % groupname
res = samdb . search ( samdb . domain_dn ( ) , scope = ldb . SCOPE_SUBTREE ,
expression = ( search_filter ) ,
attrs = [ " objectSid " ] )
if ( len ( res ) != 1 ) :
return
group_dn = res [ 0 ] . get ( ' dn ' , idx = 0 )
object_sid = res [ 0 ] . get ( ' objectSid ' , idx = 0 )
object_sid = ndr_unpack ( security . dom_sid , object_sid )
( group_dom_sid , rid ) = object_sid . split ( )
search_filter = " (|(primaryGroupID= %s )(memberOf= %s )) " % ( rid , group_dn )
res = samdb . search ( samdb . domain_dn ( ) , scope = ldb . SCOPE_SUBTREE ,
expression = ( search_filter ) ,
2012-05-09 17:24:01 +04:00
attrs = [ " samAccountName " , " cn " ] )
2012-05-02 00:17:33 +04:00
if ( len ( res ) == 0 ) :
return
for msg in res :
2012-05-09 17:24:01 +04:00
member_name = msg . get ( " samAccountName " , idx = 0 )
if member_name is None :
member_name = msg . get ( " cn " , idx = 0 )
self . outf . write ( " %s \n " % member_name )
2012-05-02 00:17:33 +04:00
except Exception , e :
raise CommandError ( ' Failed to list members of " %s " group ' % groupname , e )
2010-06-07 20:10:28 +04:00
class cmd_group ( SuperCommand ) :
""" Group management """
subcommands = { }
subcommands [ " add " ] = cmd_group_add ( )
subcommands [ " delete " ] = cmd_group_delete ( )
subcommands [ " addmembers " ] = cmd_group_add_members ( )
subcommands [ " removemembers " ] = cmd_group_remove_members ( )
2012-03-09 01:39:24 +04:00
subcommands [ " list " ] = cmd_group_list ( )
2012-05-02 00:17:33 +04:00
subcommands [ " listmembers " ] = cmd_group_list_members ( )