1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker *
3*48a54d36SAndroid Build Coastguard Worker * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker *
5*48a54d36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker *
9*48a54d36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker *
11*48a54d36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker */
17*48a54d36SAndroid Build Coastguard Worker
18*48a54d36SAndroid Build Coastguard Worker #include "Secret.h"
19*48a54d36SAndroid Build Coastguard Worker #include <stdarg.h>
20*48a54d36SAndroid Build Coastguard Worker #include <stddef.h>
21*48a54d36SAndroid Build Coastguard Worker #include <stdio.h>
22*48a54d36SAndroid Build Coastguard Worker #include <stdlib.h>
23*48a54d36SAndroid Build Coastguard Worker #include <string.h>
24*48a54d36SAndroid Build Coastguard Worker #include <winsock2.h>
25*48a54d36SAndroid Build Coastguard Worker #include <ws2tcpip.h>
26*48a54d36SAndroid Build Coastguard Worker #include <windows.h>
27*48a54d36SAndroid Build Coastguard Worker #include <process.h>
28*48a54d36SAndroid Build Coastguard Worker #include <ntsecapi.h>
29*48a54d36SAndroid Build Coastguard Worker #include <lm.h>
30*48a54d36SAndroid Build Coastguard Worker #include "DebugServices.h"
31*48a54d36SAndroid Build Coastguard Worker
32*48a54d36SAndroid Build Coastguard Worker
33*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input );
34*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input );
35*48a54d36SAndroid Build Coastguard Worker
36*48a54d36SAndroid Build Coastguard Worker
37*48a54d36SAndroid Build Coastguard Worker BOOL
LsaGetSecret(const char * inDomain,char * outDomain,unsigned outDomainSize,char * outKey,unsigned outKeySize,char * outSecret,unsigned outSecretSize)38*48a54d36SAndroid Build Coastguard Worker LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize )
39*48a54d36SAndroid Build Coastguard Worker {
40*48a54d36SAndroid Build Coastguard Worker PLSA_UNICODE_STRING domainLSA;
41*48a54d36SAndroid Build Coastguard Worker PLSA_UNICODE_STRING keyLSA;
42*48a54d36SAndroid Build Coastguard Worker PLSA_UNICODE_STRING secretLSA;
43*48a54d36SAndroid Build Coastguard Worker size_t i;
44*48a54d36SAndroid Build Coastguard Worker size_t dlen;
45*48a54d36SAndroid Build Coastguard Worker LSA_OBJECT_ATTRIBUTES attrs;
46*48a54d36SAndroid Build Coastguard Worker LSA_HANDLE handle = NULL;
47*48a54d36SAndroid Build Coastguard Worker NTSTATUS res;
48*48a54d36SAndroid Build Coastguard Worker OSStatus err;
49*48a54d36SAndroid Build Coastguard Worker
50*48a54d36SAndroid Build Coastguard Worker check( inDomain );
51*48a54d36SAndroid Build Coastguard Worker check( outDomain );
52*48a54d36SAndroid Build Coastguard Worker check( outKey );
53*48a54d36SAndroid Build Coastguard Worker check( outSecret );
54*48a54d36SAndroid Build Coastguard Worker
55*48a54d36SAndroid Build Coastguard Worker // Initialize
56*48a54d36SAndroid Build Coastguard Worker
57*48a54d36SAndroid Build Coastguard Worker domainLSA = NULL;
58*48a54d36SAndroid Build Coastguard Worker keyLSA = NULL;
59*48a54d36SAndroid Build Coastguard Worker secretLSA = NULL;
60*48a54d36SAndroid Build Coastguard Worker
61*48a54d36SAndroid Build Coastguard Worker // Make sure we have enough space to add trailing dot
62*48a54d36SAndroid Build Coastguard Worker
63*48a54d36SAndroid Build Coastguard Worker dlen = strlen( inDomain );
64*48a54d36SAndroid Build Coastguard Worker err = strcpy_s( outDomain, outDomainSize - 2, inDomain );
65*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
66*48a54d36SAndroid Build Coastguard Worker
67*48a54d36SAndroid Build Coastguard Worker // If there isn't a trailing dot, add one because the mDNSResponder
68*48a54d36SAndroid Build Coastguard Worker // presents names with the trailing dot.
69*48a54d36SAndroid Build Coastguard Worker
70*48a54d36SAndroid Build Coastguard Worker if ( outDomain[ dlen - 1 ] != '.' )
71*48a54d36SAndroid Build Coastguard Worker {
72*48a54d36SAndroid Build Coastguard Worker outDomain[ dlen++ ] = '.';
73*48a54d36SAndroid Build Coastguard Worker outDomain[ dlen ] = '\0';
74*48a54d36SAndroid Build Coastguard Worker }
75*48a54d36SAndroid Build Coastguard Worker
76*48a54d36SAndroid Build Coastguard Worker // Canonicalize name by converting to lower case (keychain and some name servers are case sensitive)
77*48a54d36SAndroid Build Coastguard Worker
78*48a54d36SAndroid Build Coastguard Worker for ( i = 0; i < dlen; i++ )
79*48a54d36SAndroid Build Coastguard Worker {
80*48a54d36SAndroid Build Coastguard Worker outDomain[i] = (char) tolower( outDomain[i] ); // canonicalize -> lower case
81*48a54d36SAndroid Build Coastguard Worker }
82*48a54d36SAndroid Build Coastguard Worker
83*48a54d36SAndroid Build Coastguard Worker // attrs are reserved, so initialize to zeroes.
84*48a54d36SAndroid Build Coastguard Worker
85*48a54d36SAndroid Build Coastguard Worker ZeroMemory( &attrs, sizeof( attrs ) );
86*48a54d36SAndroid Build Coastguard Worker
87*48a54d36SAndroid Build Coastguard Worker // Get a handle to the Policy object on the local system
88*48a54d36SAndroid Build Coastguard Worker
89*48a54d36SAndroid Build Coastguard Worker res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle );
90*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
91*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
92*48a54d36SAndroid Build Coastguard Worker
93*48a54d36SAndroid Build Coastguard Worker // Get the encrypted data
94*48a54d36SAndroid Build Coastguard Worker
95*48a54d36SAndroid Build Coastguard Worker domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) );
96*48a54d36SAndroid Build Coastguard Worker require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr );
97*48a54d36SAndroid Build Coastguard Worker err = MakeLsaStringFromUTF8String( domainLSA, outDomain );
98*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
99*48a54d36SAndroid Build Coastguard Worker
100*48a54d36SAndroid Build Coastguard Worker // Retrieve the key
101*48a54d36SAndroid Build Coastguard Worker
102*48a54d36SAndroid Build Coastguard Worker res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA );
103*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
104*48a54d36SAndroid Build Coastguard Worker require_noerr_quiet( err, exit );
105*48a54d36SAndroid Build Coastguard Worker
106*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/4192119> Lsa secrets use a flat naming space. Therefore, we will prepend "$" to the keyname to
107*48a54d36SAndroid Build Coastguard Worker // make sure it doesn't conflict with a zone name.
108*48a54d36SAndroid Build Coastguard Worker // Strip off the "$" prefix.
109*48a54d36SAndroid Build Coastguard Worker
110*48a54d36SAndroid Build Coastguard Worker err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA );
111*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
112*48a54d36SAndroid Build Coastguard Worker require_action( outKey[0] == '$', exit, err = kUnknownErr );
113*48a54d36SAndroid Build Coastguard Worker memcpy( outKey, outKey + 1, strlen( outKey ) );
114*48a54d36SAndroid Build Coastguard Worker
115*48a54d36SAndroid Build Coastguard Worker // Retrieve the secret
116*48a54d36SAndroid Build Coastguard Worker
117*48a54d36SAndroid Build Coastguard Worker res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA );
118*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
119*48a54d36SAndroid Build Coastguard Worker require_noerr_quiet( err, exit );
120*48a54d36SAndroid Build Coastguard Worker
121*48a54d36SAndroid Build Coastguard Worker // Convert the secret to UTF8 string
122*48a54d36SAndroid Build Coastguard Worker
123*48a54d36SAndroid Build Coastguard Worker err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA );
124*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
125*48a54d36SAndroid Build Coastguard Worker
126*48a54d36SAndroid Build Coastguard Worker exit:
127*48a54d36SAndroid Build Coastguard Worker
128*48a54d36SAndroid Build Coastguard Worker if ( domainLSA != NULL )
129*48a54d36SAndroid Build Coastguard Worker {
130*48a54d36SAndroid Build Coastguard Worker if ( domainLSA->Buffer != NULL )
131*48a54d36SAndroid Build Coastguard Worker {
132*48a54d36SAndroid Build Coastguard Worker free( domainLSA->Buffer );
133*48a54d36SAndroid Build Coastguard Worker }
134*48a54d36SAndroid Build Coastguard Worker
135*48a54d36SAndroid Build Coastguard Worker free( domainLSA );
136*48a54d36SAndroid Build Coastguard Worker }
137*48a54d36SAndroid Build Coastguard Worker
138*48a54d36SAndroid Build Coastguard Worker if ( keyLSA != NULL )
139*48a54d36SAndroid Build Coastguard Worker {
140*48a54d36SAndroid Build Coastguard Worker LsaFreeMemory( keyLSA );
141*48a54d36SAndroid Build Coastguard Worker }
142*48a54d36SAndroid Build Coastguard Worker
143*48a54d36SAndroid Build Coastguard Worker if ( secretLSA != NULL )
144*48a54d36SAndroid Build Coastguard Worker {
145*48a54d36SAndroid Build Coastguard Worker LsaFreeMemory( secretLSA );
146*48a54d36SAndroid Build Coastguard Worker }
147*48a54d36SAndroid Build Coastguard Worker
148*48a54d36SAndroid Build Coastguard Worker if ( handle )
149*48a54d36SAndroid Build Coastguard Worker {
150*48a54d36SAndroid Build Coastguard Worker LsaClose( handle );
151*48a54d36SAndroid Build Coastguard Worker handle = NULL;
152*48a54d36SAndroid Build Coastguard Worker }
153*48a54d36SAndroid Build Coastguard Worker
154*48a54d36SAndroid Build Coastguard Worker return ( !err ) ? TRUE : FALSE;
155*48a54d36SAndroid Build Coastguard Worker }
156*48a54d36SAndroid Build Coastguard Worker
157*48a54d36SAndroid Build Coastguard Worker
158*48a54d36SAndroid Build Coastguard Worker mDNSBool
LsaSetSecret(const char * inDomain,const char * inKey,const char * inSecret)159*48a54d36SAndroid Build Coastguard Worker LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret )
160*48a54d36SAndroid Build Coastguard Worker {
161*48a54d36SAndroid Build Coastguard Worker size_t inDomainLength;
162*48a54d36SAndroid Build Coastguard Worker size_t inKeyLength;
163*48a54d36SAndroid Build Coastguard Worker char domain[ 1024 ];
164*48a54d36SAndroid Build Coastguard Worker char key[ 1024 ];
165*48a54d36SAndroid Build Coastguard Worker LSA_OBJECT_ATTRIBUTES attrs;
166*48a54d36SAndroid Build Coastguard Worker LSA_HANDLE handle = NULL;
167*48a54d36SAndroid Build Coastguard Worker NTSTATUS res;
168*48a54d36SAndroid Build Coastguard Worker LSA_UNICODE_STRING lucZoneName;
169*48a54d36SAndroid Build Coastguard Worker LSA_UNICODE_STRING lucKeyName;
170*48a54d36SAndroid Build Coastguard Worker LSA_UNICODE_STRING lucSecretName;
171*48a54d36SAndroid Build Coastguard Worker BOOL ok = TRUE;
172*48a54d36SAndroid Build Coastguard Worker OSStatus err;
173*48a54d36SAndroid Build Coastguard Worker
174*48a54d36SAndroid Build Coastguard Worker require_action( inDomain != NULL, exit, ok = FALSE );
175*48a54d36SAndroid Build Coastguard Worker require_action( inKey != NULL, exit, ok = FALSE );
176*48a54d36SAndroid Build Coastguard Worker require_action( inSecret != NULL, exit, ok = FALSE );
177*48a54d36SAndroid Build Coastguard Worker
178*48a54d36SAndroid Build Coastguard Worker // If there isn't a trailing dot, add one because the mDNSResponder
179*48a54d36SAndroid Build Coastguard Worker // presents names with the trailing dot.
180*48a54d36SAndroid Build Coastguard Worker
181*48a54d36SAndroid Build Coastguard Worker ZeroMemory( domain, sizeof( domain ) );
182*48a54d36SAndroid Build Coastguard Worker inDomainLength = strlen( inDomain );
183*48a54d36SAndroid Build Coastguard Worker require_action( inDomainLength > 0, exit, ok = FALSE );
184*48a54d36SAndroid Build Coastguard Worker err = strcpy_s( domain, sizeof( domain ) - 2, inDomain );
185*48a54d36SAndroid Build Coastguard Worker require_action( !err, exit, ok = FALSE );
186*48a54d36SAndroid Build Coastguard Worker
187*48a54d36SAndroid Build Coastguard Worker if ( domain[ inDomainLength - 1 ] != '.' )
188*48a54d36SAndroid Build Coastguard Worker {
189*48a54d36SAndroid Build Coastguard Worker domain[ inDomainLength++ ] = '.';
190*48a54d36SAndroid Build Coastguard Worker domain[ inDomainLength ] = '\0';
191*48a54d36SAndroid Build Coastguard Worker }
192*48a54d36SAndroid Build Coastguard Worker
193*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/4192119>
194*48a54d36SAndroid Build Coastguard Worker //
195*48a54d36SAndroid Build Coastguard Worker // Prepend "$" to the key name, so that there will
196*48a54d36SAndroid Build Coastguard Worker // be no conflict between the zone name and the key
197*48a54d36SAndroid Build Coastguard Worker // name
198*48a54d36SAndroid Build Coastguard Worker
199*48a54d36SAndroid Build Coastguard Worker ZeroMemory( key, sizeof( key ) );
200*48a54d36SAndroid Build Coastguard Worker inKeyLength = strlen( inKey );
201*48a54d36SAndroid Build Coastguard Worker require_action( inKeyLength > 0 , exit, ok = FALSE );
202*48a54d36SAndroid Build Coastguard Worker key[ 0 ] = '$';
203*48a54d36SAndroid Build Coastguard Worker err = strcpy_s( key + 1, sizeof( key ) - 3, inKey );
204*48a54d36SAndroid Build Coastguard Worker require_action( !err, exit, ok = FALSE );
205*48a54d36SAndroid Build Coastguard Worker inKeyLength++;
206*48a54d36SAndroid Build Coastguard Worker
207*48a54d36SAndroid Build Coastguard Worker if ( key[ inKeyLength - 1 ] != '.' )
208*48a54d36SAndroid Build Coastguard Worker {
209*48a54d36SAndroid Build Coastguard Worker key[ inKeyLength++ ] = '.';
210*48a54d36SAndroid Build Coastguard Worker key[ inKeyLength ] = '\0';
211*48a54d36SAndroid Build Coastguard Worker }
212*48a54d36SAndroid Build Coastguard Worker
213*48a54d36SAndroid Build Coastguard Worker // attrs are reserved, so initialize to zeroes.
214*48a54d36SAndroid Build Coastguard Worker
215*48a54d36SAndroid Build Coastguard Worker ZeroMemory( &attrs, sizeof( attrs ) );
216*48a54d36SAndroid Build Coastguard Worker
217*48a54d36SAndroid Build Coastguard Worker // Get a handle to the Policy object on the local system
218*48a54d36SAndroid Build Coastguard Worker
219*48a54d36SAndroid Build Coastguard Worker res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle );
220*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
221*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
222*48a54d36SAndroid Build Coastguard Worker
223*48a54d36SAndroid Build Coastguard Worker // Intializing PLSA_UNICODE_STRING structures
224*48a54d36SAndroid Build Coastguard Worker
225*48a54d36SAndroid Build Coastguard Worker err = MakeLsaStringFromUTF8String( &lucZoneName, domain );
226*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
227*48a54d36SAndroid Build Coastguard Worker
228*48a54d36SAndroid Build Coastguard Worker err = MakeLsaStringFromUTF8String( &lucKeyName, key );
229*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
230*48a54d36SAndroid Build Coastguard Worker
231*48a54d36SAndroid Build Coastguard Worker err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret );
232*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
233*48a54d36SAndroid Build Coastguard Worker
234*48a54d36SAndroid Build Coastguard Worker // Store the private data.
235*48a54d36SAndroid Build Coastguard Worker
236*48a54d36SAndroid Build Coastguard Worker res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName );
237*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
238*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
239*48a54d36SAndroid Build Coastguard Worker
240*48a54d36SAndroid Build Coastguard Worker res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName );
241*48a54d36SAndroid Build Coastguard Worker err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
242*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
243*48a54d36SAndroid Build Coastguard Worker
244*48a54d36SAndroid Build Coastguard Worker exit:
245*48a54d36SAndroid Build Coastguard Worker
246*48a54d36SAndroid Build Coastguard Worker if ( handle )
247*48a54d36SAndroid Build Coastguard Worker {
248*48a54d36SAndroid Build Coastguard Worker LsaClose( handle );
249*48a54d36SAndroid Build Coastguard Worker handle = NULL;
250*48a54d36SAndroid Build Coastguard Worker }
251*48a54d36SAndroid Build Coastguard Worker
252*48a54d36SAndroid Build Coastguard Worker return ok;
253*48a54d36SAndroid Build Coastguard Worker }
254*48a54d36SAndroid Build Coastguard Worker
255*48a54d36SAndroid Build Coastguard Worker
256*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
257*48a54d36SAndroid Build Coastguard Worker // MakeLsaStringFromUTF8String
258*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
259*48a54d36SAndroid Build Coastguard Worker
260*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus
MakeLsaStringFromUTF8String(PLSA_UNICODE_STRING output,const char * input)261*48a54d36SAndroid Build Coastguard Worker MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
262*48a54d36SAndroid Build Coastguard Worker {
263*48a54d36SAndroid Build Coastguard Worker int size;
264*48a54d36SAndroid Build Coastguard Worker OSStatus err;
265*48a54d36SAndroid Build Coastguard Worker
266*48a54d36SAndroid Build Coastguard Worker check( input );
267*48a54d36SAndroid Build Coastguard Worker check( output );
268*48a54d36SAndroid Build Coastguard Worker
269*48a54d36SAndroid Build Coastguard Worker output->Buffer = NULL;
270*48a54d36SAndroid Build Coastguard Worker
271*48a54d36SAndroid Build Coastguard Worker size = MultiByteToWideChar( CP_UTF8, 0, input, -1, NULL, 0 );
272*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size > 0, GetLastError(), kUnknownErr );
273*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
274*48a54d36SAndroid Build Coastguard Worker
275*48a54d36SAndroid Build Coastguard Worker output->Length = (USHORT)( size * sizeof( wchar_t ) );
276*48a54d36SAndroid Build Coastguard Worker output->Buffer = (PWCHAR) malloc( output->Length );
277*48a54d36SAndroid Build Coastguard Worker require_action( output->Buffer, exit, err = mStatus_NoMemoryErr );
278*48a54d36SAndroid Build Coastguard Worker size = MultiByteToWideChar( CP_UTF8, 0, input, -1, output->Buffer, size );
279*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size > 0, GetLastError(), kUnknownErr );
280*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
281*48a54d36SAndroid Build Coastguard Worker
282*48a54d36SAndroid Build Coastguard Worker // We're going to subtrace one wchar_t from the size, because we didn't
283*48a54d36SAndroid Build Coastguard Worker // include it when we encoded the string
284*48a54d36SAndroid Build Coastguard Worker
285*48a54d36SAndroid Build Coastguard Worker output->MaximumLength = output->Length;
286*48a54d36SAndroid Build Coastguard Worker output->Length -= sizeof( wchar_t );
287*48a54d36SAndroid Build Coastguard Worker
288*48a54d36SAndroid Build Coastguard Worker exit:
289*48a54d36SAndroid Build Coastguard Worker
290*48a54d36SAndroid Build Coastguard Worker if ( err && output->Buffer )
291*48a54d36SAndroid Build Coastguard Worker {
292*48a54d36SAndroid Build Coastguard Worker free( output->Buffer );
293*48a54d36SAndroid Build Coastguard Worker output->Buffer = NULL;
294*48a54d36SAndroid Build Coastguard Worker }
295*48a54d36SAndroid Build Coastguard Worker
296*48a54d36SAndroid Build Coastguard Worker return( err );
297*48a54d36SAndroid Build Coastguard Worker }
298*48a54d36SAndroid Build Coastguard Worker
299*48a54d36SAndroid Build Coastguard Worker
300*48a54d36SAndroid Build Coastguard Worker
301*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
302*48a54d36SAndroid Build Coastguard Worker // MakeUTF8StringFromLsaString
303*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
304*48a54d36SAndroid Build Coastguard Worker
305*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus
MakeUTF8StringFromLsaString(char * output,size_t len,PLSA_UNICODE_STRING input)306*48a54d36SAndroid Build Coastguard Worker MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input )
307*48a54d36SAndroid Build Coastguard Worker {
308*48a54d36SAndroid Build Coastguard Worker size_t size;
309*48a54d36SAndroid Build Coastguard Worker OSStatus err = kNoErr;
310*48a54d36SAndroid Build Coastguard Worker
311*48a54d36SAndroid Build Coastguard Worker // The Length field of this structure holds the number of bytes,
312*48a54d36SAndroid Build Coastguard Worker // but WideCharToMultiByte expects the number of wchar_t's. So
313*48a54d36SAndroid Build Coastguard Worker // we divide by sizeof(wchar_t) to get the correct number.
314*48a54d36SAndroid Build Coastguard Worker
315*48a54d36SAndroid Build Coastguard Worker size = (size_t) WideCharToMultiByte(CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), NULL, 0, NULL, NULL);
316*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size != 0, GetLastError(), kUnknownErr );
317*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
318*48a54d36SAndroid Build Coastguard Worker
319*48a54d36SAndroid Build Coastguard Worker // Ensure that we have enough space (Add one for trailing '\0')
320*48a54d36SAndroid Build Coastguard Worker
321*48a54d36SAndroid Build Coastguard Worker require_action( ( size + 1 ) <= len, exit, err = mStatus_NoMemoryErr );
322*48a54d36SAndroid Build Coastguard Worker
323*48a54d36SAndroid Build Coastguard Worker // Convert the string
324*48a54d36SAndroid Build Coastguard Worker
325*48a54d36SAndroid Build Coastguard Worker size = (size_t) WideCharToMultiByte( CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), output, (int) size, NULL, NULL);
326*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size != 0, GetLastError(), kUnknownErr );
327*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
328*48a54d36SAndroid Build Coastguard Worker
329*48a54d36SAndroid Build Coastguard Worker // have to add the trailing 0 because WideCharToMultiByte doesn't do it,
330*48a54d36SAndroid Build Coastguard Worker // although it does return the correct size
331*48a54d36SAndroid Build Coastguard Worker
332*48a54d36SAndroid Build Coastguard Worker output[size] = '\0';
333*48a54d36SAndroid Build Coastguard Worker
334*48a54d36SAndroid Build Coastguard Worker exit:
335*48a54d36SAndroid Build Coastguard Worker
336*48a54d36SAndroid Build Coastguard Worker return err;
337*48a54d36SAndroid Build Coastguard Worker }
338*48a54d36SAndroid Build Coastguard Worker
339