Univention Bugzilla – Attachment 6987 Details for
Bug 38796
ensure uidNumber and gidNumber do not collide when add/mod user or group
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
find colliding gids, change them in LDAP and on disk
change_colliding-gids.py (text/x-python), 7.04 KB, created by
Daniel Tröder
on 2015-06-30 23:45:53 CEST
(
hide
)
Description:
find colliding gids, change them in LDAP and on disk
Filename:
MIME Type:
Creator:
Daniel Tröder
Created:
2015-06-30 23:45:53 CEST
Size:
7.04 KB
patch
obsolete
>#!/usr/bin/python ># ># Copyright 2015 Univention GmbH ># ># http://www.univention.de/ ># ># All rights reserved. ># ># The source code of this program is made available ># under the terms of the GNU Affero General Public License version 3 ># (GNU AGPL V3) as published by the Free Software Foundation. ># ># Binary versions of this program provided by Univention to you as ># well as other copyrighted, protected or trademarked materials like ># Logos, graphics, fonts, specific documentations and configurations, ># cryptographic keys etc. are subject to a license agreement between ># you and Univention and not subject to the GNU AGPL V3. ># ># In the case you use this program under the terms of the GNU AGPL V3, ># the program is provided 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 Affero General Public License for more details. ># ># You should have received a copy of the GNU Affero General Public ># License with the Debian GNU/Linux or Univention distribution in file ># /usr/share/common-licenses/AGPL-3; if not, see ># <http://www.gnu.org/licenses/>. > >import os >import sys >from optparse import OptionParser >import traceback >import datetime > >import univention.admin >import univention.admin.uldap >import univention.admin.config >import univention.admin.modules >import univention.admin.allocators as ualloc >from univention.config_registry import ConfigRegistry, handler_set, handler_unset > > >def collect_gids(): > users = dict() > for dn, attrs in lo.search('(&(uidNumber=*)(objectClass=posixAccount))', attr=('uidNumber', )): > xid = attrs.get('uidNumber') > if xid: > users[(int(xid[0]))] = dn > groups = dict() > for dn, attrs in lo.search('(&(gidNumber=*)(objectClass=posixGroup))', attr=('gidNumber', )): > xid = attrs.get('gidNumber') > if xid: > groups[(int(xid[0]))] = dn > > common_ids = set(users.keys()).intersection(set(groups.keys())) > > if options.verbose: > print "# uidNumbers: %r" % users.keys() > print "# gidNumbers: %r" % groups.keys() > print "# common ids: %r" % common_ids > > res = list() > for cid in common_ids: > new_gidNumber = int(cid) > while new_gidNumber in groups or new_gidNumber in users: > new_gidNumber = int(ualloc.request(lo, position, 'gidNumber')) > res.append((cid, new_gidNumber)) > return res > >def write_gids(gids, filename): > with open(filename, "w") as f: > f.writelines(["%d %d\n" % gid for gid in gids]) > >def read_gids(filename): > res = list() > with open(filename, "r") as f: > for line in f: > try: > from_gid, to_gid = line.strip().split() > res.append((int(from_gid), int(to_gid))) > if options.verbose: > print "# %r -> %r" % (from_gid, to_gid) > except IndexError: > pass > except ValueError: > pass > return res > >def change_gids(gids): > for from_gid, to_gid in gids: > try: > group = univention.admin.modules.lookup(group_module, co, lo, scope='sub', superordinate=None, filter='(gidNumber=%d)' % from_gid) > if len(group) == 1: > group = group[0] > if options.verbose: > print "# %r -> %r (%r)" % (from_gid, to_gid, group['name']) > group.descriptions["gidNumber"].may_change = True > group['gidNumber'] = str(to_gid) > group.descriptions["gidNumber"].may_change = False > group.modify() > except: > print "Error changing %r -> %r, writing traceback to %s." % (from_gid, to_gid, err_file_name) > err_file.write("GRPSET %r -> %r\n" % (from_gid, to_gid)) > err_file.write(traceback.format_exc()) > err_file.write("\n") > >def walk_error(oserror): > print "Error reading directory, writing traceback to %s." % err_file_name > err_file.write("LIST %r\n" % oserror) > >def chgrp(filepath, gid): > uid = os.stat(filepath).st_uid > os.chown(filepath, uid, gid) > > >parser = OptionParser() >parser.add_option("-d", "--dir", dest="chgrp_directory", > help="run chgrp recursivly on directory, expects change information from file with -i", > metavar="FILE") >parser.add_option("-i", "--infile", dest="in_filename", help="read group changes from FILE", metavar="FILE") >parser.add_option("-o", "--outfile", dest="out_filename", help="write group changes to FILE", metavar="FILE") >parser.add_option("-l", "--ldap", action="store_true", help="Modify GIDs of groups in LDAP, expects change information from file with -i [default=off].") >parser.add_option("-v", "--verbose", action="store_false", dest="verbose", default=True, > help="write about current action [default=on].") > >(options, args) = parser.parse_args() > >if options.chgrp_directory and not options.in_filename: > parser.error("Please supply the directory that run chgrp should be run on recursivly with '-i'.") >if options.in_filename and options.out_filename: > parser.error("Options -i and -o are mutually exclusive.") >if not options.in_filename and not options.out_filename: > parser.error("Please use either -i or -o.") >if options.in_filename and not (options.chgrp_directory or options.ldap): > parser.error("Please use -i with -d or -l.") >if options.ldap and not options.in_filename: > parser.error("Please supply data to change the group information in LDAP with '-i'.") >if options.ldap and options.out_filename: > parser.error("Options -l and -o are mutually exclusive.") > >univention.admin.modules.update() >univention.admin.syntax.update_choices() >lo, position = univention.admin.uldap.getAdminConnection() >co = univention.admin.config.config() >group_module = univention.admin.modules.get('groups/group') > >try: > os.mkdir("/var/log/changegrp/") >except OSError: > pass >err_file_name = "/var/log/changegrp/%s.log" % datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S") >err_file = open(err_file_name, "ab") > >if options.out_filename: > gids = collect_gids() > write_gids(gids, options.out_filename) > print "Wrote %d GID pairs to %s." % (len(gids), options.out_filename) > err_file.close() > sys.exit(0) > >if options.in_filename: > print "Reading list of groups from %r..." % options.in_filename > > gids = read_gids(options.in_filename) > print "... read %d GID pairs." % len(gids) > > if options.ldap: > print "Changing %d gidNumbers in LDAP..." % len(gids) > change_gids(gids) > print "... done." > err_file.close() > sys.exit(0) > > if options.chgrp_directory: > gids_dict = dict(gids) > stats = {"dir": 0, "file": 0} > print "Running chgrp recursivly on %r..." % options.chgrp_directory > for root, dirs, files in os.walk(options.chgrp_directory, onerror=walk_error): > print "# %r..." % root > for _dir in dirs: > dir_gid = os.stat(os.path.join(root, _dir)).st_gid > if dir_gid in gids_dict: > stats["dir"] += 1 > chgrp(os.path.join(root, _dir), gids_dict[dir_gid]) > if options.verbose: > err_file.write("CHGRP %r: %r -> %r\n" % (os.path.join(root, _dir), dir_gid, gids_dict[dir_gid])) > for _file in files: > file_gid = os.stat(os.path.join(root, _file)).st_gid > if file_gid in gids_dict: > stats["file"] += 1 > chgrp(os.path.join(root, _file), gids_dict[file_gid]) > if options.verbose: > err_file.write("CHGRP %r: %r -> %r\n" % (os.path.join(root, _file), file_gid, gids_dict[file_gid])) > print "... done. Changed permissions on %d directories and %d files." % (stats["dir"], stats["file"]) > err_file.close() > sys.exit(0)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 38796
: 6987 |
6990