Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Security / September 2007

Tip: Looking for answers? Try searching our database.

Why got error "Only one type of operation can be performed in a se

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Pucca - 13 Sep 2007 17:26 GMT
Hi, I'm using vs2005, .net 2 for a C# windows applicaiton running on Win2K
server.  One method of this application, deletes, creates and modify several
Directory Entry.  This is running fine on my development PC.  I put this on
another server and I would get error: "Only one type of operation can be
performed in a sequence"

Does anyone what could possiblly be causing this error?  Thank you.
Signature

Thanks.

Joe Kaplan - 13 Sep 2007 17:34 GMT
You need to provide more detail here.  Can you show an example of the code
that produces the error, the exact error stack trace and more information
about the differences between your development machine OS and the deployment
server?

It could be that you have run into an ADSI limitation on Win2K server where
multiple different types of attribute modifications are not allowed, but it
isn't clear if that is the problem.  If that is, you need to either write
your code differently or upgrade the server OS to a version of Windows that
supports that ADSI feature (2K3 server).

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Hi, I'm using vs2005, .net 2 for a C# windows applicaiton running on Win2K
> server.  One method of this application, deletes, creates and modify
[quoted text clipped - 5 lines]
>
> Does anyone what could possiblly be causing this error?  Thank you.
Pucca - 13 Sep 2007 18:40 GMT
Hi Joe, Both my development PC and the Virtual Machine are running Win2K
Server.  The error occur on the VM server when the code runs through this 2
methods.  What's confusing for me is that it works for my PC but getting
error on our VM test machine.  Thank you.

       private bool StartCommit()
       {
           DataRow[] newRows;
           string path, sid, strUnifiedID, ID, globalPath;
           DirectoryEntry de = new DirectoryEntry();
           SearchResult sr;
           int unifiedID = 0, ugid;
           bool useUnifiedID = false, success = false, available = false;
           DirectoryEntry deUGID = new DirectoryEntry();

           if (importUsers)
           {
               globalPath = CUnityDS.globalUsersPath +
dtGlobal.Rows[0]["curDomain"].ToString();
               ID = "UID";
               path =
"LDAP://CN=NextUnifiedID,CN=Users,CN=Global,CN=PowerADvantage,CN=Symark,CN=Program Data," + dtGlobal.Rows[0]["curDomain"].ToString();
           }
           else
           {
               globalPath = CUnityDS.globalGroupsPath +
dtGlobal.Rows[0]["curDomain"].ToString();
               ID = "GID";
               path =
"LDAP://CN=NextUnifiedID,CN=Groups,CN=Global,CN=PowerADvantage,CN=Symark,CN=Program Data," + dtGlobal.Rows[0]["curDomain"].ToString();
           }

           DirectoryEntry deSearchRoot = new DirectoryEntry(globalPath);
           DirectorySearcher dsGlobal = new DirectorySearcher(deSearchRoot);
           dsGlobal.PropertiesToLoad.Add("meetingID");
           dsGlobal.SearchScope = SearchScope.OneLevel;

           try
           {
               //Let's get all the rows that have been updated
               if(importUsers)
                   newRows = tblTarget.Select("Mapped = true", "objectSid",
DataViewRowState.CurrentRows);
               else
                   newRows = tblTargetGroup.Select("Mapped = true",
"objectSid", DataViewRowState.CurrentRows);

               if (newRows.Length <= 0)
               {
                   return false;
               }

               //Proecess each row found to import
               for (int index = 0; index < newRows.Length; index++)
               {
                   ugid = Convert.ToInt32(newRows[index][ID].ToString());
                   //Check if a Global object already exists for this row
and get the Unified ID
                   sid = newRows[index]["objectSid"].ToString();
                   dsGlobal.Filter = "cn = " + sid;
                   sr = dsGlobal.FindOne();
                   if (sr != null)//Global object already exists
                   {
                       de = sr.GetDirectoryEntry();
                       strUnifiedID =
de.Properties["meetingID"].Value.ToString();
                       available = CUnityDS.UnifiedIdAvailable(globalPath,
strUnifiedID);
                       if (!available)
                       {
                           strUnifiedID = CUnityDS.GetNextUnifiedID(path,
strUnifiedID);
                       }
                       if (strUnifiedID == null)
                       {
                           MessageBox.Show("Error obtaining a unified id.",
"PowerADvantage");
                           return false;
                       }
                       unifiedID = Convert.ToInt32(strUnifiedID);

                       if (unifiedID == ugid)
                           useUnifiedID = true;
                       else
                           useUnifiedID = false;
                       Commit(newRows[index], useUnifiedID, globalPath,
sid, ugid, true, unifiedID);
                   }
                   else//no Global object so use the ugid as the unified ID
but if it is
                   //already used as a unified id by another object then
use the next
                   //available unified id
                   {
                       de = null;
                       //No object found Global folder, use the ugid but
check it's not used already
                       available = CUnityDS.UnifiedIdAvailable(globalPath,
ugid.ToString());

                       if (available)//OK to use the ugid
                       {
                           unifiedID = ugid;
                           useUnifiedID = true;
                       }
                       else//ugid is already used as unified id by other
object.  Use the next avaible unified id
                       {
                           try
                           {
                               deUGID.Path = path;
                               //string test =
deUGID.Properties["cn"].Value.ToString();
                           }
                           catch (COMException cep)
                           {
                               MessageBox.Show(cep.Message + " Error Code:
" + cep.ErrorCode.ToString(), "PowerADvantage");
                               return false;
                           }
                           if (deUGID == null ||
deUGID.Properties["meetingID"].Value == System.DBNull.Value)
                           {
                               MessageBox.Show("Not able to retrieve the
next available unified ID.  Please " +
                                "exit and call for support.",
"PowerADvantage");
                               return false;
                           }
                           //Verify if the id obtain is not in used.  If
already in used then increment and
                           //test until it is avaiable.  Set the next avail
id back to the folder
                           strUnifiedID =
deUGID.Properties["meetingID"].Value.ToString();
                           strUnifiedID =
CUnityDS.GetNextUnifiedID(globalPath, strUnifiedID);
                           if (strUnifiedID == null)
                           {
                               MessageBox.Show("Error obtaining a unified
id.", "PowerADvantage");
                               return false;
                           }
                           unifiedID = Convert.ToInt32(strUnifiedID);//use
this avialbe ID
                           if (unifiedID == ugid)
                               useUnifiedID = true;
                           
                           //inc to set next available Unified ID
                           deUGID.Properties["meetingID"].Clear();
                           int newUid = unifiedID + 1;
                           string strNewUID = newUid.ToString();
                           deUGID.Properties["meetingID"].Add(strNewUID);
                           deUGID.CommitChanges();
                       }

                       success = Commit(newRows[index], useUnifiedID,
globalPath, sid, ugid, true, unifiedID);
                       if (!success)
                           continue;
                       newRows[index]["Imported"] = true;
                       newRows[index]["Mapped"] = System.DBNull.Value; //to
indicate no changes since commit
                       if (!importUsers)
                       {
                           if (numOfGroupMapped > 0)
                               numOfGroupMapped--;
                           newRows[index]["MemberShip"] = true;
                       }
                       else
                       {
                           if(numOfUserMapped > 0)
                               numOfUserMapped--;
                       }
                   }
               }
           }//end try
           catch (Exception ex)
           {
               MessageBox.Show(ex.Message, "PowerADvantage");
           }
           finally
           {
               //clean up
               if (dsGlobal != null)
                   dsGlobal.Dispose();
               if (deSearchRoot != null)
                   deSearchRoot.Dispose();
               if (deUGID != null)
                   deUGID.Dispose();
               if (success)
                   this.btnCommit.Enabled = false;
           }
           dgvTarget.Refresh();
           return true;
       }

       private bool Commit(DataRow dr, bool flag, string globalPath, string
sid,
           int ugid, bool createGlob, int unifiedID)
       {
           DirectoryEntry deParent = new DirectoryEntry(),
deAdUserFolder=null, dePrimaryGroup=new DirectoryEntry();
           DirectoryEntry deNewContextObject = new DirectoryEntry(),
deAdObjectImportTo = new DirectoryEntry(),
               deNewGloblObject = new DirectoryEntry();
           string parentPath, strGid, pGroupSid = "", userName = "",
               globalFolderPath = CUnityDS.globalGroupsPath
+dtGlobal.Rows[0]["curDomain"],
               adUserGroupFolderPath = "LDAP://CN=USERS, " +
dtGlobal.Rows[0]["curDomain"],
               path;
           bool result = true, alreadyMember = false;

           // create an instance of the Blob structure
           CUnityDS.Blob blob = new CUnityDS.Blob();

           try
           {
               deAdUserFolder = new
DirectoryEntry(dtGlobal.Rows[0]["ADPath"].ToString());                
               deAdObjectImportTo = CUnityDS.GetAdDE(sid, deAdUserFolder);

               //Check to see if there is already a context object with
this sid
               path =
"LDAP://CN=Contexts,CN=PowerADvantage,CN=Symark,CN=Program Data," + curDomain;
               DirectoryEntry deSrchRoot = new DirectoryEntry(path);
               deNewContextObject =
CUnityDS.GetContextEntry(deAdObjectImportTo, deSrchRoot);
               if (deNewContextObject != null)
                   deNewContextObject.DeleteTree();
               //Check to see if there is already a global object with this
sid
               deSrchRoot.Path = globalFolderPath;
               deNewContextObject =
CUnityDS.GetContextEntry(deAdObjectImportTo, deSrchRoot);
               if (deNewContextObject != null)
                   deNewContextObject.DeleteTree();

               //Start by creating the new user or group in the Context
directory
               string cn = "cn=" + sid;
               deParent.Path = contextPath;
               deNewContextObject = deParent.Children.Add(cn, "meeting");
               deParent.CommitChanges();

               string UnixName = dr["Account"].ToString();
               string strID = ugid.ToString();
               
deNewContextObject.Properties["meetingName"].Add((object)(UnixName));//unix
account
               
deNewContextObject.Properties["meetingID"].Add((object)(strID));//u/g id
               
deNewContextObject.Properties["meetingMaxParticipants"].Add((object)("1"));
//enabled
               deNewContextObject.CommitChanges();

               #region Get PrimaryGroup
               //Get the user's primary Group sid
               if (importUsers)
               {
                   pGroupSid = dr["pGroupSid"].ToString();
                   if(pGroupSid == "" || pGroupSid == null)
                   {
                       MessageBox.Show("Primary group is not found in
Active Directory.  " +
                           
deAdObjectImportTo.Properties["displayName"].Value.ToString() +
                           " cannot be imported.");
                       return false;
                   }
                   //We need to get the AD de of the primary group.  We
have to add the AD user of
                   //the row that we're adding to context a member of this
group in AD
                   dePrimaryGroup = CUnityDS.GetAdDE(pGroupSid,
deAdUserFolder);
                   if (dePrimaryGroup == null)
                   {
                       MessageBox.Show("Primary group is not found in
Active Directory.  " +
                           
deAdObjectImportTo.Properties["displayName"].Value.ToString() +
                           " cannot be imported.");
                       result = false;

                   }
                   else  //Got the primary group de
                   {
                       string primaryGroupName = "CN=" +
                           dePrimaryGroup.Properties["cn"].Value.ToString()
+ ",";
                       //If the user to import is not a member of the
primary group then make it so
                       //Get rid of the ladp:// before append then verify
membership

                       alreadyMember =
CUnityDS.IsMemberAlready(primaryGroupName, deAdObjectImportTo);

                       path = deAdObjectImportTo.Path.Substring(7,
deAdObjectImportTo.Path.Length - 7);
                       if (!alreadyMember)
                       {
                           dePrimaryGroup.Properties["member"].Add(path);
                           dePrimaryGroup.CommitChanges();
                       }
                     
                       if (pGroupSid == null)
                       {
                           MessageBox.Show("Error importing " + userName +
                               ": Primary group GID can not be null or
blank.  Please correct and try again.", "PowerADvantage");
                           return false;
                       }
                       #endregion Get PrimaryGroup

                       CUnityDS.CUserContextData userContextData = new
CUnityDS.CUserContextData();
                       //if Windows Logon Name = Unix Account name then set
flag to use windlogon
                       if
(deAdObjectImportTo.Properties["sAMAccountName"].Value.ToString() == UnixName)
                           userContextData.bWinLogOn = 1;
                       else
                           userContextData.bWinLogOn = 0;
                       if (flag)//Use Unified ID?
                           userContextData.bUnifiedID = 1;
                       else
                           userContextData.bUnifiedID = 0;

                       userContextData.IID = ugid;
                       userContextData.Revision = 0;

                       userContextData.homeDir = dr["Directory"].ToString();
                       userContextData.shell = dr["Shell"].ToString();
                       userContextData.primaryGroupSID = pGroupSid;

                         // // allocate memry for the blob
                       IntPtr pBlob =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CUnityDS.Blob)));
                       // call the function passing the pointer to the blob
byref
                       CUnityDS.LibWrap.EncodeAsnUser(ref pBlob,
userContextData);
                       // copy the unmanaged blob to managed struct Blob
                       blob = (CUnityDS.Blob)Marshal.PtrToStructure(pBlob,
typeof(CUnityDS.Blob));
                         // allocate byte array with size of blob.nLength
                       byte[] meetingBlob = new byte[blob.nLength];
                          // marshal the data pointed to by pData into the
byte array
                       
System.Runtime.InteropServices.Marshal.Copy(blob.pData, meetingBlob, 0,
                           blob.nLength);
                       //add the blob
                       
deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

                       deNewContextObject.CommitChanges();
                       result = true;
                       numOfUserMapped++;
                   }
               }//end importing a user
               else //importing a group
               {
                   CUnityDS.CGroupContextData groupContextData = new
CUnityDS.CGroupContextData();
                   //if Windows Logon Name = Unix Account name then set
flag to use windlogon
                   if
(deAdObjectImportTo.Properties["sAMAccountName"].Value.ToString() == UnixName)
                       groupContextData.bWinGroupName = 1;
                   else
                       groupContextData.bWinGroupName = 0;
                   if (flag)//Use Unified ID?
                       groupContextData.bUnifiedID = 1;
                   else
                       groupContextData.bUnifiedID = 0;

                   groupContextData.IID = ugid;
                   groupContextData.Revision = 0;

                   // // allocate memry for the blob
                   IntPtr pBlob =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CUnityDS.Blob)));
                   // call the function passing the pointer to the blob byref
                   CUnityDS.LibWrap.EncodeAsnGroup(ref pBlob,
groupContextData);
                   // copy the unmanaged blob to managed struct Blob
                   blob = (CUnityDS.Blob)Marshal.PtrToStructure(pBlob,
typeof(CUnityDS.Blob));
                   // allocate byte array with size of blob.nLength
                   byte[] meetingBlob = new byte[blob.nLength];
                   // marshal the data pointed to by pData into the byte
array
                   System.Runtime.InteropServices.Marshal.Copy(blob.pData,
meetingBlob, 0,
                       blob.nLength);

                   //add the blob
                   
deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);
                   deNewContextObject.CommitChanges();
                   result = true;
                   numOfGroupMapped++;      

               }
               
               //if the context object was created successfully then create
the Global object otherwise exit
               if (result == true)
               {
                   //Now create the Global user or group object
                   deParent.Path = globalFolderPath;                    
                   deNewGloblObject = deParent.Children.Add(cn, "meeting");
                   deParent.CommitChanges();
                   if (deNewGloblObject != null)
                   {
                       
deNewGloblObject.Properties["meetingName"].Add(dr["Login Name"].ToString());
                       
deNewGloblObject.Properties["meetingID"].Add(unifiedID);
                       deNewGloblObject.CommitChanges();
                       result = true;
                   }
                   else//Global object fail to create, return null then
remove the matching context object
                   {
                       if (deNewContextObject == null)
                       {
                           deParent.Path = contextPath;
                           deParent.Children.Remove(deNewContextObject);
                           deParent.CommitChanges();
                       }
                       result = false;
                   }
               }
           }
           catch (Exception ex)
           {
               if (ex.Message.Contains("already exist"))
               {
                   result = true;
               }
               else//Global object fail to create so delete the matching
context object
               {
                   MessageBox.Show(ex.Message, "PowerADvantage");
                   deParent.Path = contextPath;
                   deParent.Children.Remove(deNewContextObject);
                   deParent.CommitChanges();
                   result = false;
               }
           }
           finally
           {
               //clean up
               if (deParent != null)
                   deParent.Dispose();
               if (deNewContextObject != null)
                   deNewContextObject.Dispose();
               if (deAdUserFolder != null)
                   deAdUserFolder.Dispose();
               if (dePrimaryGroup != null)
                   dePrimaryGroup.Dispose();
               if (deAdObjectImportTo != null)
                   deAdObjectImportTo.Dispose();
           }

           return result;
       }

Signature

Thanks.

> You need to provide more detail here.  Can you show an example of the code
> that produces the error, the exact error stack trace and more information
[quoted text clipped - 18 lines]
> >
> > Does anyone what could possiblly be causing this error?  Thank you.
Pucca - 13 Sep 2007 22:42 GMT
Since there is no VS for me to debug on the VM server I put in a bunch of
messages to see where I'm getting this error.  It's apparently coming from my
StartCommit() method in the following code when deUGID is doing the "Add"
method.  Can you see what could possible cuase this?  Again, the same is
running just fine on my development PC.

int newUid = unifiedID + 1;
string strNewUID = newUid.ToString();
deUGID.Properties["meetingID"].Clear();
deUGID.Properties["meetingID"].Add(strNewUID);//This is the line of code
giving error
deUGID.CommitChanges();

Signature

Thanks.

> You need to provide more detail here.  Can you show an example of the code
> that produces the error, the exact error stack trace and more information
[quoted text clipped - 18 lines]
> >
> > Does anyone what could possiblly be causing this error?  Thank you.
Joe Kaplan - 13 Sep 2007 22:49 GMT
Yeah, that looks like a multiple attribute modification type of problem.  Do
you have the full stack trace of the error message?  That would be helpful.

Is there any service pack difference between the two machines?

BTW, if you just want to overwrite an attribute value, it is much more
straightforward just to do:

entry.Properties["xxxx].Value = xxxx;

That will probably make the problem go away, even if you don't ever learn
the exact underlying cause.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Since there is no VS for me to debug on the VM server I put in a bunch of
> messages to see where I'm getting this error.  It's apparently coming from
[quoted text clipped - 40 lines]
>> >
>> > Does anyone what could possiblly be causing this error?  Thank you.
Pucca - 14 Sep 2007 22:34 GMT
Yes, that did fix the problem.  Because this problem only ocurring at the
Virutal Machine that doesn't have the VS installed so I dont' have any stack
information.  However, the VM Win2k server has the same SP as my development
PC.  But why would the same code ran OK on my server but  not on the VM
server?  Thank you.
Signature

Thanks.

> Yeah, that looks like a multiple attribute modification type of problem.  Do
> you have the full stack trace of the error message?  That would be helpful.
[quoted text clipped - 55 lines]
> >> >
> >> > Does anyone what could possiblly be causing this error?  Thank you.
Pucca - 14 Sep 2007 22:40 GMT
Also, I was getting the error becuase I was committing with both "Clear" and
"Add" method done?  AD would only allow commit of one Operation at a time?  
Thank you.
Signature

Thanks.

> Yeah, that looks like a multiple attribute modification type of problem.  Do
> you have the full stack trace of the error message?  That would be helpful.
[quoted text clipped - 55 lines]
> >> >
> >> > Does anyone what could possiblly be causing this error?  Thank you.
Joe Kaplan - 15 Sep 2007 01:30 GMT
Yes, the issue is that you with older versions of ADSI, you can't mix
different property modification operations.  For example, in ADSI there is
an add, remove, replace and clear operation.  If you do an operation on the
DirectoryEntry property cache that cause more than one of those to be done
before you commit changes, it will fail.

Newer versions of ADSI allow the multiple modifications.  You normally get
different versions of ADSI with different versions of Windows (including
service packs), so that's why this issue tends to vary by OS.  There have
been a variety of changes to the underlying implementation between .NET 1.0,
1.1, 1.1 SP1 and .NET 2.0, so if you have different .NET versions, that
could also be at issue.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Also, I was getting the error becuase I was committing with both "Clear"
> and
[quoted text clipped - 71 lines]
>> >> >
>> >> > Does anyone what could possiblly be causing this error?  Thank you.
Pucca - 15 Sep 2007 01:40 GMT
Thank you Joe.  So, there is probablly some differences between my
development PC and the VM pc.  Even though I can confirm that both are win2k
server with sp4 and .net 2.0.  It's strange that it would work on my PC but
not the vm.  However, the fix per your suggestion did fix the problem.  Thank
you very much.
Signature

Thanks.

> Yes, the issue is that you with older versions of ADSI, you can't mix
> different property modification operations.  For example, in ADSI there is
[quoted text clipped - 86 lines]
> >> >> >
> >> >> > Does anyone what could possiblly be causing this error?  Thank you.
Joe Kaplan - 15 Sep 2007 03:11 GMT
You might check the versions of your ADSI DLLs and see if there is any
difference.  Otherwise, I really don't know why you'd see a behavior
difference at all.  At least you have a workaround. :)

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Thank you Joe.  So, there is probablly some differences between my
> development PC and the VM pc.  Even though I can confirm that both are
[quoted text clipped - 4 lines]
> Thank
> you very much.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.