Index: db/models/base.py
===================================================================
--- db/models/base.py	(revision 3077)
+++ db/models/base.py	(working copy)
@@ -157,7 +157,12 @@
         record_exists = True
         if pk_set:
             # Determine whether a record with the primary key already exists.
-            cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % \
+            check_sql = "SELECT 1 FROM %s WHERE %s=%%s"
+            if settings.DATABASE_ENGINE == "firebird":
+                check_sql = backend.add_limit_offset_sql(check_sql, 1)
+            else:
+                check_sql += backend.get_limit_offset_sql(1)
+            cursor.execute(check_sql % \
                 (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), [pk_val])
             # If it does already exist, do an UPDATE.
             if cursor.fetchone():
@@ -174,7 +179,7 @@
             db_values = [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)]
             # If the PK has been manually set, respect that.
             if pk_set:
-                field_names += [f.column for f in self._meta.fields if isinstance(f, AutoField)]
+                field_names += [backend.quote_name(f.column) for f in self._meta.fields if isinstance(f, AutoField)]
                 db_values += [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)]
             placeholders = ['%s'] * len(field_names)
             if self._meta.order_with_respect_to:
Index: db/models/fields/__init__.py
===================================================================
--- db/models/fields/__init__.py	(revision 3077)
+++ db/models/fields/__init__.py	(working copy)
@@ -475,7 +475,7 @@
         if value is not None:
             # MySQL will throw a warning if microseconds are given, because it
             # doesn't support microseconds.
-            if settings.DATABASE_ENGINE == 'mysql':
+            if settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'firebird':
                 value = value.replace(microsecond=0)
             value = str(value)
         return Field.get_db_prep_save(self, value)
@@ -484,7 +484,10 @@
         if lookup_type == 'range':
             value = [str(v) for v in value]
         else:
-            value = str(value)
+            # kinterbasdb accepts datetime objects
+            # but not datetime string with microseconds
+            if settings.DATABASE_ENGINE != 'firebird':
+                value = str(value)
         return Field.get_db_prep_lookup(self, lookup_type, value)
 
     def get_manipulator_field_objs(self):
@@ -739,7 +742,7 @@
         if value is not None:
             # MySQL will throw a warning if microseconds are given, because it
             # doesn't support microseconds.
-            if settings.DATABASE_ENGINE == 'mysql':
+            if settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'firebird':
                 value = value.replace(microsecond=0)
             value = str(value)
         return Field.get_db_prep_save(self, value)
Index: db/models/query.py
===================================================================
--- db/models/query.py	(revision 3077)
+++ db/models/query.py	(working copy)
@@ -2,6 +2,7 @@
 from django.db.models.fields import DateField, FieldDoesNotExist
 from django.db.models import signals
 from django.dispatch import dispatcher
+from django.conf import settings
 from django.utils.datastructures import SortedDict
 import operator
 import re
@@ -159,8 +160,11 @@
         extra_select = self._select.items()
 
         cursor = connection.cursor()
-        select, sql, params = self._get_sql_clause()
-        cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
+        select, criteria, params = self._get_sql_clause()
+        sql = "SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + criteria
+        if settings.DATABASE_ENGINE == "firebird" and self._limit is not None:
+            sql = backend.add_limit_offset_sql(sql, self._limit, self._offset)
+        cursor.execute(sql, params)
         fill_cache = self._select_related
         index_end = len(self.model._meta.fields)
         while 1:
@@ -418,14 +422,14 @@
 
         # Add any additional SELECTs.
         if self._select:
-            select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])
+            select.extend(['(%s) %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])
 
         # Start composing the body of the SQL statement.
         sql = [" FROM", backend.quote_name(opts.db_table)]
 
         # Compose the join dictionary into SQL describing the joins.
         if joins:
-            sql.append(" ".join(["%s %s AS %s ON %s" % (join_type, table, alias, condition)
+            sql.append(" ".join(["%s %s %s ON %s" % (join_type, table, alias, condition)
                             for (alias, (table, join_type, condition)) in joins.items()]))
 
         # Compose the tables clause into SQL.
@@ -468,7 +472,8 @@
 
         # LIMIT and OFFSET clauses
         if self._limit is not None:
-            sql.append("%s " % backend.get_limit_offset_sql(self._limit, self._offset))
+            if settings.DATABASE_ENGINE != "firebird":
+                sql.append("%s " % backend.get_limit_offset_sql(self._limit, self._offset))
         else:
             assert self._offset is None, "'offset' is not allowed without 'limit'"
 
Index: core/management.py
===================================================================
--- core/management.py	(revision 3077)
+++ core/management.py	(working copy)
@@ -6,6 +6,7 @@
 import os, re, shutil, sys, textwrap
 from optparse import OptionParser
 from django.utils import termcolors
+from django.conf import settings
 
 # For Python 2.3
 if not hasattr(__builtins__, 'set'):
@@ -110,6 +111,9 @@
         final_output.extend(_get_sql_for_pending_references(klass, pending_references))
         # Keep track of the fact that we've created the table for this model.
         models_output.add(klass)
+        
+        if (settings.DATABASE_ENGINE == 'firebird') & (klass._meta.has_auto_field):
+            final_output.extend(get_creation_module().create_sequence_sql(klass._meta.db_table, klass._meta.pk.column))
 
     # Create the many-to-many join tables.
     for klass in app_models:
@@ -153,7 +157,7 @@
             # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
             field_output = [style.SQL_FIELD(backend.quote_name(f.column)),
                 style.SQL_COLTYPE(col_type % rel_field.__dict__)]
-            field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
+            field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or 'DEFAULT ')))
             if f.unique:
                 field_output.append(style.SQL_KEYWORD('UNIQUE'))
             if f.primary_key:
@@ -204,7 +208,7 @@
                 col = opts.get_field(f.rel.field_name).column
                 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
                     (backend.quote_name(r_table),
-                    backend.quote_name('%s_referencing_%s_%s' % (r_col, table, col)),
+                    backend.quote_name('%s__%s' % (r_col, col)),
                     backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col)))
             del pending_references[klass]
     return final_output
@@ -240,6 +244,8 @@
             style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name()))))
         table_output.append(');')
         final_output.append('\n'.join(table_output))
+        if (settings.DATABASE_ENGINE == 'firebird'):
+            final_output.extend(get_creation_module().create_sequence_sql(f.m2m_db_table(), "id"))
     return final_output
 
 def get_sql_delete(app):
@@ -291,7 +297,7 @@
                         (style.SQL_KEYWORD('ALTER TABLE'),
                         style.SQL_TABLE(backend.quote_name(table)),
                         style.SQL_KEYWORD(backend.get_drop_foreignkey_sql()),
-                        style.SQL_FIELD(backend.quote_name("%s_referencing_%s_%s" % (col, r_table, r_col)))))
+                        style.SQL_FIELD(backend.quote_name("%s__%s" % (col, r_col)))))
                 del references_to_delete[klass]
 
     # Output DROP TABLE statements for many-to-many tables.
@@ -1026,7 +1032,7 @@
     index_output = []
     for f in fields:
         field_output = [backend.quote_name(f.name), data_types[f.get_internal_type()] % f.__dict__]
-        field_output.append("%sNULL" % (not f.null and "NOT " or ""))
+        field_output.append("%sNULL" % (not f.null and "NOT " or "DEFAULT "))
         if f.unique:
             field_output.append("UNIQUE")
         if f.primary_key:
Index: contrib/auth/models.py
===================================================================
--- contrib/auth/models.py	(revision 3077)
+++ contrib/auth/models.py	(working copy)
@@ -64,7 +64,7 @@
     date_joined = models.DateTimeField(_('date joined'), default=models.LazyDate())
     groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,
         help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
-    user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)
+    permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)
     objects = UserManager()
     class Meta:
         verbose_name = _('user')
@@ -74,7 +74,7 @@
         fields = (
             (None, {'fields': ('username', 'password')}),
             (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
-            (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
+            (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'permissions')}),
             (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
             (_('Groups'), {'fields': ('groups',)}),
         )
@@ -160,7 +160,7 @@
     def get_all_permissions(self):
         if not hasattr(self, '_perm_cache'):
             import sets
-            self._perm_cache = sets.Set(["%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.all()])
+            self._perm_cache = sets.Set(["%s.%s" % (p.content_type.app_label, p.codename) for p in self.permissions.all()])
             self._perm_cache.update(self.get_group_permissions())
         return self._perm_cache
 
@@ -249,7 +249,7 @@
 
     def _get_user_permissions(self):
         raise NotImplementedError
-    user_permissions = property(_get_user_permissions)
+    permissions = property(_get_user_permissions)
 
     def has_perm(self, perm):
         return False
