Re: [Freeipa-devel] Finishing the Community Portal
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
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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