1#!/usr/bin/perl -w 2 3# This code was developped by IDEALX (http://IDEALX.org/) and 4# contributors (their names can be found in the CONTRIBUTORS file). 5# 6# Copyright (C) 2001-2002 IDEALX 7# 8# This program is free software; you can redistribute it and/or 9# modify it under the terms of the GNU General Public License 10# as published by the Free Software Foundation; either version 2 11# of the License, or (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program; if not, write to the Free Software 20# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 21# USA. 22 23# Purpose of smbldap-groupmod : group (posix) modification 24 25 26use strict; 27use FindBin; 28use FindBin qw($RealBin); 29use lib "$RealBin/"; 30use smbldap_tools; 31use smbldap_conf; 32 33##################### 34 35use Getopt::Std; 36my %Options; 37 38my $ok = getopts('ag:n:m:or:s:t:x:?', \%Options); 39if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { 40 print "Usage: $0 [-a] [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] [-r rid] [-s sid] [-t type] groupname\n"; 41 print " -a add automatic group mapping entry\n"; 42 print " -g new gid\n"; 43 print " -o gid is not unique\n"; 44 print " -n new group name\n"; 45 print " -m add members (comma delimited)\n"; 46 print " -r group-rid\n"; 47 print " -s group-sid\n"; 48 print " -t group-type\n"; 49 print " -x delete members (comma delimted)\n"; 50 print " -? show this help message\n"; 51 exit (1); 52} 53 54my $groupName = $ARGV[0]; 55my $group_entry; 56 57if (! ($group_entry = read_group_entry($groupName))) { 58 print "$0: group $groupName doesn't exist\n"; 59 exit (6); 60} 61 62my $newname = $Options{'n'}; 63 64my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; 65 66if ($nscd_status == 0) { 67 system "/etc/init.d/nscd restart > /dev/null 2>&1"; 68} 69 70my $gid = getgrnam($groupName); 71unless (defined ($gid)) { 72 print "$0: group $groupName not found!\n"; 73 exit(6); 74} 75 76my $tmp; 77if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { 78 if (!defined($Options{'o'})) { 79 if (defined(getgrgid($tmp))) { 80 print "$0: gid $tmp exists\n"; 81 exit (6); 82 } 83 } 84 if (!($gid == $tmp)) { 85 my $ldap_master=connect_ldap_master(); 86 my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", 87 changes => [ 88 replace => [gidNumber => $tmp] 89 ] 90 ); 91 $modify->code && die "failed to modify entry: ", $modify->error ; 92 # take down session 93 $ldap_master->unbind 94 } 95} 96 97 98if (defined($newname)) { 99 my $ldap_master=connect_ldap_master(); 100 my $modify = $ldap_master->moddn ( 101 "cn=$groupName,$groupsdn", 102 newrdn => "cn=$newname", 103 deleteoldrdn => "1", 104 newsuperior => "$groupsdn" 105 ); 106 $modify->code && die "failed to modify entry: ", $modify->error ; 107 # take down session 108 $ldap_master->unbind 109} 110 111# Add members 112if (defined($Options{'m'})) { 113 my $members = $Options{'m'}; 114 my @members = split( /,/, $members ); 115 my $member; 116 foreach $member ( @members ) { 117 my $group_entry=read_group_entry($groupName); 118 $groupsdn=$group_entry->dn; 119 if (is_unix_user($member)) { 120 if (is_group_member($groupsdn,$member)) { 121 print "User $member already in the group\n"; 122 } else { 123 print "adding user $member to group $groupName\n"; 124 my $ldap_master=connect_ldap_master(); 125 my $modify = $ldap_master->modify ($groupsdn, 126 changes => [ 127 add => [memberUid => $member] 128 ] 129 ); 130 $modify->code && warn "failed to add entry: ", $modify->error ; 131 # take down session 132 $ldap_master->unbind 133 } 134 } else { 135 print "User $member does not exist: create it first !\n"; 136 } 137 } 138} 139 140# Delete members 141if (defined($Options{'x'})) { 142 my $members = $Options{'x'}; 143 my @members = split( /,/, $members ); 144 my $member; 145 foreach $member ( @members ) { 146 my $group_entry=read_group_entry($groupName); 147 $groupsdn=$group_entry->dn; 148 if (is_group_member("$groupsdn",$member)) { 149 print "deleting user $member from group $groupName\n"; 150 my $ldap_master=connect_ldap_master(); 151 my $modify = $ldap_master->modify ($groupsdn, 152 changes => [ 153 delete => [memberUid => $member] 154 ] 155 ); 156 $modify->code && warn "failed to delete entry: ", $modify->error ; 157 # take down session 158 $ldap_master->unbind 159 } else { 160 print "User $member is not in the group $groupName!\n"; 161 } 162 } 163} 164 165my $group_sid; 166if ($tmp= $Options{'s'}) { 167 if ($tmp =~ /^S-(?:\d+-)+\d+$/) { 168 $group_sid = $tmp; 169 } else { 170 print "$0: illegal group-rid $tmp\n"; 171 exit(7); 172 } 173} elsif ($Options{'r'} || $Options{'a'}) { 174 my $group_rid; 175 if ($tmp= $Options{'r'}) { 176 if ($tmp =~ /^\d+$/) { 177 $group_rid = $tmp; 178 } else { 179 print "$0: illegal group-rid $tmp\n"; 180 exit(7); 181 } 182 } else { 183 # algorithmic mapping 184 $group_rid = 2*$gid+1001; 185 } 186 $group_sid = $SID.'-'.$group_rid; 187} 188 189if ($group_sid) { 190 my @adds; 191 my @mods; 192 push(@mods, 'sambaSID' => $group_sid); 193 194 if ($tmp= $Options{'t'}) { 195 my $group_type; 196 if (defined($group_type = &group_type_by_name($tmp))) { 197 push(@mods, 'sambaGroupType' => $group_type); 198 } else { 199 print "$0: unknown group type $tmp\n"; 200 exit(8); 201 } 202 } else { 203 if (! defined($group_entry->get_value('sambaGroupType'))) { 204 push(@mods, 'sambaGroupType' => group_type_by_name('domain')); 205 } 206 } 207 208 my @oc = $group_entry->get_value('objectClass'); 209 unless (grep($_ =~ /^sambaGroupMapping$/i, @oc)) { 210 push (@adds, 'objectClass' => 'sambaGroupMapping'); 211 } 212 213 my $ldap_master=connect_ldap_master(); 214 my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", 215 changes => [ 216 'add' => [ @adds ], 217 'replace' => [ @mods ] 218 ] 219 ); 220 $modify->code && warn "failed to delete entry: ", $modify->error ; 221 # take down session 222 $ldap_master->unbind 223} 224 225$nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; 226 227if ($nscd_status == 0) { 228 system "/etc/init.d/nscd restart > /dev/null 2>&1"; 229} 230 231exit (0); 232 233############################################################ 234 235=head1 NAME 236 237smbldap-groupmod.pl - Modify a group 238 239=head1 SYNOPSIS 240 241smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group 242 243=head1 DESCRIPTION 244 245The smbldap-groupmod.pl command modifies the system account files to 246 reflect the changes that are specified on the command line. 247 The options which apply to the smbldap-groupmod command are 248 249 -g gid The numerical value of the group's ID. This value must be 250 unique, unless the -o option is used. The value must be non- 251 negative. Any files which the old group ID is the file 252 group ID must have the file group ID changed manually. 253 254 -n group_name 255 The name of the group will be changed from group to group_name. 256 257 -m members 258 The members to be added to the group in comma-delimeted form. 259 260 -x members 261 The members to be removed from the group in comma-delimted form. 262 263=head1 EXAMPLES 264 265 smbldap-groupmod.pl -g 253 development 266 This will change the GID of the 'development' group to '253'. 267 268 smbldap-groupmod.pl -n Idiots Managers 269 This will change the name of the 'Managers' group to 'Idiots'. 270 271 smbldap-groupmod.pl -m "jdoe,jsmith" "Domain Admins" 272 This will add 'jdoe' and 'jsmith' to the 'Domain Admins' group. 273 274 smbldap-groupmod.pl -x "jdoe,jsmith" "Domain Admins" 275 This will remove 'jdoe' and 'jsmith' from the 'Domain Admins' group. 276 277=head1 SEE ALSO 278 279 groupmod(1) 280 281=cut 282 283#' 284