Re: [Freeipa-devel] Finishing the Community Portal

2015-07-15 Thread Drew Erny
Yeah, user creation requires manual intervention; an admin has to move 
the user from staging to the main user tree.


It could be pretty easily modified to allow totally automated self 
sign-up though


On 07/15/2015 01:42 PM, Nathaniel McCallum wrote:

I'm pretty excited about this.

As I see it right now user creation requires manual intervention. Is this 
correct?

Is it possible to have a fully automated process where a token is generated and 
mailed to the user to verify their email address?

- Original Message -

Hi, all,

I'm just about finished with the Community Portal, which I've said a
couple of times, but I really mean it this time. The Captcha was the
last technical detail that needed addressing. At this point, any further
programming is going to be dedicated to configuration of the application.

Right now, a organization could deploy the community portal in about a
day, if they had a programmer handy who pulled down my source, changed a
bunch of hard-coded configuration, and stuck it on a server.

This might be acceptable, especially in the first iteration of the
application, but it probably isn't. How do I go about packaging the web
app that I built so that it can be deployed quickly to a server?
Someone off-list, I think, mentioned making it deployable to OpenShift?

Basically, what do I have to do to call this application Finished?

The code is located at github.com/dperny/freeipa-communityportal

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code



--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] Finishing the Community Portal

2015-07-14 Thread Drew Erny

Hi, all,

I'm just about finished with the Community Portal, which I've said a 
couple of times, but I really mean it this time. The Captcha was the 
last technical detail that needed addressing. At this point, any further 
programming is going to be dedicated to configuration of the application.


Right now, a organization could deploy the community portal in about a 
day, if they had a programmer handy who pulled down my source, changed a 
bunch of hard-coded configuration, and stuck it on a server.


This might be acceptable, especially in the first iteration of the 
application, but it probably isn't. How do I go about packaging the web 
app that I built so that it can be deployed quickly to a server?  
Someone off-list, I think, mentioned making it deployable to OpenShift?


Basically, what do I have to do to call this application Finished?

The code is located at github.com/dperny/freeipa-communityportal

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] [RFC] Community Portal Captcha

2015-07-10 Thread Drew Erny

Hi, All,

I think some of you discussed with me the details of the community 
portal captcha with me on IRC. Yesterday, I wrote up a design proposal 
for the captcha system that I'd like some of you to take a look at and 
check to see that I'm understanding it correctly, and that this captcha 
method is secure.


http://www.freeipa.org/page/V4/Community_Portal_Captcha

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] [RFC] Community Portal - Where to go next?

2015-07-02 Thread Drew Erny

Hi, all,

The core functionality of the community portal is more-or-less complete. 
In a local development environment, you can go to a web page, put in 
information, and have that information reflected in the FreeIPA server. 
There's definitely some polishing needed (for example, there is no 
styling to the web pages), but the core functionality is all there.


What I need now is for someone to go through the source code, which can 
be found at github.com/dperny/freeipa-communityportal, and let me know 
if everything seems sound and sane.


I also, perhaps more importantly, need some help on where to go with 
this next. The core functionality is all there, but how I'm going to 
deploy this to a live environment is still a bit hazy where I should 
start to make that happen. There are many ways to deploy a cherrypy web 
application, and I'm not sure which path is best. Or, if deployment 
isn't important yet at this stage in the prototype, what should I focus 
my efforts on now?


Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] IPA Python API

2015-06-25 Thread Drew Erny

If I add the lines

if not api.Backend.rpcclient.isconnected():
api.Backend.rpcclient.connect()


before I call the api, the code works. Problem (pretty much) solved.

On 06/23/2015 04:36 PM, Drew Erny wrote:

Resurrecting this thread, because the problem is getting me again.

If I go through the python interpreter and import the code that calls 
the ipalib, and then manually call it myself the way the webserver 
does, the code works. If the same code is run in the course of the web 
server process, I get the error:


Traceback (most recent call last):
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/_cprequest.py, 
line 670, in respond

response.body = self.handler()
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/lib/encoding.py, 
line 217, in __call__

self.body = self.oldhandler(*args, **kwargs)
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/_cpdispatch.py, 
line 61, in __call__

return self.callable(*self.args, **self.kwargs)
  File freeipa_community_portal/app.py, line 39, in POST
errors = user.save()
  File freeipa_community_portal/model/user.py, line 33, in save
self._call_api()
  File freeipa_community_portal/model/user.py, line 45, in _call_api
mail=self.email
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 
439, in __call__

ret = self.run(*args, **options)
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 
755, in run

return self.forward(*args, **options)
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 
776, in forward

return self.Backend.rpcclient.forward(self.name, *args, **kw)
  File /usr/lib/python2.7/site-packages/ipalib/rpc.py, line 880, in 
forward

command = getattr(self.conn, name)
  File /usr/lib/python2.7/site-packages/ipalib/backend.py, line 97, 
in __get_conn

self.id, threading.currentThread().getName())
AttributeError: no context.rpcclient in thread 'CP Server Thread-6'

The error shows up whether the server is run from within the python 
interpreter or by itself.


I kinit and have a TGT from the IPA server. The client machine is 
registered with the IPA server. When I run the commands by hand, an 
HTTP ticket can be seen in the klist. When I run the webserver, no 
HTTP ticket is ever recieved, so the code is failing on the client 
side before it even gets to the server.


Which is obviously not what should be happening. It's the same error I 
got when I was using Flask, and now I'm using cherrypy and it's still 
broken. Could this have something to do with the web server being a 
multithreaded environment?




--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [RFC] Self-service Password Reset

2015-06-25 Thread Drew Erny



On 06/25/2015 03:07 PM, Simo Sorce wrote:

On Thu, 2015-06-25 at 14:40 -0400, Drew Erny wrote:

Hi, All,

FreeIPA's most requested feature just got a proposal.

Check it out at http://www.freeipa.org/page/V4/Self_Service_Password_Reset

I eagerly await your explanations of why this is a terrible idea.

Well clearly it is a security nightmare :-D
Anyway point 6, it is better to not send any password via email.
I see 2/3 options here.
1) Just show the user the new password and a link to go and reset it.
2) Just redirect the user to the Self-Service Password change page and
pre-fill the old password fields with the newly minted password.
3) Provide a password change with hidden old-password fields straight on
the self-service portal.
I think when I was running this past my peers, they mentioned these 
concerns, and I must've forgotten to update the draft.


While 2 would be somewhjat nice it is probably difficult because of CSRF
protections in FreeIPA, and besides if you already have the password you
might as well just use it immediately and save the redirect. So I would
prefer 3.

I prefer 3 as well; I'll amend the draft right now.


Simo.



--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [RFC] Self-service Password Reset

2015-06-25 Thread Drew Erny



On 06/25/2015 03:13 PM, Drew Erny wrote:



On 06/25/2015 03:07 PM, Simo Sorce wrote:

On Thu, 2015-06-25 at 14:40 -0400, Drew Erny wrote:

Hi, All,

FreeIPA's most requested feature just got a proposal.

Check it out at 
http://www.freeipa.org/page/V4/Self_Service_Password_Reset


I eagerly await your explanations of why this is a terrible idea.

Well clearly it is a security nightmare :-D
Anyway point 6, it is better to not send any password via email.
I see 2/3 options here.
1) Just show the user the new password and a link to go and reset it.
2) Just redirect the user to the Self-Service Password change page and
pre-fill the old password fields with the newly minted password.
3) Provide a password change with hidden old-password fields straight on
the self-service portal.
I think when I was running this past my peers, they mentioned these 
concerns, and I must've forgotten to update the draft.


While 2 would be somewhjat nice it is probably difficult because of CSRF
protections in FreeIPA, and besides if you already have the password you
might as well just use it immediately and save the redirect. So I would
prefer 3.

I prefer 3 as well; I'll amend the draft right now.


Simo.





Sorry, I jumped the gun on replying to this email and forgot to sanity 
check it.


Option 3 won't work, because when anybody who is not the user resets the 
user's password (including admins, IIRC), the user is prompted to reset 
their password upon first login. So, if the user sets a new password 
straight on the self-service portal, they'll have to change it 
immediately anyway, because the self-service portal will be the user 
resetting the password, not the actual user.


Option 1, just displaying the password to the user, is probably actually 
best. This way, they copy the password, paste it into the FreeIPA webui 
login form, and then get kicked into the FreeIPA webui password reset 
workflow, instead of setting a new password just to have to change it. 
We can show the password with a big message that says, USE THIS 
PASSWORD IMMEDIATELY. IT WILL NOT BE AVAILABLE AGAIN.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] [RFC] Self-service Password Reset

2015-06-25 Thread Drew Erny

Hi, All,

FreeIPA's most requested feature just got a proposal.

Check it out at http://www.freeipa.org/page/V4/Self_Service_Password_Reset

I eagerly await your explanations of why this is a terrible idea.

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] IPA Python API

2015-06-23 Thread Drew Erny

Resurrecting this thread, because the problem is getting me again.

If I go through the python interpreter and import the code that calls 
the ipalib, and then manually call it myself the way the webserver does, 
the code works. If the same code is run in the course of the web server 
process, I get the error:


Traceback (most recent call last):
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/_cprequest.py, 
line 670, in respond
response.body = self.handler()
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/lib/encoding.py, 
line 217, in __call__
self.body = self.oldhandler(*args, **kwargs)
  File 
/home/derny/freeipa/env/lib/python2.7/site-packages/cherrypy/_cpdispatch.py, 
line 61, in __call__
return self.callable(*self.args, **self.kwargs)
  File freeipa_community_portal/app.py, line 39, in POST
errors = user.save()
  File freeipa_community_portal/model/user.py, line 33, in save
self._call_api()
  File freeipa_community_portal/model/user.py, line 45, in _call_api
mail=self.email
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 439, in 
__call__
ret = self.run(*args, **options)
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 755, in run
return self.forward(*args, **options)
  File /usr/lib/python2.7/site-packages/ipalib/frontend.py, line 776, in 
forward
return self.Backend.rpcclient.forward(self.name, *args, **kw)
  File /usr/lib/python2.7/site-packages/ipalib/rpc.py, line 880, in forward
command = getattr(self.conn, name)
  File /usr/lib/python2.7/site-packages/ipalib/backend.py, line 97, in 
__get_conn
self.id, threading.currentThread().getName())
AttributeError: no context.rpcclient in thread 'CP Server Thread-6'

The error shows up whether the server is run from within the python 
interpreter or by itself.


I kinit and have a TGT from the IPA server. The client machine is 
registered with the IPA server. When I run the commands by hand, an 
HTTP ticket can be seen in the klist. When I run the webserver, no HTTP 
ticket is ever recieved, so the code is failing on the client side 
before it even gets to the server.


Which is obviously not what should be happening. It's the same error I 
got when I was using Flask, and now I'm using cherrypy and it's still 
broken. Could this have something to do with the web server being a 
multithreaded environment?


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Community Portal Prototype

2015-06-18 Thread Drew Erny

On 06/18/2015 03:53 AM, Petr Spacek wrote:

On 17.6.2015 21:21, Drew Erny wrote:

Hello, all,

I've built a prototype of the community portal, and I'd like a quick sanity
check on it. If someone would look over the architecture of this code and make
sure that the design is sensible before I proceed any further, that would be
very helpful. The source code can be found here:
https://github.com/dperny/freeipa-communityportal

This code should run on your machine, and you should be able to add users to
the staging tree. It might not, howver; the point is to have the code looked
at before I spend anymore time on it.

The Community Portal prototype is a Python Flask web-application that acts as
a client to a FreeIPA server. It collects input from the unwashed masses (in
the form of a user sign-up page) and then sends it to the FreeIPA server. This
way, the Community Portal acts like a gateway between the FreeIPA server and
the anonymous community users, restricting the commands they can send to the
server.

Right now, the server imports FreeIPA's Python ipalib module, which allows it
to act like a client. It uses api.Command.stageuser_add(...) to add new users
to the staging area of the FreeIPA database. It then sends an email to the
admin (or, rather, it logs an email to the console instead of sending one, in
the prototype) to alert them to the fact that a user has signed up.

All feedback is welcome.

It seems reasonable except for two things:

a) Most importantly, obtaining credentials for authentication to the FreeIPA
server is completely missing.

You need to 'somehow' fill in Kerberos credential cache with a valid ticket (~
equivalent of kinit user) and use this ticket for authentication to the
FreeIPA server.

Ugly and hacky way to do that can be seen in
https://git.fedorahosted.org/cgit/freeipa.git/tree/daemons/dnssec/ipa-ods-exporter?id=4dfa23256dc2e35480843beef92e03b1bafd578b#n395


Maybe you should use GSS-Proxy so your code does not have to deal with
authentication at all and let GSS-Proxy to do that for you behind the scenes.

https://fedoraproject.org/wiki/Features/gss-proxy
https://fedorahosted.org/gss-proxy/

Please ask Simo for further details.
This is definitely something I was keeping in mind, but I wasn't too 
worried about it in the short term, because I always assumed that the 
user would configure the Community Portal to run as a special user, and 
I know there is a way for machine users to get Kerberos tickets. I 
figured I'd work out the details of that once the design was approved, 
because the Community Portal will have a configuration script to deploy 
it, and setting up that authentication will be part of the configuration 
script.



b) I understand that this is a first prototype but we should replace the
e-mailing thingy before we release it. Direct generation of e-mails goes
against the spirit of (envisioned) notification system and has it's inherent
problems.

- It is not going to scale if you have a lot of requests.
- Does not allow additional logic (auto-approval/denial based on some criteria
etc.) built on top of that.

Also, e.g. public website using FreeIPA behind the scenes for user management
might want to auto-approve accounts and put them to some pre-defined group
with lowest possible privileges.

D-Bus hooks makes this auto-approval possible and does not depend on a cron
job, i.e. eliminates the delay. The hook can of course do anything, use your
imagination :-)


I hope this helps to clarify why I insist on proper hook.

With some tweaking emailing from the web application would scale fine if 
we use some sort of non-blocking call to send the emails. I think, 
because the Community Portal is an exterior fixture (it's a client to 
the FreeIPA server, not part of the server itself), it's outside of the 
purview of the planned message system. The Community Portal might live 
on a completely different server.


Furthermore, If we wanted to build additional logic on approve/deny a 
user, that would have to be done on the client side anyway, to enforce 
the separation of concerns I have here (where the FreeIPA main 
application doesn't even have to be aware that there is a self service 
portal). So, to auto-approve/deny, we would just add additional logic to 
the User.save() method. I do not know how this would be easily 
user-configurable, and I think it's probably a bit out of scope for now 
anyway.


So, basically, it's not clear to me why we need to be worrying about a 
proper D-Bus hook at this stage in the process.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] [RFC] Community Portal

2015-06-18 Thread Drew Erny

Hi, all,

More email about the community portal. This time, I have a design 
proposal for you:


http://www.freeipa.org/page/V4/Community_Portal

Tell me what you think.

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] Community Portal Prototype

2015-06-17 Thread Drew Erny

Hello, all,

I've built a prototype of the community portal, and I'd like a quick 
sanity check on it. If someone would look over the architecture of this 
code and make sure that the design is sensible before I proceed any 
further, that would be very helpful. The source code can be found here: 
https://github.com/dperny/freeipa-communityportal


This code should run on your machine, and you should be able to add 
users to the staging tree. It might not, howver; the point is to have 
the code looked at before I spend anymore time on it.


The Community Portal prototype is a Python Flask web-application that 
acts as a client to a FreeIPA server. It collects input from the 
unwashed masses (in the form of a user sign-up page) and then sends it 
to the FreeIPA server. This way, the Community Portal acts like a 
gateway between the FreeIPA server and the anonymous community users, 
restricting the commands they can send to the server.


Right now, the server imports FreeIPA's Python ipalib module, which 
allows it to act like a client. It uses api.Command.stageuser_add(...) 
to add new users to the staging area of the FreeIPA database. It then 
sends an email to the admin (or, rather, it logs an email to the console 
instead of sending one, in the prototype) to alert them to the fact that 
a user has signed up.


All feedback is welcome.

Thanks,

Drew

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] IPA Python API

2015-06-17 Thread Drew Erny



On 06/17/2015 01:24 AM, Jan Cholasta wrote:

Dne 16.6.2015 v 20:29 Drew Erny napsal(a):

Hi, All,
...

Call


api.Backend.rpcclient.connect(ccache=krbV.default_context().default_ccache()) 



to make the problem go away.
This doesn't work. The Flask application runs (as I mentioned in a 
different email) with or without this change, but it will not run in 
debug mode either way.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] IPA Python API

2015-06-16 Thread Drew Erny

Hi, All,

I'm using the IPA Python API to write the Community Portal. Most of the 
documentation for using the IPA Python API is targeted a plugin authors, 
and this isn't a plugin for (what I think are) good reasons. I'm doing


# in the main program
import api from ipalib
api.bootstrap(context=client)
api.finalize()
api.Backend.rpcclient.connect()

# and then, inside of a separate class
api.Command.stageuser_add(...)

Which is how doc/examples/python-api.py shows it.

However, calling api.Command.stageuser_add(...) causes
AttributeError: No context.rpcclient_... in thread 'Thread-1'

I think this is probably related to the fact that I haven't configured 
my program to connect to any particular IPA server, because before the 
program errors out, it prints:

ipa: INFO: Forwarding 'stageuser_add' to json server 'None'

If the problem is the lack of a target server, as I suspect, how would I 
configure the program to connect to a particular IPA server? If this 
isn't caused by that, what could the causes be?


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] IPA Python API

2015-06-16 Thread Drew Erny



On 06/16/2015 04:17 PM, Rob Crittenden wrote:

Drew Erny wrote:

On 06/16/2015 02:29 PM, Drew Erny wrote:

Hi, All,

I'm using the IPA Python API to write the Community Portal. Most of
the documentation for using the IPA Python API is targeted a plugin
authors, and this isn't a plugin for (what I think are) good reasons.
I'm doing

# in the main program
import api from ipalib
api.bootstrap(context=client)
api.finalize()
api.Backend.rpcclient.connect()

# and then, inside of a separate class
api.Command.stageuser_add(...)

Which is how doc/examples/python-api.py shows it.

However, calling api.Command.stageuser_add(...) causes
AttributeError: No context.rpcclient_... in thread 'Thread-1'

I think this is probably related to the fact that I haven't configured
my program to connect to any particular IPA server, because before the
program errors out, it prints:
ipa: INFO: Forwarding 'stageuser_add' to json server 'None'

If the problem is the lack of a target server, as I suspect, how would
I configure the program to connect to a particular IPA server? If this
isn't caused by that, what could the causes be?


I think this may be a bug. Even after doing ipa-client-install and
following exactly the guide outlined in this email
(https://www.redhat.com/archives/freeipa-users/2012-June/msg00334.html)
I still get the same error. I've poked around in the code around this,
though, and if it is a bug then I might need help because it's WAY deep
in the FreeIPA internals.

Also, forgot to mention, all of the ellipses (...) in the code in the
first email are elided code, not literal ellipses.



I wonder if it's detecting that you are in-tree so trying to use 
~/.ipa/default.conf.


This code:

from ipalib import api
api.bootstrap(context=client)
api.finalize()
api.Backend.rpcclient.connect()

# and then, inside of a separate class
print api.Command.user_show(u'admin')

produces this:

$ python derny.py
ipa: INFO: trying https://ipadev.greyoak.com/ipa/session/json
ipa: INFO: Forwarding 'user_show' to json server 
'https://ipadev.greyoak.com/ipa/session/json'
{u'result': {u'dn': 
u'uid=admin,cn=users,cn=accounts,dc=greyoak,dc=com', u'has_keytab': 
True, u'uid': (u'admin',), u'loginshell': (u'/bin/bash',), 
u'uidnumber': (u'59000',), u'gidnumber': (u'59000',), 
u'memberof_group': (u'admins', u'trust admins'), u'has_password': 
True, u'sn': (u'Administrator',), u'homedirectory': (u'/home/admin',), 
u'nsaccountlock': False}, u'value': u'admin', u'summary': None}


rob
I've sort of figured out the problem. I uninstalled the master-branch 
rpms I had, and then installed the latest FreeIPA from the fedora repos. 
Then, I was able to run the commands from the interpreter but the 
program still threw the same error. However, after some knob-twiddling, 
I've narrowed it down: running a Flask app with debug = True causes the 
error, but removing the debug line makes the code work. This doesn't 
explain why with the master build, the code throws errors in the python 
interpreter for me, which means something else is probably afoot (and 
probably our fault instead of Flask's), but I don't have any clue what 
it is.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] IPA Python API

2015-06-16 Thread Drew Erny

On 06/16/2015 02:29 PM, Drew Erny wrote:

Hi, All,

I'm using the IPA Python API to write the Community Portal. Most of 
the documentation for using the IPA Python API is targeted a plugin 
authors, and this isn't a plugin for (what I think are) good reasons. 
I'm doing


# in the main program
import api from ipalib
api.bootstrap(context=client)
api.finalize()
api.Backend.rpcclient.connect()

# and then, inside of a separate class
api.Command.stageuser_add(...)

Which is how doc/examples/python-api.py shows it.

However, calling api.Command.stageuser_add(...) causes
AttributeError: No context.rpcclient_... in thread 'Thread-1'

I think this is probably related to the fact that I haven't configured 
my program to connect to any particular IPA server, because before the 
program errors out, it prints:

ipa: INFO: Forwarding 'stageuser_add' to json server 'None'

If the problem is the lack of a target server, as I suspect, how would 
I configure the program to connect to a particular IPA server? If this 
isn't caused by that, what could the causes be?


I think this may be a bug. Even after doing ipa-client-install and 
following exactly the guide outlined in this email 
(https://www.redhat.com/archives/freeipa-users/2012-June/msg00334.html) 
I still get the same error. I've poked around in the code around this, 
though, and if it is a bug then I might need help because it's WAY deep 
in the FreeIPA internals.


Also, forgot to mention, all of the ellipses (...) in the code in the 
first email are elided code, not literal ellipses.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Community Portal Milestone

2015-06-12 Thread Drew Erny

Hey, all,

What fields, exactly, should a self-service user be able to enter?

Thanks,

Drew Erny

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] WebUI documentation

2015-06-11 Thread Drew Erny
I'm looking for documentation that provides a broader overview of the 
way the WebUI fits together and works. I have the source, of course, and 
I've been through Petr Voborni's documentation found at 
https://pvoborni.fedorapeople.org/doc/. That documentation explains some 
narrower concepts (like how navigation fits in, or what a facet alone 
does), but I'm having trouble finding documentation that broader and 
more general in scope. I'm looking for something that will show me how 
the machinery of the WebUI works, what the layers of the application 
look like and do, etc. Does something like this exist?


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Community Portal Milestone

2015-06-10 Thread Drew Erny

On 06/10/2015 02:52 AM, Martin Kosek wrote:

On 06/10/2015 05:11 AM, Adam Young wrote:

On 06/09/2015 06:34 PM, Simo Sorce wrote:

On Tue, 2015-06-09 at 16:15 -0400, Drew Erny wrote:

Hey, Freeipa, same thread new subtopic.

So, I was bouncing some ideas around with another developer (ayoung) and
I think I have a pretty good idea for self-service user registration.

The idea is that I put self-service user registration into its own
application that calls out to ipa user-add after getting admin approval.

Workflow goes like this:

1.) User goes to registration page, inputs details into form.
Registration page and application are not part of FreeIPA.
2.) User's registration goes into a non-FreeIPA database, something like
SQLite.
3.) Admin gets a notification email with a link to approve/deny
registration.
   A.) Admin clicks approval link, registration application (which has
limited privileges) makes call out to ipa user-add command, adding the
new user to FreeIPA.
   B.) Admin click deny link, user is not added.
4.) User's registration information, approved or denied, is deleted from
the external database.

This has a couple of advantages. For starters, it provides a layer of
protection against the creation of spam accounts. Accounts do not add
directly to LDAP (inserting to LDAP is a slow operation), instead sit in
intermediate area waiting approval. Second, we don't have to write a big
extension to ipa user-add or staginguser-add that allows anonymous
access to that command. Third, it can be bundled into its own package
and given to the community separate from FreeIPA proper. Finally, it
would allow me to gracefully defer becoming buried up to my neck in
D-Bus notifications and whatever other fanciness we want to send email,
because FreeIPA won't be sending the email.

Opinions?

You could avoid using an external database by using the new USer
Lifecycle management feature [1]. This will allow you to do a simple
ldapadd, but the user will not be enabled until an admin logs into the
FreeIPA interface to enable the user.
This manes your app never needs to see the admin's credentials or use
s4u2proxy and will pose a lower risk to the system.

The big issue was having an unauthentiucated user add o the datastore;  I don't
think you want to push new values directly into LDAP.  A separate Databse makes
a lot of sense, and using SQLite for a proof of concept allows us to migrate up
to MySQL for a live deployment.

The separate database does not make lot of sense to me, why not using the Stage
User tree when it's there, ready for you? I would like to know what is the
motivation and reasoning for using completely separate DB. Besides others, I
think Stage Users area for example checks for login name or UID/GID collisions.

The Selfservice just needs to operate under an identity that has a Stage User
Administrator privilege or we can create more contained privilege that could
just add the staged users and not modify/remove them.

Well, I'm led to believe that LDAP modifications are a slow operation. 
My concern is that if a site got hit with a load of spam, it could slow 
down a lot. Enforcing a separation between verified users (who are in 
the LDAP database) and the unwashed masses (who sit isolated in a small 
relational database, good performance) might be a good thing in a public 
environment. We're not talking about much of a database, either; it 
should top out at a couple dozen entries on a massive site if the admins 
are diligent in clearing it out. If the possible performance hit isn't a 
concern (and LDAP databases are not as slow as I'd guessed) then I'll 
just the user staging area. Is performance a concern?


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Community Portal Milestone

2015-06-10 Thread Drew Erny



On 06/10/2015 10:16 AM, Martin Kosek wrote:
AFAIK, this work would form some standalone page utilizing the FreeIPA 
Web UI framework we have already, to get the same look and feel. Using 
FreeIPA API to store/manipulate user entries should be thus much 
easier, then taking care of separate database. Also, if Stage user 
tree is used, the admins doing the validation of user entries may also 
have other responsibilities in FreeIPA, so they may welcome having 
these entries in Stage User in the FreeIPA Web UI without going to 
special application. Just my thoughts, I would welcome other feedback. 
I'm worried if I try to fit this into the existing WebUI framework, I'm 
gonna end up wrangling with the fact that the WebUI expects to have an 
authenticated LDAP user, but we need anonymous access for both 
self-service registration and (eventually) for password reset. I'm not 
sure what kind of changes would be needed to make this work. I'll use 
the stageuser tree either way, though; your argument on that is 
definitely correct.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Community Portal Milestone

2015-06-09 Thread Drew Erny

Hey, Freeipa, same thread new subtopic.

So, I was bouncing some ideas around with another developer (ayoung) and 
I think I have a pretty good idea for self-service user registration.


The idea is that I put self-service user registration into its own 
application that calls out to ipa user-add after getting admin approval.


Workflow goes like this:

1.) User goes to registration page, inputs details into form. 
Registration page and application are not part of FreeIPA.
2.) User's registration goes into a non-FreeIPA database, something like 
SQLite.
3.) Admin gets a notification email with a link to approve/deny 
registration.
A.) Admin clicks approval link, registration application (which has 
limited privileges) makes call out to ipa user-add command, adding the 
new user to FreeIPA.

B.) Admin click deny link, user is not added.
4.) User's registration information, approved or denied, is deleted from 
the external database.


This has a couple of advantages. For starters, it provides a layer of 
protection against the creation of spam accounts. Accounts do not add 
directly to LDAP (inserting to LDAP is a slow operation), instead sit in 
intermediate area waiting approval. Second, we don't have to write a big 
extension to ipa user-add or staginguser-add that allows anonymous 
access to that command. Third, it can be bundled into its own package 
and given to the community separate from FreeIPA proper. Finally, it 
would allow me to gracefully defer becoming buried up to my neck in 
D-Bus notifications and whatever other fanciness we want to send email, 
because FreeIPA won't be sending the email.


Opinions?

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Password Maxlife 0 causes expiration of 90 days

2015-06-08 Thread Drew Erny



On 06/08/2015 02:42 AM, Martin Kosek wrote:

On 06/05/2015 05:07 PM, Simo Sorce wrote:

On Fri, 2015-06-05 at 10:37 -0400, Drew Erny wrote:

On 06/04/2015 05:41 PM, Alexander Bokovoy wrote:

On Thu, 04 Jun 2015, Drew Erny wrote:

https://fedorahosted.org/freeipa/ticket/2795

I've tracked down the source of this bug; it's nutty C stuff.

So, in daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c, when you
update password, the expiration time appears to be set in the
function ipapwd_CheckPolicy on line 631, which looks like

 data-expireTime = data-timeNow + pol.max_pwd_life;

So the bug has to be in how pol.max_pwd_life gets is value. So I
check around, pol is initialized like this:

 struct ipapwd_policy pol = {0};
 ...
 pol.max_pwd_life = IPAPWD_DEFAULT_PWDLIFE;

And IPAPWD_DEFAULT_PWDLIFE is a constant 90 days.

But then the actual value of max_pwd_life is obtained by passing pol
into the function ipapwd_getPolicy on line 577 or 590, depending on
the password change type.

Inside of ipapwd_getPolicy, there's a couple of lines starting at
line 393

 tmpint = slapi_entry_attr_get_int(pe, krbMaxPwdLife);
 if (tmpint != 0) {
 policy-max_pwd_life = tmpint;
 }:

Which sets the max password life to the returned value, unless this
function returns 0. However, the documentation from
/usr/include/dirsrv/slapi-plugin.h says that that function,
slapi_entry_attr_get_int, returns 0 if the entry does not contain
that attribute. So, since the value 0 is returned, an error is
assumed to have occurred that member of the struct is left
untouched... which means it's still set to the value it was set to
when it was initialized, 90 days.

So, when the expireTime is set at line 631, it's set to 90 days
because the value returned by slapi_entry_attr_get_int is 0.

I've checked to see if we can get some error context out of the pe
variable passed in, but it appears to be an opaque struct that the
user isn't meant to see the internals of.

I'm not really sure what to do with this knowledge. The only thing I
can think would be to use another sentinel value, like -1, to
indicate that the password does not expire; or, otherwise, to
document that there is no way to have non-expiring passwords, and
administrators can only set value to some far-future date, and then
close this bug. Or, we could just set the default expiration date to
be somewhere far in the future. I'm not really qualified to make a
call on how to proceed with this, but I'm capable of making the
change if someone more senior decides.

I can also totally see this issue with the interface of slapi-plugin
being the possible cause of many bugs.

You can use slapi_entry_attr_exists() to check if attribute does exist
and then treat result of slapi_entry_attr_get_int() as actual value.

Otherwise, that's a great investigation!

Using slapi_entry_attr_exists() clears us of having to worry about
getting an error condition back, but I'm still not confident how to
handle the 0 maximum. Should I just put in a far-future date?

The current behavior is completely intentional, not a side effect of the
code, the code was written that way intentionally.

However me may consider an RFE that requests different behavior, we
would have to devise a special value for krbMaxPwdLife that means
infinite.

Maybe. If we do this, we should also ban 0 as krbMaxPwdLife as it confuses
people.

Let us say, that the user sets krbMaxPwdLife to infinite, what is the wished
effect on the user entry? Should krbPasswordExpiration be simply removed/not
added when password is being set? As we cannot put any special word there, it
is GeneralizedTime syntax. I assume that our LDAP BIND/kinit code would need to
be checked that it reacts properly to missing value in that case.


I think 0 or -1 are both good sentinel values to indicate no password 
life, and it's probably unlikely that anyone is relying on the 
functionality of 0=90 days (especially if that functionality is 
undocumented, but I'm not sure if it is), so it might be safe to change 
when we roll over to 4.2.


Then, whichever flag we settle on, in the C code for password changes 
that sets the new expiration time, we just set that expiration time to 
the maximum value of time_t instead of adding the max lifetime.


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Password Maxlife 0 causes expiration of 90 days

2015-06-05 Thread Drew Erny


On 06/04/2015 05:41 PM, Alexander Bokovoy wrote:

On Thu, 04 Jun 2015, Drew Erny wrote:

https://fedorahosted.org/freeipa/ticket/2795

I've tracked down the source of this bug; it's nutty C stuff.

So, in daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c, when you 
update password, the expiration time appears to be set in the 
function ipapwd_CheckPolicy on line 631, which looks like


data-expireTime = data-timeNow + pol.max_pwd_life;

So the bug has to be in how pol.max_pwd_life gets is value. So I 
check around, pol is initialized like this:


struct ipapwd_policy pol = {0};
...
pol.max_pwd_life = IPAPWD_DEFAULT_PWDLIFE;

And IPAPWD_DEFAULT_PWDLIFE is a constant 90 days.

But then the actual value of max_pwd_life is obtained by passing pol 
into the function ipapwd_getPolicy on line 577 or 590, depending on 
the password change type.


Inside of ipapwd_getPolicy, there's a couple of lines starting at 
line 393


tmpint = slapi_entry_attr_get_int(pe, krbMaxPwdLife);
if (tmpint != 0) {
policy-max_pwd_life = tmpint;
}:

Which sets the max password life to the returned value, unless this 
function returns 0. However, the documentation from 
/usr/include/dirsrv/slapi-plugin.h says that that function, 
slapi_entry_attr_get_int, returns 0 if the entry does not contain 
that attribute. So, since the value 0 is returned, an error is 
assumed to have occurred that member of the struct is left 
untouched... which means it's still set to the value it was set to 
when it was initialized, 90 days.


So, when the expireTime is set at line 631, it's set to 90 days 
because the value returned by slapi_entry_attr_get_int is 0.


I've checked to see if we can get some error context out of the pe 
variable passed in, but it appears to be an opaque struct that the 
user isn't meant to see the internals of.


I'm not really sure what to do with this knowledge. The only thing I 
can think would be to use another sentinel value, like -1, to 
indicate that the password does not expire; or, otherwise, to 
document that there is no way to have non-expiring passwords, and 
administrators can only set value to some far-future date, and then 
close this bug. Or, we could just set the default expiration date to 
be somewhere far in the future. I'm not really qualified to make a 
call on how to proceed with this, but I'm capable of making the 
change if someone more senior decides.


I can also totally see this issue with the interface of slapi-plugin 
being the possible cause of many bugs.

You can use slapi_entry_attr_exists() to check if attribute does exist
and then treat result of slapi_entry_attr_get_int() as actual value.

Otherwise, that's a great investigation!


Using slapi_entry_attr_exists() clears us of having to worry about 
getting an error condition back, but I'm still not confident how to 
handle the 0 maximum. Should I just put in a far-future date?


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] Password Maxlife 0 causes expiration of 90 days

2015-06-04 Thread Drew Erny

https://fedorahosted.org/freeipa/ticket/2795

I've tracked down the source of this bug; it's nutty C stuff.

So, in daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c, when you update 
password, the expiration time appears to be set in the function 
ipapwd_CheckPolicy on line 631, which looks like


data-expireTime = data-timeNow + pol.max_pwd_life;

So the bug has to be in how pol.max_pwd_life gets is value. So I check 
around, pol is initialized like this:


struct ipapwd_policy pol = {0};
...
pol.max_pwd_life = IPAPWD_DEFAULT_PWDLIFE;

And IPAPWD_DEFAULT_PWDLIFE is a constant 90 days.

But then the actual value of max_pwd_life is obtained by passing pol 
into the function ipapwd_getPolicy on line 577 or 590, depending on the 
password change type.


Inside of ipapwd_getPolicy, there's a couple of lines starting at line 393

tmpint = slapi_entry_attr_get_int(pe, krbMaxPwdLife);
if (tmpint != 0) {
policy-max_pwd_life = tmpint;
}:

Which sets the max password life to the returned value, unless this 
function returns 0. However, the documentation from 
/usr/include/dirsrv/slapi-plugin.h says that that function, 
slapi_entry_attr_get_int, returns 0 if the entry does not contain that 
attribute. So, since the value 0 is returned, an error is assumed to 
have occurred that member of the struct is left untouched... which means 
it's still set to the value it was set to when it was initialized, 90 days.


So, when the expireTime is set at line 631, it's set to 90 days because 
the value returned by slapi_entry_attr_get_int is 0.


I've checked to see if we can get some error context out of the pe 
variable passed in, but it appears to be an opaque struct that the user 
isn't meant to see the internals of.


I'm not really sure what to do with this knowledge. The only thing I can 
think would be to use another sentinel value, like -1, to indicate that 
the password does not expire; or, otherwise, to document that there is 
no way to have non-expiring passwords, and administrators can only set 
value to some far-future date, and then close this bug. Or, we could 
just set the default expiration date to be somewhere far in the future. 
I'm not really qualified to make a call on how to proceed with this, but 
I'm capable of making the change if someone more senior decides.


I can also totally see this issue with the interface of slapi-plugin 
being the possible cause of many bugs.


Opinions?

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH 0001 v2] Migrate now accepts scope as argument

2015-06-04 Thread Drew Erny

Whoops, hit the wrong reply.

On 06/04/2015 03:34 PM, Drew Erny wrote:
This is the same patch sort of manually rebased on the master branch. 
I couldn't get it to cleanly rebase using tools, so I apply my commit 
line-by-line; the only changes I made were pulling the scope = 
_supported_scopes[options.get('scope')] out of the for loop I'd 
accidentally left it in, and moving the import statement to a 
different spot. Everything else should be the same, excep I 
incremented VERSION and edited the comment.


I do have to convert to tuple, because that argument is expected to be 
a tuple but .keys() returns a list.



On 06/04/2015 11:35 AM, Martin Basti wrote:

On 03/06/15 20:40, Drew Erny wrote:

Hi, all,

This is an updated patch, with the code changes suggested by Martin 
Batsi in my test email. The biggest difference is that I had to do


 from ldap import SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE

To get access to those constants in the global scope. This seems 
like a fairly clean solution, but if it's a code smell, feel free to 
suggest improvements. This should have identical behavior to the 
last patch, except it will autofill scope and no longer prompt 
interactively.


Thanks,

Drew Erny
de...@redhat.com



Hello,

please continue discussion in the same thread :)

API.txt was changed, please update VERSION file, increment minor 
version +1 and edit comment there. I forgot to tell you yesterday.


Can you rebase your patch to current master?
This patch is supposed to go to IPA 4.2.

Is the tuple conversion needed?
values=tuple(_supported_scopes.keys()),

Otherwise patch looks good.

Martin^2
--
Martin Basti




From 86618b48315c366d020fd1c6611d774602fb186d Mon Sep 17 00:00:00 2001
From: Drew Erny de...@redhat.com
Date: Thu, 4 Jun 2015 14:02:12 -0400
Subject: [PATCH] Migration now accepts scope as argument

Adds a new option to command ipa migrate-ds, --scope=[base,onelevel,subtree]
which allows the user to specify LDAP search depth for users and groups.
'onelevel' was the hard-coded level before this patch and is still
default. Specify 'subtree' to search nested OUs for users and groups.

fedorahosted.org/freeipa/ticket/2547
---
 API.txt |  3 ++-
 VERSION |  4 ++--
 ipalib/plugins/migration.py | 19 ++-
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index c47d800b126dced80a3a90b89ac2f00b6764b836..eca4e302021316f9b02e543a9dc8b029286696cc 100644
--- a/API.txt
+++ b/API.txt
@@ -2522,7 +2522,7 @@ output: Entry('result', type 'dict', Gettext('A dictionary representing an LDA
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
 command: migrate_ds
-args: 2,19,4
+args: 2,20,4
 arg: Str('ldapuri', cli_name='ldap_uri')
 arg: Password('bindpw', cli_name='password', confirm=False)
 option: DNParam('basedn?', cli_name='base_dn')
@@ -2538,6 +2538,7 @@ option: Str('groupignoreobjectclass*', autofill=True, cli_name='group_ignore_obj
 option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', csv=True, default=(u'groupOfUniqueNames', u'groupOfNames'))
 option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
 option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=(u'RFC2307bis', u'RFC2307'))
+option: StrEnum('scope', autofill=True, cli_name='scope', default=u'onelevel', values=(u'base', u'subtree', u'onelevel'))
 option: Bool('use_def_group?', autofill=True, cli_name='use_default_group', default=True)
 option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
 option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', csv=True, default=())
diff --git a/VERSION b/VERSION
index 6f6e363eb028027f789aff84256f58488d0a7964..fe746a7f5c47f02c838763bdda6cb1c61579f6ff 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=2010061412
 #  #
 
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=124
-# Last change: pvoborni - added topology management commands
+IPA_API_VERSION_MINOR=125
+# Last change: derny - migration now accepts scope as argument 
diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index 8b7dd9ef6c5e16ef39997f04ca935c4de3e56aa9..9dced137e5e8da5336c957ed567e3f26dd01d26a 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -19,6 +19,7 @@
 
 import re
 from ldap import MOD_ADD
+from ldap import SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE
 
 from ipalib import api, errors, output
 from ipalib import Command, Password, Str, Flag, StrEnum, DNParam, File, Bool
@@ -141,6 +142,10 @@ _dn_err_msg = _('Malformed DN')
 
 _supported_schemas = (u'RFC2307bis', u'RFC2307')
 
+# search scopes for users and groups when migrating
+_supported_scopes

[Freeipa-devel] [PATCH 0001 v2] Migrate now accepts scope as argument

2015-06-03 Thread Drew Erny

Hi, all,

This is an updated patch, with the code changes suggested by Martin 
Batsi in my test email. The biggest difference is that I had to do


 from ldap import SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE

To get access to those constants in the global scope. This seems like a 
fairly clean solution, but if it's a code smell, feel free to suggest 
improvements. This should have identical behavior to the last patch, 
except it will autofill scope and no longer prompt interactively.


Thanks,

Drew Erny
de...@redhat.com
From 168e910aef41bd1df661317168236287b2994822 Mon Sep 17 00:00:00 2001
From: Drew Erny de...@redhat.com
Date: Wed, 27 May 2015 09:52:42 -0400
Subject: [PATCH] Migration now accepts scope as argument

Adds a new option to command ipa migrate-ds,
--scope=[base,onelevel,subtree], which allows the user to specify LDAP
search depth for users and groups. 'onelevel' was the previous default
level. Specify 'subtree' to to search nested OUs for users and groups.

fedorahosted.org/freeipa/ticket/2547
---
 API.txt |  3 ++-
 ipalib/plugins/migration.py | 18 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/API.txt b/API.txt
index d987bc949948a280018f0f20d5af93838ecaeb20..da124c2d659510cf81d25a5708835cf8ed176efa 100644
--- a/API.txt
+++ b/API.txt
@@ -2450,7 +2450,7 @@ output: Entry('result', type 'dict', Gettext('A dictionary representing an LDA
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
 command: migrate_ds
-args: 2,18,4
+args: 2,19,4
 arg: Str('ldapuri', cli_name='ldap_uri')
 arg: Password('bindpw', cli_name='password', confirm=False)
 option: DNParam('basedn?', cli_name='base_dn')
@@ -2466,6 +2466,7 @@ option: Str('groupignoreobjectclass*', autofill=True, cli_name='group_ignore_obj
 option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', csv=True, default=(u'groupOfUniqueNames', u'groupOfNames'))
 option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
 option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=(u'RFC2307bis', u'RFC2307'))
+option: StrEnum('scope', autofill=True, cli_name='scope', default=u'onelevel', values=(u'base', u'subtree', u'onelevel'))
 option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
 option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', csv=True, default=())
 option: Str('userignoreobjectclass*', autofill=True, cli_name='user_ignore_objectclass', csv=True, default=())
diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index c8379420d539ac35901d99f981b4c8e2f0f89ffc..d922d67cbf1a91a201b3b985af36a34e7956300a 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -35,6 +35,8 @@ from ipapython.ipautil import write_tmp_file
 import datetime
 from ipaplatform.paths import paths
 
+from ldap import SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE
+
 __doc__ = _(
 Migration to IPA
 
@@ -140,6 +142,9 @@ _dn_err_msg = _('Malformed DN')
 
 _supported_schemas = (u'RFC2307bis', u'RFC2307')
 
+# search scopes for users and groups when migrating
+_supported_scopes = {u'base': SCOPE_BASE, u'onelevel': SCOPE_ONELEVEL, u'subtree': SCOPE_SUBTREE}
+_default_scope = u'onelevel'
 
 def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
 assert isinstance(dn, DN)
@@ -607,6 +612,15 @@ class migrate_ds(Command):
 doc=_('Load CA certificate of LDAP server from FILE'),
 default=None
 ),
+StrEnum('scope',
+cli_name='scope',
+label=_('Search scope'),
+doc=_('LDAP search scope for users and groups: base, onelevel, or '
+  'subtree. Defaults to onelevel'),
+values=tuple(_supported_scopes.keys()),
+default=_default_scope,
+autofill=True,
+),
 )
 
 has_output = (
@@ -711,13 +725,15 @@ can use their Kerberos accounts.''')
 exclude = options['exclude_%ss' % to_cli(ldap_obj_name)]
 context = dict(ds_ldap = ds_ldap)
 
+scope = _supported_scopes[options.get('scope')]
+
 migrated[ldap_obj_name] = []
 failed[ldap_obj_name] = {}
 
 try:
 entries, truncated = ds_ldap.find_entries(
 search_filter, ['*'], search_bases[ldap_obj_name],
-ds_ldap.SCOPE_ONELEVEL,
+scope,
 time_limit=0, size_limit=-1,
 search_refs=True# migrated DS may contain search references
 )
-- 
2.4.2

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Re: [Freeipa-devel] [PATCH 0001] Migrate now accepts scope as argument

2015-06-02 Thread Drew Erny
Sorry, the email address on that patch is wrong. It picked the old one 
off my personal box when I migrated my dotfiles. I don't know if that's 
important, but if the merger could 
s/dpe...@crimson.ua.edu/de...@redhat.com/g, that would be better. Sorry 
about that, I'll fix it in my next patch.


On 06/02/2015 04:23 PM, Drew Erny wrote:

Hi, all,

This is my first patch, which fixes Ticket #2547 at 
https://fedorahosted.org/freeipa/ticket/2547


It introduces a --scope option to ipa migrate-ds which allows the 
user to specify the search depth of a migration. The previous default 
behavior is the same as --scope=onelevel. To search nested OUs, the 
user uses --scope=subtree. --scope=base will cause the migrate script 
not to find anything, but has been included for completeness. Any 
other option is invalid and will cause the command to abort.


Please review this one carefully, because I'm only like 98% confident 
it doesn't break anything. The only thing I'm not sure about is that 
if you run ipa migrate-ds without --scope specified, it gives an 
interactive input for that option; I'm not sure if it's supposed to do 
that.


Thanks,

Drew Erny
de...@redhat.com




-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

[Freeipa-devel] [PATCH 0001] Migrate now accepts scope as argument

2015-06-02 Thread Drew Erny

Hi, all,

This is my first patch, which fixes Ticket #2547 at 
https://fedorahosted.org/freeipa/ticket/2547


It introduces a --scope option to ipa migrate-ds which allows the user 
to specify the search depth of a migration. The previous default 
behavior is the same as --scope=onelevel. To search nested OUs, the user 
uses --scope=subtree. --scope=base will cause the migrate script not to 
find anything, but has been included for completeness. Any other option 
is invalid and will cause the command to abort.


Please review this one carefully, because I'm only like 98% confident it 
doesn't break anything. The only thing I'm not sure about is that if you 
run ipa migrate-ds without --scope specified, it gives an interactive 
input for that option; I'm not sure if it's supposed to do that.


Thanks,

Drew Erny
de...@redhat.com
From b50522be44ade6af8ddd24f33eac100af67bc101 Mon Sep 17 00:00:00 2001
From: Drew Erny dpe...@crimson.ua.edu
Date: Wed, 27 May 2015 09:52:42 -0400
Subject: [PATCH] Migration now accepts scope as argument

Adds a new option to command ipa migrate-ds,
--scope=[base,onelevel,subtree], which allows the user to specify LDAP
search depth for users and groups. 'onelevel' was the previous default
level. Specify 'subtree' to to search nested OUs for users and groups.

fedorahosted.org/freeipa/ticket/2547
---
 API.txt |  3 ++-
 ipalib/plugins/migration.py | 18 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/API.txt b/API.txt
index d987bc949948a280018f0f20d5af93838ecaeb20..f8f0bb1955b21385d85e59d7683698a30ca37181 100644
--- a/API.txt
+++ b/API.txt
@@ -2450,7 +2450,7 @@ output: Entry('result', type 'dict', Gettext('A dictionary representing an LDA
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
 command: migrate_ds
-args: 2,18,4
+args: 2,19,4
 arg: Str('ldapuri', cli_name='ldap_uri')
 arg: Password('bindpw', cli_name='password', confirm=False)
 option: DNParam('basedn?', cli_name='base_dn')
@@ -2466,6 +2466,7 @@ option: Str('groupignoreobjectclass*', autofill=True, cli_name='group_ignore_obj
 option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', csv=True, default=(u'groupOfUniqueNames', u'groupOfNames'))
 option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
 option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=(u'RFC2307bis', u'RFC2307'))
+option: StrEnum('scope', cli_name='scope', default=u'onelevel', values=(u'base', u'onelevel', u'subtree'))
 option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
 option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', csv=True, default=())
 option: Str('userignoreobjectclass*', autofill=True, cli_name='user_ignore_objectclass', csv=True, default=())
diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index c8379420d539ac35901d99f981b4c8e2f0f89ffc..da23d287afd9e21cb2e5f3edec9abfa9b98f0af4 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -139,6 +139,7 @@ _ref_err_msg = _('Migration of LDAP search reference is not supported.')
 _dn_err_msg = _('Malformed DN')
 
 _supported_schemas = (u'RFC2307bis', u'RFC2307')
+_supported_scopes = (u'base', u'onelevel', u'subtree')
 
 
 def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
@@ -607,6 +608,14 @@ class migrate_ds(Command):
 doc=_('Load CA certificate of LDAP server from FILE'),
 default=None
 ),
+StrEnum('scope',
+cli_name='scope',
+label=_('Search scope'),
+doc=_('LDAP search scope for users and groups: base, onelevel, or '\
+  'subtree. Defaults to onelevel'),
+values=_supported_scopes,
+default=_supported_scopes[1],
+),
 )
 
 has_output = (
@@ -711,13 +720,20 @@ can use their Kerberos accounts.''')
 exclude = options['exclude_%ss' % to_cli(ldap_obj_name)]
 context = dict(ds_ldap = ds_ldap)
 
+if options.get('scope') == 'base':
+scope = ds_ldap.SCOPE_BASE
+elif options.get('scope') == 'subtree':
+scope = ds_ldap.SCOPE_SUBTREE
+else:
+scope = ds_ldap.SCOPE_ONELEVEL
+
 migrated[ldap_obj_name] = []
 failed[ldap_obj_name] = {}
 
 try:
 entries, truncated = ds_ldap.find_entries(
 search_filter, ['*'], search_bases[ldap_obj_name],
-ds_ldap.SCOPE_ONELEVEL,
+scope,
 time_limit=0, size_limit=-1,
 search_refs=True# migrated DS may contain search references
 )
-- 
2.4.2

-- 
Manage your subscription for the Freeipa-devel mailing list

[Freeipa-devel] Testing Migration

2015-05-28 Thread Drew Erny

Hi, freeipa-devel,

More newbie questions. I have what I believe to be a fix for Ticket 
#2547 (https://fedorahosted.org/freeipa/ticket/2547) written, but I need 
to test this fix. I need to migrate an LDAP database that is in the 
previously expected for (all users and groups under 1 level) and migrate 
an LDAP database that is in a nested form where there might be many 
sub-ou's to search for users and groups. I need to make sure the outcome 
of both migrations is the same.


What would be the best way to go about this, more specifically than set 
up two LDAP server and migrate them. Like, what tools are available to 
help me get this set up? Also, how can I preserve my work so that next 
time we have to modify migration code, it can be easily tested? Should I 
spin up VMs and save the images?


Also, I can just send a patch if someone feels so utterly confident in 
the codebase that they can tell if the thing I've done is right or wrong 
just by looking at it.


Thanks,

Drew Erny
de...@redhat.com

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] Sudorules user validation help

2015-05-28 Thread Drew Erny
Ok, so should I write a regex that matches that broader pattern, and 
only allow sudorules users to be added that follow those broader 
restrictions?


On 05/28/2015 02:09 PM, Alexander Bokovoy wrote:

On Thu, 28 May 2015, Martin Kosek wrote:

On 05/28/2015 04:27 PM, Drew Erny wrote:

In the ticket, however, it's stated that if the user wants to use any
combination of weird characters, they should be able to. Would it be 
better to

just define a function like

def validate_username(username, ignore_pattern=False):

and have it ignore all username validation?


Tough question. FreeIPA in general tries to sanitize user input and 
does not
allow everything user wants and try to advise the best practices, as 
we see it.


In your case, if we allow only the 2 mentioned user login formats, it 
should
work for AD use case just fine and add some level of sanity check of 
the user
name. BTW, given we run an LDAP search later on this user name, isn't 
there a
possibility of LDAP injection if we choose to allow all characters, 
including

( and )? :-)

In any case, if we choose to ignore the pattern, we do not need the 
extra
validator function at all. We would just skip validation in the pre 
callback if

a user is being added.

I still think we should run the validator exactly for the reasons
outlined above. There are few limiting factors for Active Directory and
Linux environments -- while user and group objects names are specified
in 'cn' attirbute in Active Directory, in POSIX environment we get the
real name from sAMAccountName attribute for users:

* Certain characters in the Relative Distinguished Names of objects must
 be escaped using the backslash, \, escape character. The characters
 that must be escaped are:
   , \ # +   ;  =
 In addition, any leading or trailing spaces in the RDN must be escaped.

* The following characters are not allowed in sAMAccountName values:
[ ] : ; | = + * ?   / \ ,

* In Windows Server 2003 domains and above, if you do not assign a
value for sAMAccountName, the system will create a semi-random value for
your. This value will be similar to:
   $KJK000-H4GJL6AQOV1I

* The schema allows 256 characters in sAMAccountName values. However,
the system limits sAMAccountName to 20 characters for user and group 
objects and

16 characters for computer objects.
As you can see, group names may have ( and ), also ! and few more
characters which you have to escape properly before making them part of
the LDAP filter.

Additionally, we actually have to allow UTF-8 characters, not just
ASCII as syntax for DirectoryString (OID 1.3.6.1.4.1.1466.115.121.1.15)
requires that.





On 05/28/2015 09:40 AM, Drew Erny wrote:
OK, I see now what you mean by that. That is a simpler solution. 
I'll do it

that way.

On 05/28/2015 04:44 AM, Martin Kosek wrote:

On 05/27/2015 08:41 PM, Drew Erny wrote:

Hey, Freeipa-devel,

I'm working on ticket #3226 
(https://fedorahosted.org/freeipa/ticket/3226)


I've identified the problem. The sudorules add user command adds 
the user
validations at the end of it's pre-callback using 
add_external_pre_callback.
However, the user plugin pattern-matches a string for the uid 
param,

because it only allows certain characters.

I've been picking through the codebase and I think I have enough 
understanding
to ask this: What if we changed the user uid validation to a 
standalone
rule function (you can do that, right? pass in a function as a 
validation
rule?) that would normally just assert that the pattern matches, 
but could

have
that pattern matching validation overridden in some cases. I 
think that's the
easiest, cleanest way to change user so that sudorules and other 
plugins can
ignore this validation if necessary (I'm trying to figure out 
exactly how to

implement this without changing any APIs).

Am I understanding the plugin params API correctly, and can I do 
this? Is this

the best way to do this?

The only other solution I see is to write sudorules-specific code 
in some
plugin-related (either user.py or baseldap.py module, which would 
create

unwanted coupling.

Most specifically, this would be a change to the object 
instantiated at

ipalib/plugins/user.py line 467

Thoughts and suggestions?
I think it would make sense to follow the example with 
validate_hostname and

prepare a function validate_username(username, upn=False,
netbios_name=False) [1].

where upn would allow using @. on top of current validator (i.e.
u...@domain.test) and netbios_name would allow the DOMAIN\user 
style. I would
just suggest making sure the standard user validation error 
message is still

the same to avoid unnecessary QE fail positives.

In add_external_pre_callback you could then just simply call

validate_username(user, True, True)

just like it is already done with hostname.

My 2 cents.

Martin

[1]
https://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx 







--
Manage your subscription for the Freeipa-devel mailing list:
https

Re: [Freeipa-devel] Sudorules user validation help

2015-05-28 Thread Drew Erny
OK, I see now what you mean by that. That is a simpler solution. I'll do 
it that way.


On 05/28/2015 04:44 AM, Martin Kosek wrote:

On 05/27/2015 08:41 PM, Drew Erny wrote:

Hey, Freeipa-devel,

I'm working on ticket #3226 (https://fedorahosted.org/freeipa/ticket/3226)

I've identified the problem. The sudorules add user command adds the user
validations at the end of it's pre-callback using add_external_pre_callback.
However, the user plugin pattern-matches a string for the uid param,
because it only allows certain characters.

I've been picking through the codebase and I think I have enough understanding
to ask this: What if we changed the user uid validation to a standalone
rule function (you can do that, right? pass in a function as a validation
rule?) that would normally just assert that the pattern matches, but could have
that pattern matching validation overridden in some cases. I think that's the
easiest, cleanest way to change user so that sudorules and other plugins can
ignore this validation if necessary (I'm trying to figure out exactly how to
implement this without changing any APIs).

Am I understanding the plugin params API correctly, and can I do this? Is this
the best way to do this?

The only other solution I see is to write sudorules-specific code in some
plugin-related (either user.py or baseldap.py module, which would create
unwanted coupling.

Most specifically, this would be a change to the object instantiated at
ipalib/plugins/user.py line 467

Thoughts and suggestions?

I think it would make sense to follow the example with validate_hostname and
prepare a function validate_username(username, upn=False, netbios_name=False) 
[1].

where upn would allow using @. on top of current validator (i.e.
u...@domain.test) and netbios_name would allow the DOMAIN\user style. I would
just suggest making sure the standard user validation error message is still
the same to avoid unnecessary QE fail positives.

In add_external_pre_callback you could then just simply call

validate_username(user, True, True)

just like it is already done with hostname.

My 2 cents.

Martin

[1] 
https://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx


--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


[Freeipa-devel] Sudorules user validation help

2015-05-27 Thread Drew Erny

Hey, Freeipa-devel,

I'm working on ticket #3226 (https://fedorahosted.org/freeipa/ticket/3226)

I've identified the problem. The sudorules add user command adds the 
user validations at the end of it's pre-callback using 
add_external_pre_callback. However, the user plugin pattern-matches a 
string for the uid param, because it only allows certain characters.


I've been picking through the codebase and I think I have enough 
understanding to ask this: What if we changed the user uid validation 
to a standalone rule function (you can do that, right? pass in a 
function as a validation rule?) that would normally just assert that the 
pattern matches, but could have that pattern matching validation 
overridden in some cases. I think that's the easiest, cleanest way to 
change user so that sudorules and other plugins can ignore this 
validation if necessary (I'm trying to figure out exactly how to 
implement this without changing any APIs).


Am I understanding the plugin params API correctly, and can I do this? 
Is this the best way to do this?


The only other solution I see is to write sudorules-specific code in 
some plugin-related (either user.py or baseldap.py module, which would 
create unwanted coupling.


Most specifically, this would be a change to the object instantiated at 
ipalib/plugins/user.py line 467


Thoughts and suggestions?

Thanks,

Drew Erny
de...@redhat.com

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code