Custom search application is throwing Access Denied error while calling the “Execute” method of FullTextSQLQuery class. OOB Search works fine!!
Recently I had to work on a case where customer has created a custom search user control in which he is using the “FullTextSQLQuery” API to fetch the results against the Office Enterprise Search. User Control contains the search code using FullTextSQlQuery API and giving Access denied on one of the environments. The same code works fine and returns the search results on another environment.
The OOB search(on affected environment) works fine but getting the below error when trying the search from the custom code..:-
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at Microsoft.Office.Server.Search.Query.FullTextSqlQuery.Execute() ....at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state) at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.b__2()
The Search Account has been set as a app pool account and the custom search web part throws UnauthorizedAccessException while calling the execute method of FullTextSQLQuery API.
Tried elevating the privileges while executing the code and hence the app pool account is used to execute the code, but that too doesn’t help. OOB search also execute the same API but doesn't encounter this issue(with the search account as the app pool account). Changing the app pool account to the MOSS Content Access account makes the custom search web part works fine.
During the troubleshooting we found that customer is encountering this issue with only the “Search Service Account” as the app pool identity and if they changed the App pool identity to the System account of SSP then everything works fine. Irrespective of this App pool account changes, the OOB search is working fine.
Now comes the interesting stuff behind the working of Search and the accounts used……
The OOB search doesn't implements the elevated privileges because if used, the OOB Security Trimmer will not work as expected. If the search query is executed with the app pool account identity for any user who logs in, then the security trimmer will not work as expected and the results will be pulled always based on the app pool identity account. So applying elevated privileges to the execution of FullTextSQLQuery is not recommended. The search query should be executed with the current user's context only (just as its executed in the OOB search).
The custom search web part should be executed for any user who logs in irrespective of the app pool account.
Doesn’t sound like a permission issue with the search DB and SSP DB(not having enough permission) as even a visitor member can do an advance search in the OOB, even when he doesn’t have permission on the search and SSP DB. In the current scenario overloaded constructor of the FullTextSQLQuery was being used by passing the search context. Checked the behaviour of same web part by passing the current SPSite as the constructor parameter. And it works now!!
The root cause behind this was determined by comparing the OOB advance search core results web part and the customer's code. While constructing the FullTextSQLQuery in the OOB Advanced Search Core Results Web Part, the SPSite constructor parameter has been used. (When a SPSite is internally constructed it will be constructed based on the user token of the current context). The reason why the Search context (which is the SSP context) fails is not because of having the inappropriate rights on SSP DB or Search DB, it’s because we are trying to execute a safe control (customer's web part) in a particular site with a different context. It’s always recommended to execute any SharePoint API's in web context with the same site context so that the respective privileges (user token)can be taken into consideration for the execution of the control. So this issue is not because of the permission issue with the DB and the issue is because of executing the web part which has been registered as a safe control for a particular site and has been utilized with another context. This access denied is the security validation issue while executing the FullTextSQLQuery in a particular web context but still using the SSP context to construct the FullTextSQLQuery instance.
So changing the web part code in search control to use….
Current SPSite as the constructor parameter for FullTextSQLQuery instead of overloaded constructor of the FullTextSQLQuery by passing the Search Context.
FullTextSQLQuery query = new FullTextSQLQuery(SearchContext.Current)
Is changed to
FullTextSQLQuery query = new FullTextSQLQuery(SPContext.Current.Site)
And that was all that’s needed to get rid of the "Access Denied" exception.