1#include "utils.h"
2#include <ldap.h>
3
4NSString* authMethodToString(int authMethod)
5{
6    switch(authMethod)
7    {
8	case LDAP_AUTH_NONE: return @"NONE";
9	case LDAP_AUTH_SIMPLE: return @"SIMPLE";
10	case LDAP_AUTH_SASL: return @"SASL";
11	case LDAP_AUTH_KRBV4: return @"KRBV4";
12	case LDAP_AUTH_KRBV41: return @"KRBV41";
13	case LDAP_AUTH_KRBV42: return @"KRBV42";
14	default: return @"UNKNOWN";
15    }
16}
17
18int stringToAuthMethod(NSString* str)
19{
20    str = [str uppercaseString];
21    if([str isEqualToString: @"NONE"]) return LDAP_AUTH_NONE;
22    if([str isEqualToString: @"SIMPLE"]) return LDAP_AUTH_SIMPLE;
23    if([str isEqualToString: @"SASL"]) return LDAP_AUTH_SASL;
24    if([str isEqualToString: @"KRBV4"]) return LDAP_AUTH_KRBV4;
25    if([str isEqualToString: @"KRBV41"]) return LDAP_AUTH_KRBV41;
26    if([str isEqualToString: @"KRBV42"]) return LDAP_AUTH_KRBV42;
27    return -1;
28}
29
30NSString* scopeToString(int scope)
31{
32    switch(scope)
33    {
34	case LDAP_SCOPE_DEFAULT: return @"DEFAULT";
35	case LDAP_SCOPE_BASE: return @"BASE";
36	case LDAP_SCOPE_ONELEVEL: return @"ONELEVEL";
37	case LDAP_SCOPE_SUBTREE: return @"SUBTREE";
38	default: return @"UNKNOWN";
39    }
40}
41
42int stringToScope(NSString* str)
43{
44    str = [str uppercaseString];
45    if([str isEqualToString: @"DEFAULT"]) return LDAP_SCOPE_DEFAULT;
46    if([str isEqualToString: @"BASE"]) return LDAP_SCOPE_BASE;
47    if([str isEqualToString: @"ONELEVEL"]) return LDAP_SCOPE_ONELEVEL;
48    if([str isEqualToString: @"SUBTREE"]) return LDAP_SCOPE_SUBTREE;
49    return -1;
50}
51
52NSArray *mapping = NULL;
53NSArray *skip = NULL;
54@class LDAPAddressBook;
55
56void initMapping(void)
57{
58    if(!mapping)
59    {
60	NSBundle *currentBundle; NSString *path;
61	currentBundle = [NSBundle bundleForClass: [LDAPAddressBook class]];
62	path = [currentBundle pathForResource: @"LDAPPersonMapping"
63			      ofType: @"plist"];
64	mapping = [[NSString stringWithContentsOfFile: path] propertyList];
65	[mapping retain];
66    }
67    if(!skip)
68    {
69	skip = [[NSArray alloc] initWithObjects: @"cn", @"objectClass", NULL];
70    }
71}
72
73id addressesKeyForLDAPKey(NSString *key)
74{
75    int i, j;
76
77    if(!mapping) initMapping();
78
79    for(i=0; i<[mapping count]; i++)
80    {
81	NSArray *arr = [[mapping objectAtIndex: i]
82			   objectForKey: @"LDAPKeys"];
83	for(j=0; j<[arr count]; j++)
84	    if([[arr objectAtIndex: j] caseInsensitiveCompare: key] ==
85	       NSOrderedSame)
86		return [[mapping objectAtIndex: i]
87			   objectForKey: @"AddressesKey"];
88    }
89
90    return nil;
91}
92
93
94ADPerson* ldapEntryToPerson(GSLDAPEntry* entry)
95{
96    ADPerson *p; NSEnumerator *nameE; NSString *name;
97
98    p = [[[ADPerson alloc] init] autorelease];
99    nameE = [entry attributeNameEnumerator];
100    while((name = [nameE nextObject]))
101    {
102	NSArray *val; id addrKey; int i;
103	NSString *property = nil, *label = nil, *key = nil;
104	ADPropertyType type;
105
106	if([skip containsObject: name]) continue;
107
108	val = [entry valuesForAttributeNamed: name];
109	addrKey = addressesKeyForLDAPKey(name);
110
111	if(!addrKey)
112	{
113	    NSLog(@"Can't handle LDAP key %@ yet\n", name);
114	    continue;
115	}
116
117	if([addrKey isEqualToString: @"Skip"])
118	    continue;
119
120	if([addrKey isKindOfClass: [NSString class]])
121	    property = addrKey;
122	else
123	{
124	    property = [addrKey objectForKey: @"Property"];
125	    label = [addrKey objectForKey: @"Label"];
126	    key = [addrKey objectForKey: @"Key"];
127	}
128
129	type = [[ADPerson class] typeOfProperty: property];
130	if(!type)
131	{
132	    NSLog(@"Error in Property %@ for %@\n",
133		  property, name);
134	    continue;
135	}
136
137	// string? set it directly
138	if(type == ADStringProperty)
139	{
140	    [p setValue: [val objectAtIndex: 0]
141	       forProperty: property];
142	    continue;
143	}
144
145	// multi-value, but not multi-dictionary
146	else if(type == ADMultiStringProperty)
147	{
148	    ADMultiValue *v; ADMutableMultiValue *mv;
149
150	    v = [p valueForProperty: property];
151	    if(!v)
152		mv = [[[ADMutableMultiValue alloc] init] autorelease];
153	    else
154		mv = [v mutableCopy];
155
156	    for(i=0; i<[val count]; i++)
157		[mv addValue: [val objectAtIndex: i]
158		    withLabel: label];
159
160	    [p setValue: [[[ADMultiValue alloc] initWithMultiValue: mv]
161			     autorelease]
162	       forProperty: property];
163	}
164
165	else if(type == ADMultiDictionaryProperty)
166	{
167	    ADMultiValue *v; ADMutableMultiValue *mv;
168	    NSDictionary *d; NSMutableDictionary *md;
169	    int index; BOOL have;
170
171	    v = [p valueForProperty: property];
172	    if(!v)
173		mv = [[[ADMutableMultiValue alloc] init] autorelease];
174	    else
175		mv = [v mutableCopy];
176
177	    d = nil; have = NO;
178	    for(index=0; index<[mv count]; index++)
179		if([[mv labelAtIndex: index] isEqualToString: label])
180		{
181		    have = YES;
182		    d = [mv valueAtIndex: index];
183		    break;
184		}
185
186	    if(!d) md = [NSMutableDictionary dictionary];
187	    else md = [[[NSMutableDictionary alloc] initWithDictionary: d]
188			  autorelease];
189
190	    [md setObject: [val objectAtIndex: 0] forKey: key];
191
192	    if(have)
193		[mv replaceValueAtIndex: index
194		    withValue: [NSDictionary dictionaryWithDictionary: md]];
195	    else
196		[mv addValue: [NSDictionary dictionaryWithDictionary: md]
197		    withLabel: label];
198
199	    [p setValue: [[[ADMultiValue alloc] initWithMultiValue: mv]
200			     autorelease]
201	       forProperty: property];
202	}
203
204	else
205	{
206	    NSLog(@"Can't handle values of type %d yet\n", type);
207	}
208    }
209
210    return p;
211}
212
213GSLDAPEntry* personToLDAPEntry(ADPerson* person)
214{
215    return nil;
216}
217