You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by se...@apache.org on 2021/07/07 22:20:34 UTC
[whimsy] branch master updated: Improve nextuid code to detect gaps
in allocation
This is an automated email from the ASF dual-hosted git repository.
sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git
The following commit(s) were added to refs/heads/master by this push:
new da401d9 Improve nextuid code to detect gaps in allocation
da401d9 is described below
commit da401d900d40bd482951c388476db2606c4588e1
Author: Sebb <se...@apache.org>
AuthorDate: Wed Jul 7 23:20:25 2021 +0100
Improve nextuid code to detect gaps in allocation
It requires an expensive search to set up, so optionally
allow retrieval of multiple free ids
Also force user to change password as per current
practice
---
lib/whimsy/asf/ldap.rb | 54 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/lib/whimsy/asf/ldap.rb b/lib/whimsy/asf/ldap.rb
index 75e7917..fc2f536 100644
--- a/lib/whimsy/asf/ldap.rb
+++ b/lib/whimsy/asf/ldap.rb
@@ -914,6 +914,38 @@ module ASF
end
end
+ MINIMUM_USER_UID = 6000 # from asfpy/ldap
+ # Return the next free value for use as uidNumber/gidNumber
+ # Optionally return several free values as an array
+ def self.next_uidNumber(count=1)
+ raise ArgumentError.new "Count: #{count} is less than 1!" if count < 1
+ numbers = ASF::search_one(ASF::Person.base, 'uid=*', ['uidNumber', 'gidNumber']).
+ map{|i| u=i['uidNumber'];g=i['gidNumber']; u == g ? u : [u,g]}.flatten.map(&:to_i).
+ select{|i| i >= MINIMUM_USER_UID}.uniq.sort.lazy
+ enum = Enumerator.new do |output|
+ last = numbers.next rescue MINIMUM_USER_UID # in case no valid entries exist
+ loop do
+ curr = numbers.next
+ if curr <= last + 1
+ last = curr
+ else
+ (last+1..curr-1).each {|i| output << i}
+ last = curr
+ end
+ end
+ # in case we ran off the end...
+ loop do
+ last = last+1
+ output << last
+ end
+ end
+ if (count == 1)
+ enum.first
+ else
+ enum.take(count)
+ end
+ end
+
# add a new person to LDAP. Attrs must include uid, cn, and mail
def self.add(attrs)
# convert keys to strings
@@ -929,9 +961,12 @@ module ASF
availid = attrs['uid']
# determine next uid and group, unless provided
- nextuid = attrs['uidNumber'] ||
- ASF::search_one(ASF::Person.base, 'uid=*', 'uidNumber').
- flatten.map(&:to_i).max + 1
+ nextuid = attrs['uidNumber']
+ if nextuid
+ raise ArgumentError.new("gidNumber #{gidNumber} != uidNumber #{uidNumber}") unless attrs['gidNumber'] == nextuid
+ else
+ nextuid = next_uidNumber
+ end
# fixed attributes
attrs.merge!({
@@ -943,7 +978,7 @@ module ASF
})
# defaults
- attrs['loginShell'] ||= '/usr/local/bin/bash'
+ attrs['loginShell'] ||= '/bin/bash' # as per asfpy.ldap
attrs['homeDirectory'] ||= File.join("/home", availid)
attrs['host'] ||= "home.apache.org"
attrs['asf-sascore'] ||= "10"
@@ -951,20 +986,15 @@ module ASF
# parse name if sn has not been provided (givenName is optional)
attrs = ASF::Person.ldap_name(attrs['cn']).merge(attrs) unless attrs['sn']
- # generate a password that is between 8 and 16 alphanumeric characters
- unless attrs['userPassword']
- while attrs['userPassword'].to_s.length < 8
- attrs['userPassword'] = SecureRandom.base64(12).gsub(/\W+/, '')
- end
- end
+ # user is expected to use id.apache.org to set their initial password
+ attrs['userPassword'] = '{CRYPT}*' # invalid password (I assume)
# create new LDAP person
entry = attrs.map {|key, value| mod_add(key, value)}
ASF::LDAP.add("uid=#{availid},#{base}", entry)
- # return person object with password filled in
+ # return person object; they must use id.apache.org to reset the password
person = ASF::Person.find(availid)
- person.attrs['userPassword'] = [attrs['userPassword']]
person
end