Runtime COMException when adding directory objects

G

Guest

Hi
I have written a code-behind page with exact lines of code and it works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called by the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e) +545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1281
 
J

Joe Kaplan \(MVP - ADSI\)

Are you sure you aren't accidentally trying to add the same account twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of these
conditions before attempting to commit.

Joe K.
 
G

Guest

Yes, I am sure. The only difference is running by the code-behind page along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

Joe Kaplan (MVP - ADSI) said:
Are you sure you aren't accidentally trying to add the same account twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of these
conditions before attempting to commit.

Joe K.

Hi
I have written a code-behind page with exact lines of code and it works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called by the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e) +545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1281


--------------------------------------------------------------------------
 
J

Joe Kaplan \(MVP - ADSI\)

Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

Joe Kaplan (MVP - ADSI) said:
Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of these
conditions before attempting to commit.

Joe K.

Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called by the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e) +545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1281


--------------------------------------------------------------------------
 
G

Guest

Hi Joe
System.Security.Principal.WindowsIdentity.GetCurrent().Name => both return
the custom "least privilege" a/c for the worker process

Here comes the code, a bit lengthy! it go thru the code-behind one and a/c
will be created, but for the called method one it throw exception at the
first commitChanges().
TIA

this is the code-behind file by itself
void btnEntryCreate_Click(Object sender, EventArgs e)
{
Trace.Write("button clicked");
String domain, dirPath, fullName, cnName, sAMName;
String uName, uPwd;
//code to create OU
if (IsValid) {
fullName = txtFName.Text + " " + txtMI.Text + " " +
txtLName.Text;
cnName = "cn=" + fullName;
//Regex strReg = new Regex(" ");
sAMName = txtFName.Text + txtLName.Text;
//ouName = "ou=" + DropDownList1.SelectedItem.Text;
domain = (string)Session["domain"];
dirPath = "LDAP://ou=" + DropDownList1.SelectedItem.Text + "," +
domain;
try
{
//DirectoryEntry myDir = new DirectoryEntry(dirPath, uName,
uPwd);
Trace.Write(dirPath);
Trace.Write(cnName);
Trace.Write(sAMName);
//DirEntry entry = new
DirEntry(DropDownList1.SelectedItem.Text, domain);
//entry.entryAdd(txtFName.Text, txtLName.Text, txtMI.Text,
txtTeleNum.Text, 0);
//can throw own exception message on error

DirectoryEntry myDir = new DirectoryEntry(dirPath);
DirectoryEntry newUser = myDir.Children.Add(cnName, "user");
DirEntry entry = new DirEntry(dirPath);
if (entry.chkCN(cnName) == 0)
{
//Trace.Write("setting properties - sAMName");
sAMName = entry.getsAMAcName(txtFName.Text,
txtLName.Text, txtMI.Text);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
newUser.Properties["givenName"].Add(txtFName.Text);
if (txtMI.Text != "")
newUser.Properties["initials"].Add(txtMI.Text);
newUser.Properties["sn"].Add(txtLName.Text);

newUser.Properties["telephoneNumber"].Add(txtTeleNum.Text);
Trace.Write("about to commit");
newUser.CommitChanges();
////Set user additional properties
newUser.Invoke("SetPassword", new object[] { "test" });

////If this user is the admin of this OU
////0x40 Can't Change pwd (this is not working
somehow!)
////0x200 Normal account ie. not disabled
////0x10000 pwd never expires
newUser.Properties["userAccountControl"].Value =
0x10042;
newUser.CommitChanges();
myDir.Dispose();
Response.Write("User " + cnName + " is created");



this is the called method
public int entryAdd(String fname, String lname, String mi, String
telno, int flag)
{
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath, "admin",
"abc123");
try
{
//DirectoryEntry entry = new DirectoryEntry(_path);
//_domain = entry.Parent.Path;
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
_msg = "setting sAMName: " + sAMName;
newUser.Properties["sAMAccountName"].Add(sAMName);
_msg =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
newUser.CommitChanges();

//Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
_msg = "committed once";
newUser.Properties["givenName"].Add(fname);
if (mi != "")
newUser.Properties["initials"].Add(mi);
newUser.Properties["sn"].Add(lname);
newUser.Properties["telephoneNumber"].Add(telno);
//Trace.Write("about to commit");
newUser.CommitChanges();
_msg = "committed twice";
//Set user additional properties
//If this user is the admin of this OU
//0x40 Can't Change pwd (this is not working somehow!)
//0x200 Normal account ie. not disabled
//0x10000 pwd never expires
newUser.Invoke("SetPassword", new object[] { _ouName });
if (flag == 0)
{
newUser.Properties["userAccountControl"].Value =
0x10040;
}


Joe Kaplan (MVP - ADSI) said:
Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

in message news:[email protected]...
Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of these
conditions before attempting to commit.

Joe K.

<dl> wrote in message Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called by the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e) +545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1281
------------------------------------------------------------------------- -
 
J

Joe Kaplan \(MVP - ADSI\)

Which line does it crash on and what is the stack trace?

Also, you can't set "user can't change password" using userAccountControl in
AD. You have to change the security descriptor for the user. It is
actually a bit of a pain.

Joe K.

Hi Joe
System.Security.Principal.WindowsIdentity.GetCurrent().Name => both return
the custom "least privilege" a/c for the worker process

Here comes the code, a bit lengthy! it go thru the code-behind one and
a/c
will be created, but for the called method one it throw exception at the
first commitChanges().
TIA

this is the code-behind file by itself
void btnEntryCreate_Click(Object sender, EventArgs e)
{
Trace.Write("button clicked");
String domain, dirPath, fullName, cnName, sAMName;
String uName, uPwd;
//code to create OU
if (IsValid) {
fullName = txtFName.Text + " " + txtMI.Text + " " +
txtLName.Text;
cnName = "cn=" + fullName;
//Regex strReg = new Regex(" ");
sAMName = txtFName.Text + txtLName.Text;
//ouName = "ou=" + DropDownList1.SelectedItem.Text;
domain = (string)Session["domain"];
dirPath = "LDAP://ou=" + DropDownList1.SelectedItem.Text + ","
+
domain;
try
{
//DirectoryEntry myDir = new DirectoryEntry(dirPath, uName,
uPwd);
Trace.Write(dirPath);
Trace.Write(cnName);
Trace.Write(sAMName);
//DirEntry entry = new
DirEntry(DropDownList1.SelectedItem.Text, domain);
//entry.entryAdd(txtFName.Text, txtLName.Text, txtMI.Text,
txtTeleNum.Text, 0);
//can throw own exception message on error

DirectoryEntry myDir = new DirectoryEntry(dirPath);
DirectoryEntry newUser = myDir.Children.Add(cnName,
"user");
DirEntry entry = new DirEntry(dirPath);
if (entry.chkCN(cnName) == 0)
{
//Trace.Write("setting properties - sAMName");
sAMName = entry.getsAMAcName(txtFName.Text,
txtLName.Text, txtMI.Text);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
newUser.Properties["givenName"].Add(txtFName.Text);
if (txtMI.Text != "")
newUser.Properties["initials"].Add(txtMI.Text);
newUser.Properties["sn"].Add(txtLName.Text);

newUser.Properties["telephoneNumber"].Add(txtTeleNum.Text);
Trace.Write("about to commit");
newUser.CommitChanges();
////Set user additional properties
newUser.Invoke("SetPassword", new object[] { "test" });

////If this user is the admin of this OU
////0x40 Can't Change pwd (this is not working
somehow!)
////0x200 Normal account ie. not disabled
////0x10000 pwd never expires
newUser.Properties["userAccountControl"].Value =
0x10042;
newUser.CommitChanges();
myDir.Dispose();
Response.Write("User " + cnName + " is created");



this is the called method
public int entryAdd(String fname, String lname, String mi, String
telno, int flag)
{
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath, "admin",
"abc123");
try
{
//DirectoryEntry entry = new DirectoryEntry(_path);
//_domain = entry.Parent.Path;
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
_msg = "setting sAMName: " + sAMName;
newUser.Properties["sAMAccountName"].Add(sAMName);
_msg =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
newUser.CommitChanges();

//Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
_msg = "committed once";
newUser.Properties["givenName"].Add(fname);
if (mi != "")
newUser.Properties["initials"].Add(mi);
newUser.Properties["sn"].Add(lname);
newUser.Properties["telephoneNumber"].Add(telno);
//Trace.Write("about to commit");
newUser.CommitChanges();
_msg = "committed twice";
//Set user additional properties
//If this user is the admin of this OU
//0x40 Can't Change pwd (this is not working somehow!)
//0x200 Normal account ie. not disabled
//0x10000 pwd never expires
newUser.Invoke("SetPassword", new object[] { _ouName });
if (flag == 0)
{
newUser.Properties["userAccountControl"].Value =
0x10040;
}


Joe Kaplan (MVP - ADSI) said:
Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

in message Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of
these
conditions before attempting to commit.

Joe K.

<dl> wrote in message Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called
by
the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e)
+545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108


System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection
postData)
+33
System.Web.UI.Page.ProcessRequestMain() +1281
------------------------------------------------------------------------- -
--
 
G

Guest

I have included both the code-behind one and the called method.

the code-behind one should work as is, and if you uncomment the following
two lines
//DirEntry entry = new ....
//entry.entryAdd(....
and comment out the rest of code-behind one, the result should call the
class method ie. entryAdd and throw exception
on the first commitChanges(), the stack trace was included in my first
message of this thread.
TIA

Joe Kaplan (MVP - ADSI) said:
Which line does it crash on and what is the stack trace?

Also, you can't set "user can't change password" using userAccountControl in
AD. You have to change the security descriptor for the user. It is
actually a bit of a pain.

Joe K.

Hi Joe
System.Security.Principal.WindowsIdentity.GetCurrent().Name => both return
the custom "least privilege" a/c for the worker process

Here comes the code, a bit lengthy! it go thru the code-behind one and
a/c
will be created, but for the called method one it throw exception at the
first commitChanges().
TIA

this is the code-behind file by itself
void btnEntryCreate_Click(Object sender, EventArgs e)
{
Trace.Write("button clicked");
String domain, dirPath, fullName, cnName, sAMName;
String uName, uPwd;
//code to create OU
if (IsValid) {
fullName = txtFName.Text + " " + txtMI.Text + " " +
txtLName.Text;
cnName = "cn=" + fullName;
//Regex strReg = new Regex(" ");
sAMName = txtFName.Text + txtLName.Text;
//ouName = "ou=" + DropDownList1.SelectedItem.Text;
domain = (string)Session["domain"];
dirPath = "LDAP://ou=" + DropDownList1.SelectedItem.Text + ","
+
domain;
try
{
//DirectoryEntry myDir = new DirectoryEntry(dirPath, uName,
uPwd);
Trace.Write(dirPath);
Trace.Write(cnName);
Trace.Write(sAMName);
//DirEntry entry = new
DirEntry(DropDownList1.SelectedItem.Text, domain);
//entry.entryAdd(txtFName.Text, txtLName.Text, txtMI.Text,
txtTeleNum.Text, 0);
//can throw own exception message on error

DirectoryEntry myDir = new DirectoryEntry(dirPath);
DirectoryEntry newUser = myDir.Children.Add(cnName,
"user");
DirEntry entry = new DirEntry(dirPath);
if (entry.chkCN(cnName) == 0)
{
//Trace.Write("setting properties - sAMName");
sAMName = entry.getsAMAcName(txtFName.Text,
txtLName.Text, txtMI.Text);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
newUser.Properties["givenName"].Add(txtFName.Text);
if (txtMI.Text != "")
newUser.Properties["initials"].Add(txtMI.Text);
newUser.Properties["sn"].Add(txtLName.Text);

newUser.Properties["telephoneNumber"].Add(txtTeleNum.Text);
Trace.Write("about to commit");
newUser.CommitChanges();
////Set user additional properties
newUser.Invoke("SetPassword", new object[] { "test" });

////If this user is the admin of this OU
////0x40 Can't Change pwd (this is not working
somehow!)
////0x200 Normal account ie. not disabled
////0x10000 pwd never expires
newUser.Properties["userAccountControl"].Value =
0x10042;
newUser.CommitChanges();
myDir.Dispose();
Response.Write("User " + cnName + " is created");



this is the called method
public int entryAdd(String fname, String lname, String mi, String
telno, int flag)
{
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath, "admin",
"abc123");
try
{
//DirectoryEntry entry = new DirectoryEntry(_path);
//_domain = entry.Parent.Path;
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
_msg = "setting sAMName: " + sAMName;
newUser.Properties["sAMAccountName"].Add(sAMName);
_msg =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
newUser.CommitChanges();

//Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
_msg = "committed once";
newUser.Properties["givenName"].Add(fname);
if (mi != "")
newUser.Properties["initials"].Add(mi);
newUser.Properties["sn"].Add(lname);
newUser.Properties["telephoneNumber"].Add(telno);
//Trace.Write("about to commit");
newUser.CommitChanges();
_msg = "committed twice";
//Set user additional properties
//If this user is the admin of this OU
//0x40 Can't Change pwd (this is not working somehow!)
//0x200 Normal account ie. not disabled
//0x10000 pwd never expires
newUser.Invoke("SetPassword", new object[] { _ouName });
if (flag == 0)
{
newUser.Properties["userAccountControl"].Value =
0x10040;
}


in message news:%[email protected]...
Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

<dl> wrote in message Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

in message Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of
these
conditions before attempting to commit.

Joe K.

<dl> wrote in message Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then called
by
the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi, String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e)
+545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection
postData)
+33
System.Web.UI.Page.ProcessRequestMain() +1281




------------------------------------------------------------------------
-
-
 
J

Joe Kaplan \(MVP - ADSI\)

I'm guessing this is the problem. In the "method", you specify the CN for
the Add method like this:
string cn = fname + " " + mi + " " + lname;

In the "code behind", you specify it like this:
cnName = "cn=" + fullName;

The name must be specified in the format "CN=username" which appears to be
how you are doing it in the code behind but not in the method.

Joe K.

I have included both the code-behind one and the called method.

the code-behind one should work as is, and if you uncomment the following
two lines
//DirEntry entry = new ....
//entry.entryAdd(....
and comment out the rest of code-behind one, the result should call the
class method ie. entryAdd and throw exception
on the first commitChanges(), the stack trace was included in my first
message of this thread.
TIA

Joe Kaplan (MVP - ADSI) said:
Which line does it crash on and what is the stack trace?

Also, you can't set "user can't change password" using userAccountControl in
AD. You have to change the security descriptor for the user. It is
actually a bit of a pain.

Joe K.

Hi Joe
System.Security.Principal.WindowsIdentity.GetCurrent().Name => both return
the custom "least privilege" a/c for the worker process

Here comes the code, a bit lengthy! it go thru the code-behind one and
a/c
will be created, but for the called method one it throw exception at
the
first commitChanges().
TIA

this is the code-behind file by itself
void btnEntryCreate_Click(Object sender, EventArgs e)
{
Trace.Write("button clicked");
String domain, dirPath, fullName, cnName, sAMName;
String uName, uPwd;
//code to create OU
if (IsValid) {
fullName = txtFName.Text + " " + txtMI.Text + " " +
txtLName.Text;
cnName = "cn=" + fullName;
//Regex strReg = new Regex(" ");
sAMName = txtFName.Text + txtLName.Text;
//ouName = "ou=" + DropDownList1.SelectedItem.Text;
domain = (string)Session["domain"];
dirPath = "LDAP://ou=" + DropDownList1.SelectedItem.Text + ","
+
domain;
try
{
//DirectoryEntry myDir = new DirectoryEntry(dirPath, uName,
uPwd);
Trace.Write(dirPath);
Trace.Write(cnName);
Trace.Write(sAMName);
//DirEntry entry = new
DirEntry(DropDownList1.SelectedItem.Text, domain);
//entry.entryAdd(txtFName.Text, txtLName.Text, txtMI.Text,
txtTeleNum.Text, 0);
//can throw own exception message on error

DirectoryEntry myDir = new DirectoryEntry(dirPath);
DirectoryEntry newUser = myDir.Children.Add(cnName,
"user");
DirEntry entry = new DirEntry(dirPath);
if (entry.chkCN(cnName) == 0)
{
//Trace.Write("setting properties - sAMName");
sAMName = entry.getsAMAcName(txtFName.Text,
txtLName.Text, txtMI.Text);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
newUser.Properties["givenName"].Add(txtFName.Text);
if (txtMI.Text != "")
newUser.Properties["initials"].Add(txtMI.Text);
newUser.Properties["sn"].Add(txtLName.Text);

newUser.Properties["telephoneNumber"].Add(txtTeleNum.Text);
Trace.Write("about to commit");
newUser.CommitChanges();
////Set user additional properties
newUser.Invoke("SetPassword", new object[] { "test" });

////If this user is the admin of this OU
////0x40 Can't Change pwd (this is not working
somehow!)
////0x200 Normal account ie. not disabled
////0x10000 pwd never expires
newUser.Properties["userAccountControl"].Value =
0x10042;
newUser.CommitChanges();
myDir.Dispose();
Response.Write("User " + cnName + " is created");



this is the called method
public int entryAdd(String fname, String lname, String mi,
String
telno, int flag)
{
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath, "admin",
"abc123");
try
{
//DirectoryEntry entry = new DirectoryEntry(_path);
//_domain = entry.Parent.Path;
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
_msg = "setting sAMName: " + sAMName;
newUser.Properties["sAMAccountName"].Add(sAMName);
_msg =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
newUser.CommitChanges();

//Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
_msg = "committed once";
newUser.Properties["givenName"].Add(fname);
if (mi != "")
newUser.Properties["initials"].Add(mi);
newUser.Properties["sn"].Add(lname);
newUser.Properties["telephoneNumber"].Add(telno);
//Trace.Write("about to commit");
newUser.CommitChanges();
_msg = "committed twice";
//Set user additional properties
//If this user is the admin of this OU
//0x40 Can't Change pwd (this is not working somehow!)
//0x200 Normal account ie. not disabled
//0x10000 pwd never expires
newUser.Invoke("SetPassword", new object[] { _ouName });
if (flag == 0)
{
newUser.Properties["userAccountControl"].Value =
0x10040;
}


in message Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

<dl> wrote in message Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

"Joe Kaplan (MVP - ADSI)" <[email protected]>
wrote
in message Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a either of
these
conditions before attempting to commit.

Joe K.

<dl> wrote in message Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn,
"user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then
called
by
the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process
the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi,
String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender, EventArgs e)
+545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108



System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection
postData)
+33
System.Web.UI.Page.ProcessRequestMain() +1281
------------------------------------------------------------------------ -
-
--
 
G

Guest

Hi Joe
You are right! What a silly mistake? Appreciate your help on this!
Thankyou very much!

Joe Kaplan (MVP - ADSI) said:
I'm guessing this is the problem. In the "method", you specify the CN for
the Add method like this:
string cn = fname + " " + mi + " " + lname;

In the "code behind", you specify it like this:
cnName = "cn=" + fullName;

The name must be specified in the format "CN=username" which appears to be
how you are doing it in the code behind but not in the method.

Joe K.

I have included both the code-behind one and the called method.

the code-behind one should work as is, and if you uncomment the following
two lines
//DirEntry entry = new ....
//entry.entryAdd(....
and comment out the rest of code-behind one, the result should call the
class method ie. entryAdd and throw exception
on the first commitChanges(), the stack trace was included in my first
message of this thread.
TIA

in message news:[email protected]...
Which line does it crash on and what is the stack trace?

Also, you can't set "user can't change password" using
userAccountControl
in
AD. You have to change the security descriptor for the user. It is
actually a bit of a pain.

Joe K.

<dl> wrote in message Hi Joe
System.Security.Principal.WindowsIdentity.GetCurrent().Name => both return
the custom "least privilege" a/c for the worker process

Here comes the code, a bit lengthy! it go thru the code-behind one and
a/c
will be created, but for the called method one it throw exception at
the
first commitChanges().
TIA

this is the code-behind file by itself
void btnEntryCreate_Click(Object sender, EventArgs e)
{
Trace.Write("button clicked");
String domain, dirPath, fullName, cnName, sAMName;
String uName, uPwd;
//code to create OU
if (IsValid) {
fullName = txtFName.Text + " " + txtMI.Text + " " +
txtLName.Text;
cnName = "cn=" + fullName;
//Regex strReg = new Regex(" ");
sAMName = txtFName.Text + txtLName.Text;
//ouName = "ou=" + DropDownList1.SelectedItem.Text;
domain = (string)Session["domain"];
dirPath = "LDAP://ou=" + DropDownList1.SelectedItem.Text + ","
+
domain;
try
{
//DirectoryEntry myDir = new DirectoryEntry(dirPath, uName,
uPwd);
Trace.Write(dirPath);
Trace.Write(cnName);
Trace.Write(sAMName);
//DirEntry entry = new
DirEntry(DropDownList1.SelectedItem.Text, domain);
//entry.entryAdd(txtFName.Text, txtLName.Text, txtMI.Text,
txtTeleNum.Text, 0);
//can throw own exception message on error

DirectoryEntry myDir = new DirectoryEntry(dirPath);
DirectoryEntry newUser = myDir.Children.Add(cnName,
"user");
DirEntry entry = new DirEntry(dirPath);
if (entry.chkCN(cnName) == 0)
{
//Trace.Write("setting properties - sAMName");
sAMName = entry.getsAMAcName(txtFName.Text,
txtLName.Text, txtMI.Text);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();
Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
newUser.Properties["givenName"].Add(txtFName.Text);
if (txtMI.Text != "")
newUser.Properties["initials"].Add(txtMI.Text);
newUser.Properties["sn"].Add(txtLName.Text);

newUser.Properties["telephoneNumber"].Add(txtTeleNum.Text);
Trace.Write("about to commit");
newUser.CommitChanges();
////Set user additional properties
newUser.Invoke("SetPassword", new object[] { "test" });

////If this user is the admin of this OU
////0x40 Can't Change pwd (this is not working
somehow!)
////0x200 Normal account ie. not disabled
////0x10000 pwd never expires
newUser.Properties["userAccountControl"].Value =
0x10042;
newUser.CommitChanges();
myDir.Dispose();
Response.Write("User " + cnName + " is created");



this is the called method
public int entryAdd(String fname, String lname, String mi,
String
telno, int flag)
{
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath, "admin",
"abc123");
try
{
//DirectoryEntry entry = new DirectoryEntry(_path);
//_domain = entry.Parent.Path;
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn, "user");
string sAMName = getsAMAcName(fname, lname, mi);
_msg = "setting sAMName: " + sAMName;
newUser.Properties["sAMAccountName"].Add(sAMName);
_msg =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
newUser.CommitChanges();
//Trace.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
_msg = "committed once";
newUser.Properties["givenName"].Add(fname);
if (mi != "")
newUser.Properties["initials"].Add(mi);
newUser.Properties["sn"].Add(lname);
newUser.Properties["telephoneNumber"].Add(telno);
//Trace.Write("about to commit");
newUser.CommitChanges();
_msg = "committed twice";
//Set user additional properties
//If this user is the admin of this OU
//0x40 Can't Change pwd (this is not working somehow!)
//0x200 Normal account ie. not disabled
//0x10000 pwd never expires
newUser.Invoke("SetPassword", new object[] { _ouName });
if (flag == 0)
{
newUser.Properties["userAccountControl"].Value =
0x10040;
}


in message Can you show the code in both instances and tell what
System.Security.Principal.WindowsIdentity.GetCurrent().Name is in both
contexts?

Thanks,

Joe K.

<dl> wrote in message Yes, I am sure. The only difference is running by the code-behind page
along
with the commitChanges() or calling from the code-behind with the
commitChanges() being executed in a class method.
My environment:
ASP.NET 1.1 sp1
DC running on Win2000 server with custom "least privilege" account with
Account Operator membership.

TIA

"Joe Kaplan (MVP - ADSI)"
wrote
in message Are you sure you aren't accidentally trying to add the same account
twice?
The directory will try to prevent you from creating duplicate
sAMAccountNames directory-wide or duplicate CNs in the same container.

A robust application should search the directory first for a
either
of
these
conditions before attempting to commit.

Joe K.

<dl> wrote in message Hi
I have written a code-behind page with exact lines of code and it
works.
string dirPath = "LDAP://ou=" + _ouName + "," + _domain;
DirectoryEntry entry = new DirectoryEntry(dirPath);
string cn = fname + " " + mi + " " + lname;
DirectoryEntry newUser = entry.Children.Add(cn,
"user");
string sAMName = getsAMAcName(fname, lname, mi);
newUser.Properties["sAMAccountName"].Add(sAMName);
newUser.CommitChanges();

But when I move these lines to a class method which is then
called
by
the
code-behind page I got errors on "CommitChanges".

Any idea, please?!
TIA

[COMException (0x80072035): The server is unwilling to process
the
request.]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +37
NETDS.DirEntry.entryAdd(String fname, String lname, String mi,
String
telno, Int32 flag) +307
NETDS.EntryCreate.btnEntryCreate_Click(Object sender,
EventArgs
e)
+545
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection
postData)
+33
System.Web.UI.Page.ProcessRequestMain() +1281





-----------------------------------------------------------------------
-
-
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top