1130b656e5
This will make a number of things easier in the future, as well as (finally!) avoiding the Id-smashing problem which has plagued developers for so long. Boy, I'm glad we're not using sup anymore. This update would have been insane otherwise.
192 lines
3.9 KiB
Tcl
192 lines
3.9 KiB
Tcl
#!/usr/bin/tclsh
|
|
# Copyright (c) 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
|
|
# All rights reserved.
|
|
#
|
|
# addgroup - add a group or add users to a group
|
|
#
|
|
# addgroup [-g gid] group [user[,user,...]]
|
|
#
|
|
#
|
|
# addgroup -g 2000 foobar
|
|
#
|
|
# Add group `foobar' to group database. Group id is 2000 if
|
|
# possible or higher. Don't add group `foobar' if `foobar' is
|
|
# already in group database.
|
|
#
|
|
#
|
|
# addgroup foo blech,bar
|
|
#
|
|
# Add user `blech' and user `bar' to group `foo'. Create group
|
|
# `foo' with default gid if not exists.
|
|
#
|
|
#
|
|
# The option [-g gid] is only for new groups.
|
|
#
|
|
# see group(5)
|
|
#
|
|
# TODO:
|
|
# file locking
|
|
# signal handling
|
|
# add only users who exist
|
|
#
|
|
# $FreeBSD$
|
|
|
|
# set global variables
|
|
set etc_group "/etc/group"; #set etc_group "/usr/tmp/group"
|
|
set gid_start 1000
|
|
set gid_max 65500
|
|
|
|
proc putsErr {string} {
|
|
if {[catch {open "/dev/stderr" w} stderr]} {
|
|
puts $stderr
|
|
} else {
|
|
puts $stderr $string
|
|
close $stderr
|
|
}
|
|
}
|
|
|
|
proc usage {} {
|
|
putsErr {usage: addgroup group [user]}
|
|
putsErr { addgroup [-g gid] group [user[,user,...]]}
|
|
exit 1
|
|
}
|
|
|
|
# check double user names: foo,bla,foo
|
|
proc double_name {groupmembers} {
|
|
set l [split $groupmembers ","]
|
|
if {[llength $l] > 1} {
|
|
for {set i 0} {$i < [llength $l]} {incr i} {
|
|
if {[lsearch [lrange $l [expr $i + 1] end] \
|
|
[lindex $l $i]] != -1} {
|
|
putsErr "Double user name: [lindex $l $i]"
|
|
return 1
|
|
}
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
# cleanup and die
|
|
proc Err {string} {
|
|
upvar etc_group_new new
|
|
putsErr "$string"
|
|
exec rm -f $new
|
|
exit 1
|
|
}
|
|
|
|
if {$argc < 1} { usage }
|
|
|
|
# check options
|
|
switch -glob -- [lindex $argv 0] {
|
|
-g* {
|
|
if {$argc < 2} {
|
|
putsErr "Missing group id"
|
|
usage
|
|
}
|
|
set g [lindex $argv 1]
|
|
if {$g < 100 || $g >= $gid_max} {
|
|
putsErr "Group id out of range 100 < $g < $gid_max"
|
|
usage
|
|
}
|
|
set gid_start $g
|
|
incr argc -2
|
|
set argv [lrange $argv 2 end]
|
|
}
|
|
-* { usage }
|
|
}
|
|
|
|
if {$argc < 1} { usage }
|
|
|
|
# read group name
|
|
set groupname [lindex $argv 0]
|
|
if {[string match "*:*" $groupname] != 0} {
|
|
putsErr "Colon are not allowed in group name: ``$groupname''"
|
|
usage
|
|
}
|
|
|
|
# read optional group members
|
|
if {$argc == 2} {
|
|
set groupmembers [lindex $argv 1]
|
|
if {[string match "*:*" $groupmembers] != 0} {
|
|
putsErr "Colon are not allowed in user names: ``$groupmembers''"
|
|
usage
|
|
}
|
|
if {[double_name $groupmembers] != 0} {
|
|
usage
|
|
}
|
|
} else {
|
|
set groupmembers ""
|
|
}
|
|
|
|
|
|
# open /etc/group database
|
|
if {[catch {open $etc_group r} db]} {
|
|
Err $db
|
|
}
|
|
|
|
# open temporary database
|
|
set etc_group_new "$etc_group.new";
|
|
if {[catch {open $etc_group_new w} db_new]} {
|
|
Err $db_new
|
|
}
|
|
set done 0
|
|
|
|
while {[gets $db line] >= 0 } {
|
|
if {$done > 0} {
|
|
puts $db_new $line
|
|
continue
|
|
}
|
|
|
|
# ``group:passwd:gid:member''
|
|
# 0 1 2 3
|
|
set l [split $line ":"]
|
|
set group([lindex $l 0]) [lindex $l 2]
|
|
set gid([lindex $l 2]) [lindex $l 0]
|
|
set member([lindex $l 0]) [lindex $l 3]
|
|
|
|
# found existing group
|
|
if {[string compare [lindex $l 0] $groupname] == 0} {
|
|
if {[string compare $groupmembers ""] == 0} {
|
|
Err "Group exists: ``$groupname''"
|
|
}
|
|
|
|
# add new group members
|
|
set y [lindex $l 3]
|
|
|
|
# group with no group members?
|
|
if {[string compare $y ""] == 0} {
|
|
puts $db_new "$line$groupmembers"
|
|
} else {
|
|
if {[double_name "$y,$groupmembers"] != 0} {
|
|
Err "\t$line,$groupmembers"
|
|
} else {
|
|
puts $db_new "$line,$groupmembers"
|
|
}
|
|
}
|
|
set done 1
|
|
} else {
|
|
puts $db_new $line
|
|
}
|
|
}
|
|
|
|
# add a new group
|
|
if {$done == 0} {
|
|
for {set i $gid_start} {$i < $gid_max} {incr i} {
|
|
if {[info exists gid($i)] == 0} {
|
|
puts $db_new "$groupname:*:$i:$groupmembers"
|
|
set done 1
|
|
break
|
|
}
|
|
}
|
|
|
|
# no free group id
|
|
if {$done == 0} {
|
|
Err "Cannot find free group id: ``$groupname''"
|
|
}
|
|
}
|
|
|
|
close $db_new
|
|
close $db
|
|
exec cp -pf $etc_group "$etc_group.bak"
|
|
exec mv -f $etc_group_new $etc_group
|