* support-test-*.cs: Rename from test-*-p2.cs.
[mono.git] / mcs / class / System.DirectoryServices / System.DirectoryServices / DirectoryEntries.cs
1 /******************************************************************************
2 * The MIT License
3 * Copyright (c) 2003 Novell Inc.,  www.novell.com
4
5 * Permission is hereby granted, free of charge, to any person obtaining  a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including  without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
9 * copies of the Software, and to  permit persons to whom the Software is 
10 * furnished to do so, subject to the following conditions:
11
12 * The above copyright notice and this permission notice shall be included in 
13 * all copies or substantial portions of the Software.
14
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *******************************************************************************/
23
24 //
25 // System.DirectoryServices.DirectoryEntries.cs
26 //
27 // Author:
28 //   Sunil Kumar (sunilk@novell.com)
29 //
30 // (C) Novell Inc.
31 //
32
33 using System.Collections;
34 using Novell.Directory.Ldap;
35
36 namespace System.DirectoryServices
37 {
38         
39         /// <summary>
40         ///Contains the children (child entries) of an entry in
41         /// a Ldap Directory
42         /// </summary>
43         public class DirectoryEntries : IEnumerable
44         {
45                 private LdapConnection _Conn=null;
46                 private string _Bpath=null;
47                 private string _Buser=null;
48                 private string _Bpass=null;
49                 private string _Basedn=null;
50                 private ArrayList m_oValues=null;
51
52
53                 /// <summary> Initializes the Connection and other properties.
54                 /// 
55                 /// </summary>
56                 private void InitBlock()
57                 {
58                         try                     {
59                                 LdapUrl lUrl=new LdapUrl(_Bpath);
60                                 _Conn = new LdapConnection();
61                                 _Conn.Connect(lUrl.Host,lUrl.Port);
62                                 _Conn.Bind(_Buser,_Bpass);
63                         }
64                         catch(LdapException ex)                 {
65                                 throw ex;
66                         }
67                         catch(Exception e)                              {
68                                 throw e;
69                         }
70                 }
71
72                 internal string Basedn
73                 {
74                         get                                                                             {
75                                 if( _Basedn == null)                            {
76                                         LdapUrl lurl=new LdapUrl(_Bpath);
77                                         string bdn = lurl.getDN();
78                                         if( bdn != null)
79                                                 _Basedn = bdn;
80                                         else
81                                                 _Basedn = "";
82                                 }
83                                 return _Basedn;
84                         }
85                 }
86                                 
87                 /// <summary> Contains the Path of the Container under which
88                 /// the entries belongs to.
89                 /// </summary>
90                 internal string Bpath
91                 {
92                         get                     {
93                                 return _Bpath;
94                         }
95                         set                     {
96                                 _Bpath=value;
97                         }
98                 }
99
100                 /// <summary> Returns the connection object used to communicate with
101                 /// Ldap server
102                 /// </summary>
103                 internal LdapConnection Conn
104                 {
105                         get                                             {
106                                 if( _Conn == null)      {
107                                         InitBlock();
108                                 }
109                                 return _Conn;
110                         }
111                         set                                             {
112                                 _Conn=value;
113                         }
114                 }
115
116                 /// <summary> Constructs a collection of all the child entries of
117                 /// an entry
118                 /// </summary>
119                 /// <param name="path"> Path of the entry
120                 /// </param>
121                 /// <param name="uname"> Username to Bind as while authenticating to ldap
122                 /// server</param>
123                 /// <param name="passwd"> Password of the user</param>
124                 internal DirectoryEntries(string path, string uname, string passwd)
125                 {
126                         _Bpath = path;
127                         _Buser = uname;
128                         _Bpass = passwd;
129                 }
130
131                 /// <summary> Constructs a collection of all the child entries of
132                 /// a entry
133                 /// </summary>
134                 /// <param name="path"> Path of the entry
135                 /// </param>
136                 /// <param name="lc"> connection object used to connect to ldap server
137                 /// </param>
138                 internal DirectoryEntries(string path,  LdapConnection lc)
139                 {
140                         _Bpath = path;
141                         _Conn = lc;
142                 }
143
144                 public SchemaNameCollection SchemaFilter {
145                         [MonoTODO]
146                         get { throw new NotImplementedException ("System.DirectoryServices.DirectoryEntries.SchemaFilter"); }
147                 }
148
149                 public  IEnumerator GetEnumerator()
150                 {
151                         m_oValues= new ArrayList();
152                         string[] attrs={"objectClass"};
153                         LdapSearchResults lsc= Conn.Search(     Basedn,
154                                                                                                 LdapConnection.SCOPE_ONE,
155                                                                                                 "objectClass=*",
156                                                                                                 attrs,
157                                                                                                 false);
158
159                         LdapUrl Burl=new LdapUrl(_Bpath);
160                         string host=Burl.Host;
161                         int port=Burl.Port;
162
163                         while (lsc.hasMore())                   {
164                                 LdapEntry nextEntry = null;
165                                 try                                     {
166                                         nextEntry = lsc.next();
167                                 }
168                                 catch(LdapException e)          {
169                                         // Exception is thrown, go for next entry
170                                         continue;
171                                 }
172                                 DirectoryEntry dEntry=new DirectoryEntry(Conn);
173                                 string eFdn=nextEntry.DN;
174                                 LdapUrl curl=new LdapUrl(host,port,eFdn);
175                                 dEntry.Path=curl.ToString();
176                                 m_oValues.Add((DirectoryEntry) dEntry);
177                         }
178                         return m_oValues.GetEnumerator();
179                 }
180
181                 /// <summary> Creates a request to create a new entry in the container.
182                 /// 
183                 /// </summary>
184                 /// <param name="name"> RDN of the entry to be created
185                 /// </param>
186                 /// <param name="schemaClassName"> StructuralClassName of the entry to be
187                 /// created.
188                 /// </param>
189                 public DirectoryEntry Add(      string name,string schemaClassName)
190                 {
191                         DirectoryEntry ent=new DirectoryEntry(Conn);
192                         LdapUrl Burl=new LdapUrl(_Bpath);
193                         string baseDn = Burl.getDN();
194                         string eFdn=((baseDn != null && baseDn.Length != 0) ? (name + "," + baseDn) : name);
195                         LdapUrl curl=new LdapUrl(Burl.Host,Burl.Port,eFdn);
196                         ent.Path=curl.ToString();
197                         ent.Nflag = true;
198                         return ent;
199                 }
200
201                 /// <summary>
202                 /// Deletes a child DirectoryEntry from this collection
203                 /// </summary>
204                 /// <param name="entry">The DirectoryEntry to delete</param>
205                 public void Remove(     DirectoryEntry entry )
206                 {
207                         LdapUrl Burl=new LdapUrl(_Bpath);
208                         string eFDN = entry.Name + "," + Burl.getDN();
209                         Conn.Delete( eFDN);
210                 }
211
212                 /// <summary>
213                 /// Returns the child with the specified name.
214                 /// </summary>
215                 /// <param name="filter">relative distinguised name of the child
216                 /// </param>
217                 /// <returns>Child entry with the specified name </returns>
218                 public DirectoryEntry Find(string filter)
219                 {
220                         DirectoryEntry child=CheckEntry(filter);
221                         return child;
222                 }
223
224                 /// <summary>
225                 /// Returns the child with the specified name and of the specified type.
226                 /// </summary>
227                 /// <param name="filter">relative distinguised name of the child
228                 /// </param>
229                 /// <param name="otype"> Type of the child i.e strutcuralObjectClass
230                 /// name of the child </param>
231                 /// <returns>Child entry with the specified name and type</returns>
232                 public DirectoryEntry Find(string filter, string otype)
233                 {
234                         DirectoryEntry child=CheckEntry(filter);
235
236                         if( child != null)                      {
237                                 if(child.Properties["objectclass"].ContainsCaselessStringValue(otype))
238                                         return child;
239                                 else
240                                         throw new SystemException("An unknown directory object was requested");
241                         }
242                         return child;
243                 }
244
245                 /// <summary>
246                 /// Checks whether the entry with the specified Relative distinguised name
247                 /// exists or not.
248                 /// </summary>
249                 /// <param name="rdn"> Relative distinguished name of the entry</param>
250                 /// <returns>DirectoryEntry object of Entry if entry exists,
251                 /// Null if entry doesn't exist </returns>
252                 private DirectoryEntry CheckEntry(string rdn)
253                 {
254                         string Ofdn=null;
255                         DirectoryEntry cEntry=null;
256
257                         Ofdn=rdn+","+Basedn;
258                         string[] attrs={"objectClass"};
259                         try                                                                             {
260                                 LdapSearchResults lsc= Conn.Search(     Ofdn,
261                                                                                                         LdapConnection.SCOPE_BASE,
262                                                                                                         "objectClass=*",
263                                                                                                         attrs,
264                                                                                                         false);
265                                 while(lsc.hasMore())                            {
266                                         LdapEntry nextEntry = null;
267                                         try                                                             {
268                                                 nextEntry = lsc.next();
269                                                 cEntry =  new DirectoryEntry(Conn);
270                                                 LdapUrl Burl=new LdapUrl(_Bpath);
271                                                 LdapUrl curl=new LdapUrl(Burl.Host,Burl.Port,Ofdn);
272                                                 cEntry.Path=curl.ToString();
273                                         }
274                                         catch(LdapException e)                  {
275                                                 // Exception is thrown, go for next entry
276                                                 throw e;
277                                         }
278                                         break;
279                                 }
280
281                         }
282                         catch(LdapException le)
283                         {
284                                 if(le.ResultCode == LdapException.NO_SUCH_OBJECT)       {
285                                         return null;
286                                 }
287                                 else            {
288                                         throw le;
289                                 }
290                         }
291                         catch(Exception e)              {
292                                 throw e;
293                         }
294                         return cEntry;
295                 }
296
297         }
298
299 }
300