Package dak :: Module import_users_from_passwd
[hide private]
[frames] | no frames]

Source Code for Module dak.import_users_from_passwd

  1  #! /usr/bin/env python3 
  2   
  3  """Sync PostgreSQL users with system users""" 
  4  # Copyright (C) 2001, 2002, 2006  James Troup <james@nocrew.org> 
  5   
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10   
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15   
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19   
 20  ################################################################################ 
 21   
 22  import grp 
 23  import pwd 
 24  import re 
 25  import sys 
 26   
 27  import apt_pkg 
 28   
 29  from daklib import utils 
 30  from daklib.config import Config 
 31  from daklib.dbconn import DBConn 
 32   
 33  ################################################################################ 
 34   
 35   
36 -def usage(exit_code=0):
37 print( 38 """Usage: dak import-users-from-passwd [OPTION]... 39 Sync PostgreSQL's users with system users. 40 41 -h, --help show this help and exit 42 -n, --no-action don't do anything 43 -q, --quiet be quiet about what is being done 44 -v, --verbose explain what is being done""" 45 ) 46 sys.exit(exit_code)
47 48 49 ################################################################################ 50 51
52 -def main():
53 cnf = Config() 54 55 Arguments = [ 56 ("n", "no-action", "Import-Users-From-Passwd::Options::No-Action"), 57 ("q", "quiet", "Import-Users-From-Passwd::Options::Quiet"), 58 ("v", "verbose", "Import-Users-From-Passwd::Options::Verbose"), 59 ("h", "help", "Import-Users-From-Passwd::Options::Help"), 60 ] 61 for i in ["no-action", "quiet", "verbose", "help"]: 62 key = "Import-Users-From-Passwd::Options::%s" % i 63 if key not in cnf: 64 cnf[key] = "" 65 66 arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) 67 Options = cnf.subtree("Import-Users-From-Passwd::Options") 68 69 if Options["Help"]: 70 usage() 71 elif arguments: 72 utils.warn("dak import-users-from-passwd takes no non-option arguments.") 73 usage(1) 74 75 session = DBConn().session() 76 valid_gid = cnf.get("Import-Users-From-Passwd::ValidGID", "") 77 if valid_gid: 78 debiangrp = grp.getgrnam(valid_gid).gr_mem 79 else: 80 debiangrp = [] 81 82 passwd_unames = {} 83 for entry in pwd.getpwall(): 84 uname = entry[0] 85 if uname not in debiangrp: 86 if Options["Verbose"]: 87 print("Skipping %s (Not in group %s)." % (uname, valid_gid)) 88 continue 89 passwd_unames[uname] = "" 90 91 postgres_unames = {} 92 q = session.execute("SELECT usename FROM pg_user") 93 for i in q.fetchall(): 94 uname = i[0] 95 postgres_unames[uname] = "" 96 97 known_postgres_unames = {} 98 for i in cnf.get("Import-Users-From-Passwd::KnownPostgres", "").split(","): 99 uname = i.strip() 100 known_postgres_unames[uname] = "" 101 102 for uname in sorted(postgres_unames): 103 if uname not in passwd_unames and uname not in known_postgres_unames: 104 print( 105 "I: Deleting %s from Postgres, no longer in passwd or list of known Postgres users" 106 % (uname) 107 ) 108 q = session.execute('DROP USER "%s"' % (uname)) 109 110 safe_name = re.compile("^[A-Za-z0-9]+$") 111 for uname in sorted(passwd_unames): 112 if uname not in postgres_unames: 113 if not Options["Quiet"]: 114 print("Creating %s user in Postgres." % (uname)) 115 if not Options["No-Action"]: 116 if safe_name.match(uname): 117 # NB: I never figured out how to use a bind parameter for this query 118 # XXX: Fix this as it looks like a potential SQL injection attack to me 119 # (hence the safe_name match we do) 120 try: 121 q = session.execute('CREATE USER "%s"' % (uname)) 122 session.commit() 123 except Exception as e: 124 utils.warn("Could not create user %s (%s)" % (uname, str(e))) 125 session.rollback() 126 else: 127 print("NOT CREATING USER %s. Doesn't match safety regex" % uname) 128 129 session.commit()
130 131 132 ####################################################################################### 133 134 135 if __name__ == "__main__": 136 main() 137