In one of my customer's MOSS implementations we're using SharePoint's resident permission management to control who has access to what InfoPath forms. The issue we came across is that if a user has read-only access to a form and opens it, they can see the Update button. Clicking it does error and denies the change, and after the error the user gets the typical form closed message.

We wanted to hide the button from the view of a user who has read-only permissions to deny the error all together and minimize user complaints.

Using the code behind in the InfoPath form, we can check the current user against the current item then set a field in InfoPath to flag whether or not the user is read-only or not. From there, we can base the conditional formatting of buttons, text boxes, etc. on this value.

try
{
 if (e.InputParameters.ContainsKey("XmlLocation") && !SPContext.Current.Web.CurrentUser.IsSiteAdmin)  //Regardless of resident permissions, give SiteAdmins access
 {
  SPUser curUser = SPContext.Current.Web.CurrentUser;
  string path = e.InputParameters["XmlLocation"].ToString(); //get the location of the XML file and parse
  string lib = path.Substring(0, path.LastIndexOf("/"));
  string formName = path.Substring(path.LastIndexOf("/") + 1);
  using (SPSite site = new SPSite(SPContext.Current.Site.ID))
  {
   SPWeb web = site.OpenWeb(SPContext.Current.Web.ID); //grab the current web
   SPListItem li = web.GetListItem(path.Replace(web.Url, "")); //grab the current list item using the

   if (li.DoesUserHavePermissions(SPBasePermissions.EditListItems)) //check for permissions
    SetNodeValue("/my:mySAR/my:IsReadOnly", "0"); //if it exists, set field to false
   else
    SetNodeValue("/my:mySAR/my:IsReadOnly", "1"); //if it doesn't, set it to true
  }

 }
 else
  SetNodeValue("/my:mySAR/my:IsReadOnly", "0"); //if the XmlLocation doesn't exist, it's a new form so it's not Read Only
}
catch (Exception ex)
{
 WriteErrorToLog("FormEvents_Loading", "Problem setting user permissions", ex);
 SetNodeValue("/my:mySAR/my:IsReadOnly", "1"); //on error stop the user from writing
}

From here I based the buttons' conditional formatting on the field IsReadOnly.