1
2#import <Foundation/Foundation.h>
3#import <OpenDirectory/OpenDirectory.h>
4
5#import <CommonCrypto/CommonDigest.h>
6
7#include <err.h>
8
9static CFStringRef kerberosKDC = CFSTR("KerberosKDC");
10static CFStringRef rootName = CFSTR("/Local/Default");
11static CFStringRef realName = CFSTR("dsAttrTypeStandard:RealName");
12
13static char *
14sha1_hash(const void *data, size_t len)
15{
16    char *outstr, *cpOut;
17    unsigned char digest[CC_SHA1_DIGEST_LENGTH];
18    unsigned i;
19    
20    CC_SHA1(data, len, digest);
21
22    cpOut = outstr = (char *)malloc((2 * CC_SHA1_DIGEST_LENGTH) + 1);
23    if (outstr == NULL)
24	return NULL;
25
26    for(i = 0; i < sizeof(digest); i++, cpOut += 2)
27	sprintf(cpOut, "%02X", (unsigned)digest[i]);
28    *cpOut = '\0';
29    return outstr;
30}
31
32
33static void
34update_node(NSString *realm)
35{
36    ODNodeRef localRef = NULL;
37    NSArray *attrs;
38    ODRecordRef cfRecord;
39
40    localRef = ODNodeCreateWithName(kCFAllocatorDefault,
41				    kODSessionDefault,
42				    rootName,
43				    NULL);
44    if (localRef == NULL)
45	errx(1, "ODNodeCreateWithName");
46
47    attrs = [NSArray arrayWithObject:(id)realName];
48
49    cfRecord = ODNodeCopyRecord(localRef, kODRecordTypeConfiguration,
50				kerberosKDC, (CFArrayRef)attrs, NULL);
51    if (cfRecord == NULL) {
52	NSDictionary *attributes;
53	
54	attributes = [[NSDictionary alloc] init];
55	
56	cfRecord = ODNodeCreateRecord(localRef, 
57				      kODRecordTypeConfiguration,
58				      kerberosKDC,
59				      (CFDictionaryRef)attributes,
60				      NULL);
61	[attributes release];
62
63	if (cfRecord == NULL)
64	    errx(1, "failed to create node");
65
66    }
67
68    /* update record.realname with realname */
69
70    bool r = ODRecordSetValue(cfRecord, (NSString *)realName,
71			      [NSArray arrayWithObject:realm],
72			      NULL);
73    if (!r)
74	errx(1, "ODRecordSetValue");
75
76    ODRecordSynchronize(cfRecord, NULL);
77
78    CFRelease(cfRecord);
79    CFRelease(localRef);
80}
81
82
83
84int
85main(int argc, char **argv)
86{
87    NSString* realm, *urealm;
88    OSStatus ret;
89    SecIdentityRef idRef = NULL;
90    SecCertificateRef certRef = NULL;
91    char *cert_hash = NULL;
92    CFDataRef certData;
93    
94    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
95
96    ret = SecIdentityCopySystemIdentity(kSecIdentityDomainKerberosKDC,
97					 &idRef, NULL);
98    if (ret) {
99	cssmPerror("SecIdentityCopySystemIdentity", ret);
100	return 1;
101    }
102    
103    ret = SecIdentityCopyCertificate(idRef, &certRef);
104    if (ret) {
105	cssmPerror("SecIdentityCopyCertificate", ret);
106	return 1;
107    }
108    
109    /* now the actual cert data */
110    certData = SecCertificateCopyData(certRef);
111    if (certRef == NULL)
112	errx(1, "SecCertificateCopyData");
113	
114    cert_hash = sha1_hash(CFDataGetBytePtr(certData), CFDataGetLength(certData));
115    CFRelease(certData);
116    if (cert_hash == NULL)
117	errx(1, "Error obtaining cert hash");
118
119    realm = [NSString stringWithFormat:@"LKDC:SHA1.%@", [NSString stringWithCString: cert_hash encoding:NSUTF8StringEncoding]];
120    
121    urealm = [realm uppercaseString];
122    update_node(urealm);
123
124    free(cert_hash);
125    CFRelease(certRef);
126    CFRelease(idRef);
127
128    printf("realm: %s\n", [urealm UTF8String]);
129
130    [pool drain];
131
132    return 0;
133
134}
135