/* GroupMod script for klusrmgr and Samba Server for OS/2 */ Version = '2.5.0' /* Copyright (C) bww bitwise works GmbH., netlabs.org 2007-2018 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Purpose: Add/remove a kLIBC group whenever a Samba group is added/removed. Let users join/leave a kLIBC group whenever a Samba user joined/ left a Samba group. This script can also be used from the commandline to add/remove kLIBC groups and let users join/leave groups Sambas smb.conf needs these changes: [global] add group script = x:\usr\bin\groupmod.cmd -a "%g" delete group script = x:\usr\bin\groupmod.cmd -x "%g" add user to group script = x:\usr\bin\groupmod.cmd -j "%g" "%u" delete user from group script = x:\usr\bin\groupmod.cmd -l "%g" "%u" */ call _LoadOtherFuncs call _InitTempDir call _klusrInit call _klusrExtendSearchPath parse arg '-'mode' "'group'"' if group = "" & mode <> "" then parse arg '-'mode' 'group mode = translate(mode) User = "" GID = "" OtherParms = "" GIDParm = "" if mode ="J" | mode = "L" then do parse arg '-'mode' "'group'" "'User'"' mode = translate(mode) end if mode = "A" then do parse arg '-'mode' "'group'" 'OtherParms group = strip(group,'T','"') mode = translate(mode) if OtherParms <> "" then do OtherW = words(OtherParms) if wordpos("-g",OtherParms) > 0 then do parse var OtherParms .'-g 'gidparm' -' gidparm = strip(gidparm) gidparm = strip(gidparm,,'"') end end end if mode = "X" then do parse arg '-'mode' 'group mode = translate(mode) group = strip(group,,'"') if datatype(group) = "NUM" then do gid = group end end call _GroupRead GroupExists = _GroupIsValid(group) select when mode = "A" & GroupExists then do say 'Group "'group'" already exists!' exit 251 end when mode = "X" & \GroupExists then do say 'Group "'group'" is invalid - cannot remove!' exit 252 end when mode = "J" & \GroupExists then do say 'Group "'group'" is invalid - user cannot join!' exit 253 end when mode = "L" & \GroupExists then do say 'Group "'group'" is invalid - user cannot leave!' exit 254 end when mode = "V" then do nop end when mode = "?" | mode = "H" | arg(1) = "/?" | arg(1) ="" | (group = "" & mode <> "") then do if (group = "" & mode <> "") then say "Ambiguos commandline. Check syntax!" say say 'Add a kLIBC group: groupmod -a "groupname" [-g GID]' say 'Remove a kLIBC group: groupmod -x "groupname" | GID' say 'Join a kLIBC group: groupmod -j "groupname" "username"' say 'Leave a kLIBC group: groupmod -l "groupname" "username"' say 'List kLIBC groups: groupmod -v' say exit 255 end otherwise nop /* mode and existence are compatible */ end select when mode = "A" then call _GroupAdd when mode = "X" then call _GroupDel when mode = "J" then call _GroupJoin when mode = "L" then call _GroupLeave when mode = "V" then call _GroupList otherwise nop end call _GroupWrite call beep 1200, 10 say 'Done.' exit 0 /* Common subroutines for several programs/scripts */ _LoadOtherFuncs: /* Load other REXX libraries */ '@echo off' call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs' call SysLoadFuncs call RxFuncAdd 'VRLoadFuncs', 'VROBJ', 'VRLoadFuncs' call VRLoadFuncs return _InitTempDir: /* make sure we have a valid temporary directory */ /* Get temporary directory */ HaveNoTMPDIR = 0 TempDir = translate(value('TMPDIR',,'OS2ENVIRONMENT'),'\','/') if TempDir = '' then do HaveNoTMPDIR = 1 TempDir = translate(value('TEMP',,'OS2ENVIRONMENT'),'\','/') end if TempDir = '' then TempDir = translate(value('TMP',,'OS2ENVIRONMENT'),'\','/') if TempDir = '' then TempDir = directory() if HaveNoTMPDIR then do say 'Setting missing TMPDIR variable to "'TempDir'".' ok = value('TMPDIR',TempDir,'OS2ENVIRONMENT') end TempDir = strip(TempDir,'T','\')||'\' /* make sure there is trailing "\" */ return _klusrInit: /* Detect Samba components, initialize klusrmgr. stem */ ETC = value('ETC',,'OS2ENVIRONMENT') UnixRoot = value("UNIXROOT",,'OS2ENVIRONMENT') if UnixRoot = "" then do UnixRoot = left(ETC,length(ETC)-4) say 'Setting missing UNIXROOT variable to "'UnixRoot'".' ok = value("UNIXROOT",UnixRoot,'OS2ENVIRONMENT') end UnixETC = UnixRoot'\etc' klusrmgr.!masterpasswd = UnixEtc'\master.passwd' klusrmgr.!group = UnixEtc'\group' klusrmgr.!bin = UnixRoot'\usr\bin' /* get the path to this file */ parse source . . script klusrmgr.!tools = strip(filespec('D',script)||filespec('P',script),,'\') script = VRParseFileName(script,'N') if klusrmgr.!bin = "" then klusrmgr.!bin = klusrmgr.!tools klusrmgr.!pwd_mkdb = SysSearchPath("PATH","pwd_mkdb.exe") if klusrmgr.!pwd_mkdb = "" then do /* in current directory? */ ok = SysFileTree('.\pwd_mkdb.exe', exist.,'FO') if exist.0 = 1 then klusrmgr.!pwd_mkdb = exist.1 end if klusrmgr.!pwd_mkdb = "" then do /* in usr/sbin directory? */ ok = SysFileTree(UnixRoot'\usr\sbin\pwd_mkdb.exe', exist.,'FO') if exist.0 = 1 then klusrmgr.!pwd_mkdb = exist.1 end if klusrmgr.!pwd_mkdb = "" then do /* tools directory? */ ok = SysFileTree(klusrmgr.!tools'\pwd_mkdb.exe', exist.,'FO') if exist.0 = 1 then klusrmgr.!pwd_mkdb = exist.1 end if klusrmgr.!pwd_mkdb = "" then do /* in SMB_SBIN ? */ klusrmgr.!pwd_mkdb = SysSearchPath("SMB_SBIN","pwd_mkdb.exe") end return _klusrExtendSearchPath: /* Add binary and tools path to the PATH variable */ old_path = value('PATH',, 'OS2ENVIRONMENT') if pos(translate(klusrmgr.!bin';'),translate(old_path)) = 0 then do if klusrmgr.!bin = klusrmgr.!tools then new_path = klusrmgr.!bin';' else new_path = klusrmgr.!bin';'klusrmgr.!tools';' ok = value('PATH', new_path || old_path, 'OS2ENVIRONMENT') drop new_path end drop old_path /* Add binary and tools path to the BEGINLIBPATH variable */ old_beginlibpath = SysQueryExtLibPath("B") if pos(translate(klusrmgr.!bin';'),translate(old_beginlibpath)) = 0 then do if klusrmgr.!bin = klusrmgr.!tools then new_beginlibpath = klusrmgr.!bin';'old_beginlibpath else new_beginlibpath = klusrmgr.!bin';'klusrmgr.!tools';'old_beginlibpath ok = SysSetExtLibPath( new_beginlibpath, "B") drop new_beginlibpath end drop old_beginlibpath /* Set LIBPATHSTRICT (this is an option - disabled by default) */ /* ok = value('LIBPATHSTRICT','T', 'OS2ENVIRONMENT') */ return _GroupRead: /* Read complete groupfile into stems */ /* Structure of group file: groupname:*:GID:user,user,user, */ Group512 = 0 Group513 = 0 Group515 = 0 J = 0 do until lines(klusrmgr.!group) = 0 groupline = strip(linein(klusrmgr.!group)) if J = 0 & groupline = "" then leave /* Skip comments */ if left(groupline,1) = "#" then iterate /* parse fields into stem variables */ J = J + 1 parse var groupline groupname.J':'gpasswd.J':'ggid.J':'gusers.J if ggid.J = 512 then Group512 = J if ggid.J = 513 then Group513 = J if ggid.J = 515 then Group515 = J end ok = stream(klusrmgr.!group,'c','close') /* set "stem roots" properly */ groupname.0 = J gpasswd.0 = J; gpasswd. = '*' /* default value, unused */ ggid.0 = J gusers.0 = J return _GroupWrite: newgroup = TempDir'group.smb' ok = SysFileDelete(newgroup) call lineout newgroup, '# Created by 'Script' 'Version' on 'date()' at 'time() call lineout newgroup, '# syntax:' call lineout newgroup, '# groupname:password:GID:user[,user,...,]' do J = 1 to groupname.0 call lineout newgroup, groupname.J':'Gpasswd.J':'GGid.J':'GUsers.J end ok = stream(newgroup,'c','close') ok = VRCopyFile( klusrmgr.!group, klusrmgr.!group'.bak' ) ok = VRCopyFile( newgroup, klusrmgr.!group ) ok = SysFileDelete(newgroup) return _GroupIsValid: procedure expose Groupname. GGID. Group = arg(1) HaveValidGroup = 0 do I = 1 to Groupname.0 if translate(Groupname.I) = translate(Group) | Group = GGID.I then do HaveValidGroup = 1 leave end end return HaveValidGroup _GroupAdd: /* Add a new group to group stems */ /* Minimum GID that a group can obtain */ if GIDParm = "" then MinGID = 3000 else MinGID = GIDParm if translate(Group) = "ADMIN" then MinGID = 512 if translate(Group) = "USERS" then MinGID = 513 if translate(Group) = "GUESTS" then MinGID = 514 if translate(Group) = "MACHINES" then MinGID = 515 /* determine next free GID */ do nextGGID = minGID to 65535 by 1 do i=1 to GGID.0 while GGID.i <> nextGGID end if GGID.i <> nextGGID then leave end /* Add new group to the stems */ I = GGID.0 I = I + 1 GGID.0 = I groupname.0 = I /* set new values */ Groupname.I = group /* we get that from Samba */ GGID.I = NextGGID Gusers.I = "" say 'Adding group "'group'" (GID: 'GGID.I').' return _GroupDel: /* Remove a group from group STEMS */ do I = 1 to groupname.0 if translate(groupname.I) = translate(group) | ggid.I = gid then do ExGGID = GGID.I group = groupname.I ok = SysStemDelete("groupname.",I) ok = SysStemDelete("ggid.",I) ok = SysStemDelete("gusers.",I) leave end end say 'Removing group "'group'" (GID: 'ExGGID').' return _GroupJoin: /* Add a new user to the groups user STEM */ /* Translate machine account to upper case - Samba 3.3 needs this */ if right(User,1) = "$" then User = translate(User) do I = 1 to groupname.0 if translate(groupname.I) = translate(group) then do if pos(translate(User),translate(Gusers.I)) = 0 then do Gusers.I = Gusers.I||User',' say '"'User'" joined group "'group'" (GID: 'GGID.I').' leave end else say '"'User'" already in group "'group'" (GID: 'GGID.I').' end end return _GroupLeave: /* Remove a user from the groups STEM */ do I = 1 to groupname.0 if translate(groupname.I) = translate(group) then do blGUsers = translate(Gusers.I,' ',',') UPos = wordpos(translate(User),translate(blGusers)) if Upos > 0 then do blGUsers = delword(blGusers,UPos,1) Gusers.I = translate(blGusers,',',' ') say '"'User'" removed from group "'group'" (GID: 'GGID.I').' leave end else say '"'User'" not member in group "'group'" (GID: 'GGID.I').' end end return _GroupList: do I = 1 to groupname.0 say groupname.I end return