def ldap_connect():
    '''a helper method for connecting to ldap'''
    try:
        ldap_obj = psuldap.psuldap()
        ldap_obj.connect(ldapurl='ldap://ldap.oit.pdx.edu/')
        ldap_connected = True
        return ldap_obj, ldap_connected
    except psuldap.ldap.LDAPError, err:
        print '\nerror connecting to ldap: {0}\n'.format(err)
        return None, False
def ldap_lookup( website_no_http ):
  '''helper method for handling the ldap lookup'''
  ldap_connected = False
  ldap_searched = False
  search_results = []
  ldap_results = []

  try:
    ldap_obj = psuldap.psuldap()
    ldap_obj.connect(ldapurl='ldap://ldap.oit.pdx.edu/')
    ldap_connected = True
  except:
    print '\nerror connecting to ldap\n'

  if ldap_connected:
    this_search_filter = '(&(eduPersonAffiliation=WEB)(labeledUri=*' + str( website_no_http ) + '*))'
    try:
      search_results = ldap_obj.search( searchfilter=this_search_filter )
      ldap_searched = True
      if len( search_results ) > 0:
        ldap_results.append( search_results )
    except:
      print '\nerror searching ldap\n' + str( exc_info()[1] ) + '\n'

    if len( search_results ) is 0:
      this_search_filter = '(&(eduPersonAffiliation=WEB)(cn=*' + str( website_no_http ) + '*))'
      try:
        search_results = ldap_obj.search( searchfilter=this_search_filter )
        ldap_searched = True
        if len( search_results ) > 0:
         ldap_results.append( search_results )
      except:
        print '\nerror searching ldap\n' + str( exc_info()[1] ) + '\n'

    if len( search_results ) is 0:
      this_search_filter = '(&(eduPersonAffiliation=WEB)(gecos=*' + str( website_no_http ) + '*))'
      try:
        search_results = ldap_obj.search( searchfilter=this_search_filter )
        ldap_searched = True
        if len( search_results ) > 0:
          ldap_results.append( search_results )
      except:
        print '\nerror searching ldap\n' + str( exc_info()[1] ) + '\n'

  #ldap searched will always be true provided there was no error
  if ldap_searched:
    if len( search_results ) is 0:
      uid = ''
    else:
      uid = str( search_results[0][1]['uid'])
  else:
    uid = ''

  return uid, search_results
Пример #3
0
	def route_to_psu_future(self, login):
		ldap = psuldap('/vol/certs')
		# ldapsearch -x -h ldap.oit.pdx.edu -b 'dc=pdx, dc=edu' uid=dennis mailhost
		ldap_host = self.prop.getProperty('ldap.host')
		ldap_login = self.prop.getProperty('ldap.login')
		ldap_password = self.prop.getProperty('ldap.password')
		#self.log.info('opt_in_alread(): connecting to LDAP: ' + ldap_host)
		ldap.connect( ldap_host, ldap_login, ldap_password)
		
		dn = 'uid=' + login + ',ou=people,dc=pdx,dc=edu'
		ldap.mod_attribute(dn, 'mailHost', 'cyrus.psumail.pdx.edu')		
Пример #4
0
	def get_ldap_attr(self, login, attr):
		ldap = psuldap('/vol/certs')
		ldap_host = self.prop.getProperty('ldap.read.host')
		ldap_login = self.prop.getProperty('ldap.login')
		ldap_password = self.prop.getProperty('ldap.password')
		self.log.info('opt_in_alread(): connecting to LDAP: ' + ldap_host)
				
		ldap.connect( ldap_host, ldap_login, ldap_password)
		res = ldap.search( searchfilter = 'uid=' + login, attrlist = ['mailHost'])
		
		for (dn, result) in res:
			if result.has_key(attr):
				return str(result[attr])

		return None
Пример #5
0
	def opt_in_already(self, login):
		ldap = psuldap('/vol/certs')
		ldap_host = self.prop.getProperty('ldap.read.host')
		ldap_login = self.prop.getProperty('ldap.login')
		ldap_password = self.prop.getProperty('ldap.password')
		self.log.info('opt_in_alread(): connecting to LDAP: ' + ldap_host)
				
		ldap.connect( ldap_host, ldap_login, ldap_password)
		res = ldap.search( searchfilter = 'uid=' + login, attrlist = ['mailHost'])
		
		for (dn, result) in res:
			if result.has_key("mailHost"):
				self.log.info('opt_in_alread() user: '******' has a mailHost ' + str(result['mailHost']))
				if "gmx.pdx.edu" in result["mailHost"]:
					self.log.info('opt_in_alread() user: '******' has a mailHost entry set to gmx.pdx.edu')
					return True
		return False
Пример #6
0
    def populate(self):
        """Connects to Google domain, populates a list of usernames, and filters out against a static list of opt-outs and against the ldap directory. Creates a nested list of usernames."""
        optouts = [ "janely", "leschins", "cfrl", "jensenmm", "polly", "nelsonk", "kerrigs", "pats", "wamserc", "wacke", "smithcc", "psu25042", "mackc", "powells", "mjantzen", "pcooper", "staplej", "pmueller", "ferguse" ]
    
        if self.plevel == "prod":
            gdomain = "pdx.edu"

        elif self.plevel == "test":
            gdomain = "gtest.pdx.edu"

        elif self.plevel == "devl":
            gdomain = "gdev.pdx.edu"

        else:
            raise Exception("Invalid plevel %s" % self.plevel)

        guser = raw_input("Username: "******"Gathering all usernames for Google apps domain %s" % gdomain)
        googleuserlists = google.allusernames()
    
        optinuserlists = list()
    
        print("Screening out early migration opt-opt users")
        for userlist in googleuserlists:
            optinuserlists.append([user for user in userlist if user not in optouts])
    
        directory = psuldap()
        directory.connect(ldapurl="ldap://ldap1.oit.pdx.edu")

        self.userlists = list()
    
        print("Screening out non-LDAP users")
        for userlist in optinuserlists:
            self.userlists.append([user for user in userlist if directory.exists("(uid=%s)" % user)])

        print("Ready to launch!")
Пример #7
0
	def is_oamed(self, login):
		ldap = psuldap('/vol/certs')
		ldap_host = self.prop.getProperty('ldap.read.host')
		ldap_login = self.prop.getProperty('ldap.login')
		ldap_password = self.prop.getProperty('ldap.password')
		self.log.info('is_oamed(): connecting to LDAP: ' + ldap_host)
				
		attr = 'eduPersonAffiliation'
		ldap.connect( ldap_host, ldap_login, ldap_password)
		res = ldap.search( searchfilter = 'uid=' + login, attrlist = [attr])
		
		for (dn, result) in res:
			if result.has_key(attr):
				self.log.info('is_oamed() user: '******' has a ' + attr + ' of ' + str(result[attr]))
				#print('is_oamed() user: '******' has a ' + attr + ' of ' + str(result[attr]))

				for affiliation in result[attr]:
					if affiliation in ['SPONSORED', 'SERVICE']:
						self.log.info('is_oamed() user: '******' is not OAMed' )
						#print('is_oamed() user: '******' is not OAMed' )
						return False
		return True
Пример #8
0
def imapsync(ldapuri=None, state_memcaches=None, nosync_memcaches=None, imapserver=None, adminuser=None, plevel="test", dryrun=True, runlimit=7200, user=None):
    imapsync_dir = "/opt/google-imap/"
    imapsync_cmd = imapsync_dir + "imapsync"
    cyrus_pf = imapsync_dir + "cyrus.pf"
    exclude_list = "'^Shared Folders|^mail/|^Junk$|^junk$|^JUNK$|^Spam$|^spam$|^SPAM$'"
    whitespace_cleanup = " --regextrans2 's/[ ]+/ /g' --regextrans2 's/\s+$//g' --regextrans2 's/\s+(?=\/)//g' --regextrans2 's/^\s+//g' --regextrans2 's/(?=\/)\s+//g'"
    folder_cases = " --regextrans2 's/^drafts$/[Gmail]\/Drafts/i' --regextrans2 's/^trash$/[Gmail]\/Trash/i' --regextrans2 's/^(sent|sent-mail)$/[Gmail]\/Sent Mail/i' --delete2foldersbutnot '^\[Gmail\]'"
    extra_opts = " --delete2 --delete2folders --fast"
    exitstatus = "premature"

    if dryrun:
        extra_opts = extra_opts + " --dry" 

    if runlimit <= 0:
        raise Exception("Runlimit must be a positive integer.")

    if plevel == "prod":
        google_pf = imapsync_dir + "google-prod.pf"
        google_domain = "pdx.edu"

    elif plevel == "test":
        google_pf = imapsync_dir + "google-test.pf"
        google_domain = "gtest.pdx.edu"

    else:
        raise Exception("Plevel must be test or prod.")

    command = imapsync_cmd + " --pidfile /tmp/imapsync-" + user + ".pid --host1 " + imapserver + " --port1 993 --user1 " + user + " --authuser1 " + adminuser + " --passfile1 " + cyrus_pf + " --host2 imap.gmail.com --port2 993 --user2 " + user + "@" + google_domain + " --passfile2 " + google_pf + " --ssl1 --ssl2 --maxsize 26214400 --authmech1 PLAIN --authmech2 XOAUTH -sep1 '/' --exclude " + exclude_list + folder_cases + whitespace_cleanup + extra_opts

    cache = memcache.Client(servers=state_memcaches)            # System state
    nosync_cache = memcache.Client(servers=nosync_memcaches)    # Users not-to-sync

    cachekey = "(%s,auto)" % user
    optinkey = "email_copy_progress.%s" % user

    if nosync_cache.get(cachekey) != None:  # If the key exists in this cache, skip the sync.
        return (user, "nosync")

    if cache.get(optinkey) != None:         # If the user has opted in, skip the sync.
        if nosync_cache.set(cachekey,{"status":"nosync"}) != True:
            raise Exception("Could not set %s in nosync_cache." % cachekey)

        return (user, "nosync")

    directory = psuldap()       # Our LDAP handle
    directory.connect(ldapuri)  # Anonymous bind

    # Search for the user's mailHost attribute.
    mailhostsearch = directory.search(searchfilter="(uid=%s)" % user, attrlist=["mailHost"]) 

    # Loop through the search results. If any them match gmx.pdx.edu, set in the nosync cache.
    for (dn, result) in mailhostsearch:
        if result.has_key("mailHost"):
            if "gmx.pdx.edu" in result["mailHost"]:
                if nosync_cache.set(cachekey,{"status":"nosync"}) != True:
                    raise Exception("Could not set %s in nosync_cache." % cachekey)

                return (user, "nosync")

    # We can continue.
    cachestate = cache.gets(cachekey)

    if cachestate == None:  # Maybe the cache has been cleared. Continue.
        pass

    # Well, it looks like the cache has another task's data for this user. Abort.
    elif cachestate["status"] != "queued" or cachestate["taskid"] != imapsync.request.id:
        raise Exception("Cache inconsistency error for user %s." % user)

    # We're good to go. Let's set the cache with our new state.
    runstate = {
        "status":"running"
        ,"timestamp":int(time())
        ,"taskid":imapsync.request.id
        ,"worker":uname()[1]
    }

    cachelimit = runlimit + 10  # Fudge factor. 5 seconds for the sleep, 5 seconds for fudge.
    
    if cache.cas(cachekey, runstate, time=cachelimit) != True: # Whoops, something changed. Abort.
        raise Exception("Cache inconsistency error for user %s." % user)

    syncprocess = subprocess.Popen(
        args=shlex.split(command)
        ,bufsize=-1
        ,close_fds=True
        ,stdout=open("/dev/null",'w')
        ,stderr=None
    )

    starttime = time()

    # While the process is running, and we're under the time limit
    while (syncprocess.poll() == None) and ((time() - starttime) < runlimit):
        sleep(5)
    
    # Are we still running? Send a SIGTERM to the process and throw the task back on the queue.
    # This is done to prevent one user from tying up a worker for longer than the runlimit.
    if (syncprocess.poll() == None):
        syncprocess.terminate()     # Send SIGTERM
        syncprocess.communicate()   # Read stdin/out, and wait for process to terminate
        exitstatus = "outtatime"

    else:
        if syncprocess.returncode == 0:
            exitstatus = "ok"

        else:
            exitstatus = "error_%d" % syncprocess.returncode

    cachestate = cache.gets(cachekey)

    if cachestate == None: # Maybe the cache has been cleared. Continue.
        pass

    # Check to see if our cache state matches the previously set state. 
    if cachestate != runstate:
        raise Exception("Cache inconsistency error for user %s." % user)

    # We're good to go. Let's set the cache with our new state.
    endstate = {
        "status":"complete"
        ,"timestamp":int(time())
        ,"taskid":imapsync.request.id
        ,"worker":uname()[1]
        ,"returned":exitstatus
        ,"runtime":int(time() - starttime)
    }
    
    if cache.cas(cachekey, endstate) != True: # Whoops, something changed. Abort.
        raise Exception("Cache inconsistency error for user %s." % user)

    return (user, exitstatus)