google-code-export / ruby-activeldap

Automatically exported from code.google.com/p/ruby-activeldap
Other
1 stars 1 forks source link

ppolicy special value not supported #53

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. use ppolicy and have a user accont blocked
2. retrieve user with u = User.find('myuser', :attributes => ['+'])
3. print pwd_account_locked_time
>> u.pwd_account_locked_time
=> Sat Jan 01 00:00:00 UTC 2000

What is the expected output? What do you see instead?
Expected output is some value like '00000101000000Z'
instead, time is set to 01/01/2000 : Sat Jan 01 00:00:00 UTC 2000

What version of the product are you using? On what operating system?
activeldap-1.2.2

Please provide any additional information below.
The patch attached to this issue seems to workaround this issue:
diff --git a/lib/active_ldap/schema/.syntaxes.rb.swp 
b/lib/active_ldap/schema/.syntaxes.rb.swp
deleted file mode 100644
index 4dce9aa..0000000
Binary files a/lib/active_ldap/schema/.syntaxes.rb.swp and /dev/null differ
diff --git a/lib/active_ldap/schema/syntaxes.rb 
b/lib/active_ldap/schema/syntaxes.rb
index b6c26c1..8b7fa77 100644
--- a/lib/active_ldap/schema/syntaxes.rb
+++ b/lib/active_ldap/schema/syntaxes.rb
@@ -164,6 +164,7 @@ module ActiveLdap
       end

       class GeneralizedTime < Base
+        LOCKED_TIME = '00000101000000Z'
         SYNTAXES["1.3.6.1.4.1.1466.115.121.1.24"] = self
         FORMAT = /\A
                   (\d{4,4})?
@@ -177,7 +178,7 @@ module ActiveLdap
                  \z/x

         def type_cast(value)
-          return value if value.nil? or value.is_a?(Time)
+          return value if value.nil? or value.is_a?(Time) or value == 
LOCKED_TIME
           match_data = FORMAT.match(value)
           if match_data
             required_components = match_data.to_a[1, 6]

Original issue reported on code.google.com by chan...@gmail.com on 24 Sep 2010 at 4:13

Attachments:

GoogleCodeExporter commented 9 years ago
Umm. I can't understand why ActiveLdap should return '00000101000000Z' instead 
of Time.

Could you show your application code that uses ppolicy pwd_account_locked_time? 
Should we check special account lock value on the general syntax layer? Is 
application layer or more upper layer not appropriate?

Original comment by kou...@gmail.com on 3 Oct 2010 at 1:30

GoogleCodeExporter commented 9 years ago

Original comment by kou...@gmail.com on 3 Oct 2010 at 1:30

GoogleCodeExporter commented 9 years ago
Hi koutou,

Tks for looking after that.

00000101000000Z is a special ppolicy overlay value. When an account has  
pwd_account_locked_time set to this value, the overlay will consider it has 
"disabled".

With the default ActiveLdap code, when the account is disabled, 
u.pwd_account_locked_time returns Sat Jan 01 00:00:00 UTC 2000 which should 
actually match LDAP time "20000101000000Z" instead of "00000101000000Z".

In ppolicy code, the special value "00000101000000Z" is actually considered as 
time 0, hence 19700101000000Z.

In my opinion, account locked value should not be handled at the general syntax 
layer, but I dont see any other ways of accessing this special value/case from 
the object itself. Even u.pwd_account_locked_time.to_i returns a timestamp 
matching "Sat Jan 01 00:00:00 UTC 2000"

I also believe that the culprit might actually be the Time class from ruby as 
the following code return a 2000 year time instead of raising an error:
>> Time.send(:make_time,0,1,1,0,0,0,0,'Z',Time.now)
=> Sat Jan 01 00:00:00 UTC 2000

If this was raising an error, then the time returned would be 0 and that would 
allow me to check if wether or not the account is disabled.

Maybe instead of returning '00000101000000Z' the class could check if it is 
'00000101000000Z' and then return Time.at(0).
Then, at application layer, one could check
if u.pwd_account_locked_time.to_i == 0
  account_is_disabled
else
  acount_is_not_disabled
end

Or another solution would be to be able to access the raw LDAP value from 
u.pwd_account_locked_time.

I am really new to ruby so I might not be able to help much outside of 
reporting this issue. I found a dirty solution so far, but I have to agree this 
is not the way to solve it :)

Looking at LDAP code, the parsing time function used by ppolicy overlay is 
http://www.openldap.org/devel/cvsweb.cgi/~checkout~/libraries/liblutil/utils.c?r
ev=1.73&hideattic=1&sortbydate=0 at line 154:
int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )

    /* special case 0000/01/01+00:00:00 is returned as zero */
    if ( tm->tm_year == -1900 && tm->tm_mon == 0 && tm->tm_mday == 1 &&
        tm->tm_hour == 0 && tm->tm_min == 0 && tm->tm_sec == 0 ) {
        tt->tt_sec = 0;
        tt->tt_gsec = 0;
        return 0;
    }

So it seems OpenLDAP actually handle this value as a special case within their 
main library.

More on ppolicy can be found here: http://linux.die.net/man/5/slapo-ppolicy

Original comment by chan...@gmail.com on 4 Oct 2010 at 11:18

GoogleCodeExporter commented 9 years ago
What about this?

  if u.pwd_account_locked_time_before_type_cast == "00000101000000Z"
    account_is_disabled
  else
    acount_is_not_disabled
  end

Original comment by kou...@gmail.com on 4 Oct 2010 at 1:17

GoogleCodeExporter commented 9 years ago
Hi koutou,

Thanks a million for that hint. This indeed solves my issue.
I am just too much of a ruby/ror noob to have spotted this out.

Sorry for taking some of your time on this one then :s

Original comment by chan...@gmail.com on 4 Oct 2010 at 1:36