Index: etc/jspwiki.properties.tmpl
===================================================================
--- etc/jspwiki.properties.tmpl	(revision 750163)
+++ etc/jspwiki.properties.tmpl	(working copy)
@@ -443,6 +443,13 @@
 jspwiki.loginModule.class = org.apache.wiki.auth.login.UserDatabaseLoginModule
 
 #
+# Not all LoginModules allow you to change login names or passwords.  Set these
+# options to false if you use a custom LoginModule which doesn't allow these
+# changes.
+#jspwiki.loginModule.canChangeLoginName = true
+#jspwiki.loginModule.canChangePassword = true
+
+#
 # JAAS LoginContext parameters used to initialize the LoginModule. Note that 'param1'
 #  etc. should be replaced with the actual parameter names. The parameter names and
 # values will be loaded to a Map and passed to the LoginModule as the 'options' parameter
Index: src/java/org/apache/wiki/auth/AuthenticationManager.java
===================================================================
--- src/java/org/apache/wiki/auth/AuthenticationManager.java	(revision 750163)
+++ src/java/org/apache/wiki/auth/AuthenticationManager.java	(working copy)
@@ -113,6 +113,10 @@
     /** The {@link javax.security.auth.spi.LoginModule} to use for custom authentication. */
     protected static final String                 PROP_LOGIN_MODULE = "jspwiki.loginModule.class";
     
+    /** Property specifying whether the LoginModule can change login names or passwords. */
+    protected static final String                 PROP_CHANGE_LOGIN = "jspwiki.loginModule.canChangeLoginName";
+    protected static final String                 PROP_CHANGE_PASSWORD = "jspwiki.loginModule.canChangePassword";
+    
     /** Empty Map passed to JAAS {@link #doJAASLogin(Class, CallbackHandler, Map)} method. */
     protected static final Map<String,String> EMPTY_MAP = Collections.unmodifiableMap( new HashMap<String,String>() );
     
@@ -123,6 +127,11 @@
      * initialized by {@link #initialize(WikiEngine, Properties)}. */
     protected Map<String,String> m_loginModuleOptions = new HashMap<String,String>();
 
+    /** Can this LoginModule change the username or password? 
+     * initialized by {@link #initialize(WikiEngine, Properties)}. */
+    protected boolean m_canChangeLoginName = true;
+    protected boolean m_canChangePassword = true;
+
     /** Just to provide compatibility with the old versions.  The same
      *  as SECURITY_OFF.
      *
@@ -156,6 +165,38 @@
     private TimedCounterList<String> m_lastLoginAttempts = new TimedCounterList<String>();
     
     /**
+     * Returns true if the current Authentication manager is capable of 
+     * changing the login name.  Defaults to true for most LoginModules
+     * except when using container based authentication.
+     *
+     * @return <code>true</code> if it is possible to change the password,
+     *         <code>false</code> otherwise.
+     */
+    public final boolean canChangeLoginName()
+    {
+        if ( isContainerAuthenticated() )
+            return false;
+        else
+            return m_canChangeLoginName;
+    }
+    
+    /**
+     * Returns true if the current Authentication manager is capable of 
+     * changing the password.  Defaults to true for most LoginModules
+     * except when using container based authentication.
+     *
+     * @return <code>true</code> if it is possible to change the password,
+     *         <code>false</code> otherwise.
+     */
+    public final boolean canChangePassword()
+    {
+        if ( isContainerAuthenticated() )
+            return false;
+        else
+            return m_canChangePassword;
+    }
+    
+    /**
      * Creates an AuthenticationManager instance for the given WikiEngine and
      * the specified set of properties. All initialization for the modules is
      * done here.
@@ -199,6 +240,13 @@
             throw new WikiException(e.getMessage());
         }
         
+        // Can this LoginModule change names or passwords?
+        m_canChangeLoginName = TextUtil.getBooleanProperty( props,
+                                                        PROP_CHANGE_LOGIN,
+                                                        true );
+        m_canChangePassword = TextUtil.getBooleanProperty( props,
+                                                        PROP_CHANGE_PASSWORD,
+                                                        true );
         // Initialize the LoginModule options
         initLoginModuleOptions( props );
     }
@@ -644,7 +692,7 @@
         {
             try
             {
-                return defaultFile.toURL();
+                return defaultFile.toURI().toURL();
             }
             catch ( MalformedURLException e)
             {
Index: src/java/org/apache/wiki/auth/UserManager.java
===================================================================
--- src/java/org/apache/wiki/auth/UserManager.java	(revision 750163)
+++ src/java/org/apache/wiki/auth/UserManager.java	(working copy)
@@ -446,8 +446,8 @@
         fullname = InputValidator.isBlank( fullname ) ? null : fullname;
         email = InputValidator.isBlank( email ) ? null : email;
 
-        // A special case if we have container authentication
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated() )
+        // A special case if we can't rename accounts
+        if ( !m_engine.getAuthenticationManager().canChangeLoginName() )
         {
             // If authenticated, login name is always taken from container
             if ( context.getWikiSession().isAuthenticated() )
@@ -502,8 +502,9 @@
             }
         }
         
-        // If container-managed auth and user not logged in, throw an error
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated()
+        // If we can't change or create loginnames and user not logged in,
+        // throw an error
+        if ( !m_engine.getAuthenticationManager().canChangeLoginName()
              && !context.getWikiSession().isAuthenticated() )
         {
             session.addMessage( SESSION_MESSAGES, rb.getString("security.error.createprofilebeforelogin") );
@@ -514,7 +515,7 @@
         validator.validate( profile.getEmail(), rb.getString("security.user.email"), InputValidator.EMAIL );
 
         // If new profile, passwords must match and can't be null
-        if ( !m_engine.getAuthenticationManager().isContainerAuthenticated() )
+        if ( m_engine.getAuthenticationManager().canChangePassword() )
         {
             String password = profile.getPassword();
             if ( password == null )
Index: src/java/org/apache/wiki/tags/UserProfileTag.java
===================================================================
--- src/java/org/apache/wiki/tags/UserProfileTag.java	(revision 750163)
+++ src/java/org/apache/wiki/tags/UserProfileTag.java	(working copy)
@@ -183,18 +183,30 @@
                 }
             }
         }
-        else if ( CHANGE_PASSWORD.equals( m_prop ) || CHANGE_LOGIN_NAME.equals( m_prop ) )
+        else if ( CHANGE_LOGIN_NAME.equals( m_prop ) || NOT_CHANGE_LOGIN_NAME.equals( m_prop ) )
         {
-            AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager();
-            if ( !authMgr.isContainerAuthenticated() )
+            boolean canChange = m_wikiContext.getEngine().getAuthenticationManager().canChangeLoginName();
+            
+            // Cheap and nasty trick to check for boolean NOT
+            if (  m_prop.charAt(0) == '!' )
+            {
+                canChange = !canChange;
+            }
+            if ( canChange )
             {
                 return EVAL_BODY_INCLUDE;
             }
         }
-        else if ( NOT_CHANGE_PASSWORD.equals( m_prop ) || NOT_CHANGE_LOGIN_NAME.equals( m_prop ) )
+        else if ( CHANGE_PASSWORD.equals( m_prop ) || NOT_CHANGE_PASSWORD.equals( m_prop ) )
         {
-            AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager();
-            if ( authMgr.isContainerAuthenticated() )
+            boolean canChange = m_wikiContext.getEngine().getAuthenticationManager().canChangePassword();
+            
+            // Cheap and nasty trick to check for boolean NOT
+            if (  m_prop.charAt(0) == '!' )
+            {
+                canChange = !canChange;
+            }
+            if ( canChange )
             {
                 return EVAL_BODY_INCLUDE;
             }
