Google Apps Password Sync for Samba4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gapslib.py 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/usr/bin/env python
  2. import binascii
  3. import quopri
  4. import sys
  5. import textwrap
  6. import hashlib
  7. import syslog
  8. import json
  9. import httplib2
  10. import ldb
  11. import os
  12. from apiclient import errors
  13. from apiclient.discovery import build
  14. from samba.auth import system_session
  15. from samba.credentials import Credentials
  16. from samba.param import LoadParm
  17. from samba.samdb import SamDB
  18. from samba.netcmd.user import GetPasswordCommand
  19. from ConfigParser import SafeConfigParser
  20. from oauth2client.client import SignedJwtAssertionCredentials
  21. ## Get confgiruation
  22. config = SafeConfigParser()
  23. config.read('/etc/gaps/gaps.conf')
  24. ## Open connection to Syslog ##
  25. syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL3)
  26. filename = config.get('common', 'path_pwdlastset_file')
  27. dict_mail_pwdlastset={}
  28. if os.path.isfile(filename):
  29. dict_mail_pwdlastset = json.loads(open(filename,'r').read())
  30. ## Load Google Configuration ##
  31. with open( config.get('google', 'service_json')) as data_file:
  32. gaConfig = json.load(data_file)
  33. ## Load Google Service ##
  34. def createDirectoryService(user_email):
  35. credentials = SignedJwtAssertionCredentials(
  36. gaConfig['client_email'],
  37. gaConfig['private_key'],
  38. scope='https://www.googleapis.com/auth/admin.directory.user',
  39. sub=user_email
  40. )
  41. http = httplib2.Http()
  42. http = credentials.authorize(http)
  43. return build('admin', 'directory_v1', http=http)
  44. def update_password(mail, pwd, pwdlastset):
  45. # Create a new service object
  46. service = createDirectoryService(config.get('google', 'admin_email'))
  47. try:
  48. user = service.users().get(userKey = mail).execute()
  49. except:
  50. syslog.syslog(syslog.LOG_WARNING, '[WARNING] Account %s not found' % mail)
  51. return 0
  52. user['hashFunction'] = 'crypt'
  53. user['password'] = pwd.replace('{CRYPT}','')
  54. try:
  55. #Change password
  56. service.users().update(userKey = mail, body=user).execute()
  57. syslog.syslog(syslog.LOG_WARNING, '[NOTICE] Updated password for %s' % mail)
  58. dict_mail_pwdlastset[str(mail)]=str(pwdlastset)
  59. open(filename,'w').write(json.dumps(dict_mail_pwdlastset))
  60. except Exception as e:
  61. syslog.syslog(syslog.LOG_WARNING, '[ERROR] %s : %s' % (mail,str(e)))
  62. finally:
  63. service = None
  64. def run():
  65. param_samba = {
  66. 'basedn' : config.get('samba', 'path'),
  67. 'pathsamdb':'%s/sam.ldb' % config.get('samba', 'private'),
  68. 'adbase': config.get('samba', 'base')
  69. }
  70. # SAMDB
  71. lp = LoadParm()
  72. creds = Credentials()
  73. creds.guess(lp)
  74. samdb_loc = SamDB(url=param_samba['pathsamdb'], session_info=system_session(),credentials=creds, lp=lp)
  75. testpawd = GetPasswordCommand()
  76. testpawd.lp = lp
  77. passwordattr = config.get('common', 'attr_password')
  78. allmail = {}
  79. # Search all users
  80. for user in samdb_loc.search(base=param_samba['adbase'], expression="(&(objectClass=user)(mail=*))", attrs=["mail","sAMAccountName","pwdLastSet"]):
  81. mail = str(user["mail"])
  82. #replace mail if replace_domain in config
  83. if config.getboolean('common', 'replace_domain'):
  84. mail = mail.split('@')[0] + '@' + config.get('common', 'domain')
  85. pwdlastset = user.get('pwdLastSet','')
  86. #add mail in all mail
  87. allmail[mail] = None
  88. if str(pwdlastset) != dict_mail_pwdlastset.get(mail,''):
  89. # Update if password different in dict mail pwdlastset
  90. password = testpawd.get_account_attributes(samdb_loc,None,param_samba['basedn'],filter="(sAMAccountName=%s)" % (str(user["sAMAccountName"])),scope=ldb.SCOPE_SUBTREE,attrs=[passwordattr],decrypt=True)
  91. if not passwordattr in password:
  92. continue
  93. password = str(password[passwordattr])
  94. update_password(mail, password, pwdlastset)
  95. #delete user found in dict mail pwdlastset but not found in samba
  96. listdelete = []
  97. for user in dict_mail_pwdlastset :
  98. if not user in allmail:
  99. listdelete.append(user)
  100. for user in listdelete:
  101. del dict_mail_pwdlastset[user]
  102. #write new json dict mail password
  103. if listdelete:
  104. open(filename,'w').write(json.dumps(dict_mail_pwdlastset))