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