Should the Controller make direct assignments on the Model objects, or just tell the Model what needs to be done?
It's fine for it to make "direct assignments" on the model, as long as it does so through an interface.
The controller has two traditional roles:
handling the input event from the UI (registered handler or callback)
notifying the model of an action--which may or may not result in a change on the model's state
It does not perform data validation, that is on the model, nor does it have any say in how information is presented.
The Model services don't have to know the existence of the controller, thus, controller can do the stuff what ever the view needs by utilising the model services.
It depends largely on the scope of your application. If it's relatively quick and dirty, then there's no sense in over-engineering, and sure, your controllers can talk to your model objects. On the other hand, if it needs to be more "enterprisey" for whatever reason, a good pattern to use in conjunction with MVC is the so-called "Business Delegate". This is where you can compose coarse-grained methods out of one or more methods on one or more model objects; for instance deleting an object and then returning a refreshed list without that object. This layer gives two advantages. For one, it decouples the controllers from whatever ORM system is being used for model objects. Furthermore, it is the layer that finally must constructively deal with any exceptions that may have occurred instead of re-throwing them.
I don't think a controller should be dealing with model objects.
I tend to think that controller is really part of the UI tier. I prefer to inject a service layer in-between the controller and the rest of the app. The web tier accepts HTTP requests, unmarshals parameters from request objects into objects that the service interface can deal with, and marshals the response to send back. All the work with transactions, units of work, and dealing with model and persistence objects is done by the service.
This approach is more service oriented. It separates the service from the user interface, leaving open the possibility that several clients can reuse the same service. It makes the layer that marshals requests to the service "thin", so it's easy to switch out SOAP services for REST or EJB or CORBA or whatever the next new thing will be.