In our WSS 3.0 application, we have a document library that has an elevated folder called "Approved". It has different permissions from the rest of the Document Library in order to prevent people from normal access to it for uploads or editing. The only entities that have full access to that folder are an Administration group, including myself.
However, we do have a scenario where it is necessary to upload straight to it. I devised a simple ASPX page with a FileUpload
control, which then uses SPSecurity.RunWithElevatedPrivileges
(in itself inside of a SPLongOperation
) to attempt an upload to that folder. If I run it, the thing runs smoothly, the file is uploaded, everything is green. But whenever one of our engineers tries it, they get an "Access Denied" error for having insufficient privileges.
This is despite running the entire thing inside of the elevated privileges of the System Account, and an extra measure I took to remove the original uploading user entirely from the equation and pretend it was the System Account. I don't understand why this is failing, as for all intents and purposes the System Account is running everything and it has sufficient privilege to post in that library (and does so in a workflow that can be triggered by any user at a different stage in the process!)
Below is the code that I use inside of the SPSecurity.RunWithElevatedPrivileges
block. It's a very simple upload code, and yet it seems to be insufficient. Am I missing some security bits or anything? Am I going about it wrong?
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
bool oldAllow = web.AllowUnsafeUpdates;
try
{
SPList l = web.Lists[_targetList];
SPFile file;
int tID = int.Parse(hdIdent.Value);
SPListItem task = web.Lists["Tasks"].GetItemById(tID);
int targetID = int.Parse(hdRef.Value);
SPListItem target = web.Lists[_targetList].GetItemById(targetID);
web.AllowUnsafeUpdates = true;
//Grab file from the FileUpload control "upDrawing"
System.IO.Stream fStream;
byte[] contents = new byte[upDrawing.PostedFile.InputStream.Length];
fStream = upDrawing.PostedFile.InputStream;
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
//Original values are in comments, switched to the System Account
//in case this was the cause, but it still fails.
SPUser u1 = siteAdmin; //target.GetSPUser("Created By");
SPUser u2 = siteAdmin; //currentUser;
file = web.Files.Add(webUrl + "/" + _targetList + "/Approved/" + upDrawing.FileName, contents, u1, u2, (DateTime)target["Created"], DateTime.Now);
target = web.Lists[_targetList].GetItemById(targetID);
target["File Flag"] = 1;
target.NonfiringUpdate();
}
finally
{
web.AllowUnsafeUpdates = oldAllow;
}
}
}
GetSPUser
just extracts the SPUser from an SPUserValue that has a user, whileNonfiringUpdate
is just aSystem.Update(false)
inside of theDisableEventFiring
of an event receiver template. Everything else is just normal functions and ideally intuitive variable names.web.Update()
after changing the value ofweb.AllowUnsafeUpdates
(which is set totrue
before the upload, then set back tofalse
). I figured that it'd be safer to call the updates than to assume that changing the boolean alone was enough.