On 05/23/2011 04:45 PM, Jan Pazdziora wrote:
On Thu, May 19, 2011 at 11:46:37AM +0200, Ionuț Arțăriși wrote:
On 05/18/2011 05:05 PM, Jan Pazdziora wrote:
On Wed, May 18, 2011 at 02:38:54PM +0200, Ionuț Arțăriși wrote:
On 05/18/2011 01:14 PM, Jan Pazdziora wrote:

...
Nack. This is SQL-injection-prone. You have to use bind parameters
or sanitize the input properly.
Thanks, I have fixed the SQL issue.
It's still somewhat missing in your patch.
Ok, I think I now understood what you mean. Here's the re-patched patch :).
Good.

Now all that is left is make sure the call cannot be used to access
information which should not be accessible to the server. If you check
the getErrataInfo and take it as an example, you will see how to
authenticate / authorize, and we will need the query extended to join
with (probably) rhnServerChannel and rhnChannelErrata.


Thanks, I think this should be fixed now.
Those SQL IN operations seem to be quite tedious. Is there anywhere
that we could move this _bind_list function? Perhaps to something
like rhnSQL.bind_list? I haven't found any other helpers like this
already in rhnSQL, but I've seen it used in other places.
It is certainly possible.

I looked a bit more into rhnSQL and I found two more helpers in rhnSQL.sql_lib. It looks like a good place for adding the bind_list function.

-Ionuț
>From 3688631b956423aa3a0b31d370f98b177462272a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ionu=C8=9B=20Ar=C8=9B=C4=83ri=C8=99i?= <iartar...@suse.cz>
Date: Tue, 24 May 2011 14:53:40 +0200
Subject: [PATCH] added errata.getErrataNamesById function to the API

---
 backend/server/handlers/xmlrpc/errata.py |   56 ++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/backend/server/handlers/xmlrpc/errata.py b/backend/server/handlers/xmlrpc/errata.py
index 5b11637..ef161cd 100644
--- a/backend/server/handlers/xmlrpc/errata.py
+++ b/backend/server/handlers/xmlrpc/errata.py
@@ -35,6 +35,7 @@ class Errata(rhnHandler):
         self.functions.append('GetByPackage')      # Clients v1-
         self.functions.append('getPackageErratum') # Clients v2+
         self.functions.append('getErrataInfo')     # clients v2+
+        self.functions.append('getErrataNamesById')
         
     def GetByPackage(self, pkg, osRel):
         """ Clients v1- Get errata for a package given "n-v-r" format
@@ -242,7 +243,62 @@ class Errata(rhnHandler):
                             pkg_arch])
         return ret
 
+    def getErrataNamesById(self, system_id, errata_ids):
+        """Return a list of RhnErrata tuples of (id, advisory_name)
 
+        IN: system_id - id of the system requesting this info (must be
+            subscribed to the channel that contains the erratas)
+            errata_ids - a list of RhnErrata ids
+
+        Only the erratas that belong to channels that the client system
+        is subscribed to are returned. If no erratas match this
+        criterion, then an empty list is returned.
+
+        """
+        log_debug(5, system_id, errata_ids)
+        self.auth_system(system_id)
+
+        log_debug(1, self.server_id, errata_ids)
+
+        sql_list, bound_vars = _bind_list(errata_ids)
+        bound_vars.update({'server_id': self.server_id})
+
+        sql = """SELECT DISTINCT e.id, e.advisory_name
+                 FROM rhnErrata e,
+                      rhnPackage p,
+                      rhnChannelPackage cp, 
+                      rhnServerChannel sc,
+                      rhnErrataPackage ep
+                 WHERE e.id in (%s) AND
+                       ep.errata_id = e.id AND
+                       ep.package_id = p.id AND
+                       sc.server_id = :server_id AND
+                       sc.channel_id = cp.channel_id AND
+                       cp.package_id = p.id"""
+        h = rhnSQL.prepare(sql % sql_list)
+        h.execute(**bound_vars)
+        
+        return h.fetchall()
+
+
+def _bind_list(elems):
+    """Transform a list into an sql list with bound parameters
+
+    IN: elems - a list of elements
+
+    Returns a tuple of:
+     sql_list - a comma separated list of parameter numbers: 'p_0, p_1, p_2'
+     bound_vars - a dict of parameter names and values {'p_0': 42, 'p_1': 34}
+
+    """
+    bound_names = []
+    bound_vars = {}
+    for i, elem in enumerate(elems):
+        bound_vars['p_%s' % i] = elem
+        bound_names.append(':p_%s' % i)
+    sql_list = ', '.join(bound_names)
+    return sql_list, bound_vars
+            
 #-----------------------------------------------------------------------------
 if __name__ == "__main__":
     print "You can not run this module by itself"
-- 
1.7.4.4

_______________________________________________
Spacewalk-devel mailing list
Spacewalk-devel@redhat.com
https://www.redhat.com/mailman/listinfo/spacewalk-devel

Reply via email to