[PATCH] Save all data to sysdb in one transaction
by Sumit Bose
Hi,
this patch for master saves all IPA HBAC data in one transaction and
proceeds if the sysdb transaction fails. It addresses a review comment
from the "Use new schema for HBAC service checks" patch.
The first patch changes the handling of the host data to be compatible
with the other data. The second removes the individual transactions and
introduces a common sysdb transaction.
Do we want/need a similar patch for master, too?
bye,
Sumit
13 years
[PATCH] Check for controls before using them
by Simo Sorce
Some time ago I added code to fetch the rootdse on connection, but
didn't publicize it too much.
Attached find 2 patches.
1) Rework the way we store data fetched from the rootdse so the it is
more useful and is actually attached to the ldap handle.
2) Check controls are supported before using them.
Simo.
--
Simo Sorce * Red Hat, Inc * New York
13 years
[PATCH] Make ldap bind asynchronous
by Martin Nagy
Hi,
this is (hopefully) my last stab at asynchronous ldap bind. I have
tested it on fedora and it seems to work pretty ok, but I haven't tried
it yet with an older openldap where the asynchronous connections aren't
supported.
Martin
13 years, 1 month
[PATCH] Fix two problems with --as-needed
by Jakub Hrozek
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
On Fedora, I saw two problems when building and using sssd with
- -Wl,--as-needed:
The configure-time check for HAVE_DBUS_WATCH_GET_UNIX_FD wasn't run
correctly which resulted in using the deprecated DBus function and
subsequent GCC warning. The other issue was that the LDAP backend
wouldn't start and complained about "libsss_ldap.so: undefined symbol:
hash_error_string".
The attached patch addresses them. It is at least partial fix for #559.
Jakub
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkxO5PEACgkQHsardTLnvCVqzACfVKjUjDMLP5OWK9md9hoL7nbU
TNcAn2fXTvI1SIPlxJ5faPYgO23zAnCp
=OUib
-----END PGP SIGNATURE-----
13 years, 1 month
Special HBAC rules
by Dmitri Pal
Hello,
On a discussion about the UI for HBAC rules it occured to me that there
is a use case that we currently do not support with IPA<->SSSD.
I do not think it will be an issue for IPAv2 and SSSD 1.5 or but down
the road probably yes. So I want to put together a good description of
the feature into a trac ticket.
But I need to ask questions first, thus this email.
The HBAC is good for the cases when a group of admins has access to the
group of the machines.
But those rules are not that good for the laptop use case.
Effectively the access to any laptop will usually be controlled by the
two logical rules:
* Allow a group of admins to access a group of the laptops - this is
handled well with HBAC rules.
* Allow the owner of the laptop to access the laptop locally and
remotely. Hm... But how to express this without creating individual
rules for every user-laptop pair?
Here is what comes to mind.
In the HBAC rule we have the concept of the hostCategory. Currently we
support only "All". But we can easily support the category "Laptop" or
"Personal Computer" to be more generic and add a special string
attribute "hostPattern" that will contain a pattern that will allow to
match host name and the user name. By placing users and groups into such
rule we will effectively allow laptop users access to their own machines.
Here is the example:
my login name is dpal (short one) and dpal(a)redhat.com is long one. My
host name is dpal.laptop
So if I create an HBAC rule:
dn: ipaUniqueID=49af8430-cbed-11dd-ad8b-0800200c9a66, cn=hbac,...
objectClass: top
objectClass: ipaAssociation
objectClass: ipaHBACRule
ipaUniqueID: 49af8430-cbed-11dd-ad8b-0800200c9a66
accessRuleType: allow
memberUser: cn=dpal,cn=users,cn=accounts,...
memberUser: cn=sgallagh,cn=users,cn=accounts,...
memberUser: cn=ssorce,cn=users,cn=accounts,...
memberUser: cn=ssbose,cn=users,cn=accounts,...
memberUser: cn=Brnodev,cn=groups,cn=accounts,...
memberService: cn=ssh,cn=hbacservices,cn=accounts,...
hostCategory: laptop
hostPattern: %short%.laptop
...
This rule grants individual users listed above and Brno developers access to the machines who's name starts with the short name of user and has suffix ".laptop".
The only drawback is that the admins would have to use some kind of pattern for the personal machine names derived from the user name. IMO this is a reasonable suggestion for those who want to start to control access via HBAC rules,
Potentially we can support several patterns in one HBAC rule if there different naming conventions due to acquisitions and other historical reasons.
Thoughts?
--
Thank you,
Dmitri Pal
Engineering Manager IPA project,
Red Hat Inc.
-------------------------------
Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
13 years, 1 month
[PATCH] Validate keytab at startup
by Jakub Hrozek
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
In addition to validating the keytab everytime a TGT is requested, we
also validate the keytab on back end startup to give early warning that
the keytab is not usable.
Fixes: #556
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkxHF4YACgkQHsardTLnvCUHuwCfdvEPJkqZqAs2XYW0g/TVgUCt
H5oAoKO1CG++6xQQi02dTss/Hjo5uPa2
=N5+t
-----END PGP SIGNATURE-----
13 years, 2 months
[PATCHES] Fix severe performance problems with initgroups
by Stephen Gallagher
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Users who are a member of one or more groups containing large numbers of
members end up with unacceptable wait times (or timeouts) performing
initgroups calls.
Since initgroups calls are always performed on login, this is causing
unacceptably long login waits.
This is happening because we tried to be too clever with the initgroups
calls. When a user logs in, we attempt to completely refresh all entries
associated with all groups the user is a member of. This worked fine in
our small test environments, but we didn't adequately test this for
scalability. Our customers are now doing this for us and are not pleased
with the results.
This patch alters the RFC2307 processing to only update the sysdb with
information about the current user. This means that there is only one
round-trip to the LDAP server, and also that the sysdb will not need to
process many user entries all at once.
Patch 0001: Add sysdb_attrs_to_list() utility function
This is a simple utility to grab the values of a particular attributes
from a sysdb_attrs list.
Patch 0002: Add a utility function to compare two non-ordered lists of
strings. It stores the first list as keys in a dhash table, then
attempts to remove all the keys in the second list with dhash_remove().
If the return value is success, that value was in both, if it's not
found, then it was only in the second list. The leftover keys at the end
are returned as the values only in the first list.
Patch 0003: Add sysdb_group_dn_reverse()
This is a simple utility to just return the rdn name portion of a
distinguished name.
Patch 0004: Add a utility routine to duplicate a NULL-terminated list of
strings.
Patch 0005: Add sysdb_update_members function
This function will take a user, a list of groups that this user
should be added to and a list of groups the user should be removed
from and will recursively call sysdb_[add|remove]_group_member
Patch 0006: Clean up initgroups processing for RFC2307
Instead of recursively updating all users of each group the user
being queried belongs to, just add or remove membership for the
requested user.
This series of patches will fix
https://bugzilla.redhat.com/show_bug.cgi?id=617623 and
https://fedorahosted.org/sssd/ticket/478
This is a blocker for the 1.2.2 bugfix release.
- --
Stephen Gallagher
RHCE 804006346421761
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkxQhSsACgkQeiVVYja6o6MdoACgrHGdzRmWOqq/aNrL/2w3WOS1
dWsAnihlfn91CdWchy86qbQcbqRxHIUG
=itid
-----END PGP SIGNATURE-----
13 years, 2 months
Forking "Common" into a separate git repository
by Dmitri Pal
Hello,
Stephen an I have been discussing the split for a while.
When we were starting the SSSD we acknowledged that the time for
splitting out the tools part into a separate repository would come.
It seems this is the time. The versions of the tools released in 1.2.1
are pretty stable and there are no requirements for changes in them
until 1.5. So to avoid SSSD 1.3 and 1.4 dragging along the incomplete
enhancements we suggest that we create a separate repository for
everything that is currently under "common". This move would allow
separate schedules for development of those. It will also allow better
access control and patch submission process for the tools under
"common". It will also remove pressure for the review of the interim
patches until it is time to integrate.
This is not forking of the project. It is just a creation of the second
repository under the project (at least for now).
We will continue to use this list and same trac instance to track tasks
since the tools have more relation to SSSD than previously forked out
ELAPI project.
Here is the detailed plan:
* Stephen will finish with 1.2.2 and 1.3 releases early next week
* Stephen will create a new repository and move the code there, apply
the pending patches and create per library spec files later next week.
* Dmitri will create new milestones in the trac and move the tools
related tickets to the newly created buckets.
Comments welcome!
--
Thank you,
Dmitri Pal
Engineering Manager IPA project,
Red Hat Inc.
-------------------------------
Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
13 years, 2 months
ldap_result found nothing!
by Patrik Martinsson
Hello everybody,
I've just started configuring sssd on rhel 6 beta 2 against our Windows
AD Domain.
It looks like sssd is able to connect through ldap with password, but i
cant seem to get
any results from the ldap_search, and was hoping for any kind if
pointers/advises.
Here's how my sssd.conf looks,
--------------
[domain/FOO]
description = LDAP domain with AD server
enumerate = false
min_id = 1000
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://foo.bar:636
ldap_schema = rfc2307bis
ldap_default_bind_dn = cn=xx,ou=People,dc=xx,dc=xx,dc=xx
ldap_default_authtok_type = password
ldap_default_authtok = xx
ldap_search_base = DC=xx,DC=xx,DC=xx
ldap_user_search_scope = sub
ldap_user_search_base = ou=People,dc=xx,dc=xx,dc=xx
ldap_group_search_base = ou=Groups,dc=xx,dc=xx,dc=xx
ldap_user_object_class = person
ldap_user_name = cn
ldap_user_uid_number = msSFU30UidNumber
ldap_user_gid_number = msSFU30GidNumber
ldap_user_home_directory = msSFU30HomeDirectory
ldap_user_shell = msSFU30LoginShell
ldap_user_principal = userPrincipalName
ldap_group_object_class = group
ldap_group_name = posixGroup
ldap_group_gid_number = msSFU30GidNumber
ldap_force_upper_case_realm = True
ldap_tls_reqcert = demand
ldap_tls_cacert = /etc/openldap/cacerts/CADOUBLE.cer
ldap_tls_cacertdir = /etc/openldap/cacerts
--------------
Here's the output from sssd -d10 (the vital part, i think anyways)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_uri_callback] (6):
Constructed uri 'ldaps://foo.bar:636'
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_rootdse_send] (9):
Getting rootdse
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (6):
calling ldap_search_ext with [(objectclass=*)][].
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [*]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [altServer]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [namingContexts]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [supportedControl]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [supportedExtension]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [supportedFeatures]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [supportedLDAPVersion]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [supportedSASLMechanisms]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]]
[sdap_ldap_connect_callback_add] (9): New LDAP connection to
[ldaps://foo.bar:636] with fd [19].
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (8):
ldap_search_ext called, msgid = 1
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b8c840], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_parse_entry] (9):
OriginalDN: []. <<<= ####### SHOULD THIS BE EMPTY? ########
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b8c840], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_done] (6):
Search result: Success(0), (null)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_rootdse_done] (9):
Got rootdse
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [simple_bind_send] (4):
Executing simple bind as: cn=xx,ou=People,dc=xx,dc=xx,dc=xx
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [simple_bind_send] (8): ldap
simple bind sent, msgid = 2
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b6a7b0], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: ldap_result found nothing!
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b6a7b0], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [simple_bind_done] (5):
Server returned no controls.
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [simple_bind_done] (3): Bind
result: Success(0), (null)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [fo_set_port_status] (4):
Marking port 636 of server 'foo.bar' as 'working'
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [set_server_common_status]
(4): Marking server 'foo.bar' as 'working'
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (6):
calling ldap_search_ext with
[(&(cn=xx)(objectclass=person))][ou=People,dc=ad,dc=smhi,dc=se].
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [objectClass]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [cn]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [userPassword]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [msSFU30UidNumber]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [msSFU30GidNumber]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [gecos]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [msSFU30HomeDirectory]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [msSFU30LoginShell]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [userPrincipalName]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [cn]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [memberOf]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [nsUniqueId]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [modifyTimestamp]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowLastChange]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowMin]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowMax]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowWarning]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowInactive]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowExpire]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [shadowFlag]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [krbLastPwdChange]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [krbPasswordExpiration]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (7):
Requesting attrs: [pwdAttribute]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_send] (8):
ldap_search_ext called, msgid = 3
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b69c30], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: ldap_result found nothing!
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b69c30], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_parse_entry] (9):
OriginalDN: [CN=a001584,OU=People,DC=ad,DC=smhi,DC=se].
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[0x1b69c30], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_generic_done] (6):
Search result: Success(0), (null)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_users_process] (6):
Search for users, returned 1 results.
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: sh[0x1a91b30], connected[1], ops[(nil)], ldap[0x1a91d90]
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_process_result] (8):
Trace: ldap_result found nothing!
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [ldb] (9): start ldb
transaction (nesting: 0)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_save_user_send] (9):
Save user
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_save_user_send] (1): no
uid provided for [xx] in domain [FOO].
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_save_users_process]
(2): Failed to store user 0. Ignoring.
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [ldb] (9): commit ldb
transaction (nesting: 0)
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [sdap_get_users_done] (9):
Saving 1 Users - Done
(Thu Jul 29 13:05:48 2010) [sssd[be[FOO]]] [acctinfo_callback] (4):
Request processed. Returned 0,0,Success
Here's how a working ldapsearch looks like,
ldapsearch -x -L -Hldaps://foo.bar/ -D
'cn=xxbind,ou=People,dc=xx,dc=xx,dc=xx' -w xxbindpwd -b
'dc=xx,dc=xx,dc=xx' '(&(cn=xx)(objectclass=person))' cn uid
This returns, as expected cn/uid for the requested user.
As i said, any tips is appreciated.
I'm not an expert in ldap nor AD, so please go easy on me.
/Patrik Martinsson, Sweden.
13 years, 2 months
[PATCHES] INI and Collection
by Dmitri Pal
Hello,
This is the set of patches that start to build up the new INI config
interface.
Since some functionality required additions to the collection the
collection was updated.
All the the patches have patch comments that explain what the patch does
if it is not clear from the name.
I tried to keep the patches small for easier review. Only one is
actually big but has an extensive comment explaining the logic.
The patches should be applied in the provided order on top of the 6
patches that are currently pending.
0001--COLLECTION-Allow-destroying-collection-with-a-call.patch - adds a
cleanup with callback
0002--BASICOBJ-Added-a-convenience-function.patch - I was struggling
with type casting. It turned that it is simpler just to add a function
that adds a const char* instead of type casting to void *.
0003--INI-More-config-files-for-testing.patch - Needed a variety of the
config files to test so added couple
0004--INI-Extend-the-comment-interface.patch -Added a function to use
already known length of the string instead of counting it again.
0005--INI-Add-error-codes-for-the-new-parser.patch - New parser will
require couple new error codes, so I added them
0006--INI-Fixes-to-the-value-object.patch - Value object has some issues
so was corrected and enhanced.
0007--INI-The-beginning-of-the-new-INI-interface.patch - Started the new
high level config interface obscuring the collection.
0008--INI-New-INI-parser.patch - (BIG!) The INI new parser.
0009--INI-COLLECTION-Correcting-library-and-project-vers.patch -
Corrected the versions of the libraries and projects
Also noticed that the spec file should be updated to include the basic
object. I think we need a separate ticket for that. Agree?
I can try to do it but probably a bit later.
I tested new code with unit tests and ran it via valgrind.
The patches are starting to pile up and rot. I already had some hard
time merging them with the spec file.
I understand that we have other priorities but we need to come up with
some way with dealing with these patches too.
Reviewers welcome!
--
Thank you,
Dmitri Pal
Engineering Manager IPA project,
Red Hat Inc.
-------------------------------
Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
13 years, 2 months