summaryrefslogtreecommitdiffstats
path: root/adduser
diff options
context:
space:
mode:
authorWolfram Schneider <wosch@FreeBSD.org>1996-10-29 20:31:43 +0000
committerWolfram Schneider <wosch@FreeBSD.org>1996-10-29 20:31:43 +0000
commit1a199459fdd00c673950ef758f2fae90860b2e9e (patch)
tree7ffce1e1e739b8e7a849915a27a06e3d3e6be9f0 /adduser
parent326af800ad8e2a80ceffaa3ec3a2ceb3d6e2f30f (diff)
downloadpw-darwin-1a199459fdd00c673950ef758f2fae90860b2e9e.tar.gz
pw-darwin-1a199459fdd00c673950ef758f2fae90860b2e9e.tar.zst
pw-darwin-1a199459fdd00c673950ef758f2fae90860b2e9e.zip
addgroup - add a group or add users to a group
addgroup [-g gid] group [user[,user,...]]
Diffstat (limited to 'adduser')
-rw-r--r--adduser/addgroup.tcl220
1 files changed, 220 insertions, 0 deletions
diff --git a/adduser/addgroup.tcl b/adduser/addgroup.tcl
new file mode 100644
index 0000000..82ed4a0
--- /dev/null
+++ b/adduser/addgroup.tcl
@@ -0,0 +1,220 @@
+#!/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
+#
+# $Id: addgroup.tcl,v 1.5 1996/10/29 19:11:50 wosch Exp wosch $
+
+# 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
+}
+
+# check group(5) limits
+proc group_limit {string} {
+ set line_max 100; # max group line length
+ set groups_max 200; # max group members
+
+ if {[string length $string] >= $line_max} {
+ return 1
+ }
+
+ set l [split $string ","]
+ if {[llength $l] >= $groups_max} {
+ 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} {
+ if {[group_limit "$line$groupmembers"] == 0} {
+ puts $db_new "$line$groupmembers"
+ } else {
+ Err "group line too long: ``$line$groupmembers''"
+ }
+ } else {
+ if {[group_limit "$line,$groupmembers"] == 0} {
+ if {[double_name "$y,$groupmembers"] != 0} {
+ Err "\t$line,$groupmembers"
+ } else {
+ puts $db_new "$line,$groupmembers"
+ }
+ } else {
+ Err "group line too long: ``$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} {
+ if {[group_limit "$groupname:*:$i:$groupmembers"] == 0} {
+ puts $db_new "$groupname:*:$i:$groupmembers"
+ } else {
+ Err "group line too long: ``$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