Ticket #1131: patch-src-osdep-unix-ckp_osx.c

File patch-src-osdep-unix-ckp_osx.c, 13.2 KB (added by bchesneau@…, 21 years ago)

patch ckp_osx in src/osdep/unix

Line 
1diff -ruP src/osdep/unix-orig/ckp_osx.c src/osdep/unix/ckp_osx.c
2--- src/osdep/unix-orig/ckp_osx.c       Thu Jan  1 01:00:00 1970
3+++ src/osdep/unix/ckp_osx.c    Wed Nov  5 00:18:14 2003
4@@ -0,0 +1,471 @@
5+/*
6+ * Program:    OS X check password
7+ *
8+ * Author:     Mark Crispin
9+ *             Networks and Distributed Computing
10+ *             Computing & Communications
11+ *             University of Washington
12+ *             Administration Building, AG-44
13+ *             Seattle, WA  98195
14+ *             Internet: MRC@CAC.Washington.EDU
15+ *
16+ * Modified by: Tom Brown
17+ *              tb000@maczipit.com
18+ *              (Modifications provided as-is, with no warranties, including the warranty
19+ *              of merchantability or fitness for a particular purpose.)
20+ *
21+ * Date:       1 August 1988
22+ * Last Edited:        October 26, 2003
23+ *
24+ * The IMAP toolkit provided in this Distribution is
25+ * Copyright 2000 University of Washington.
26+ * The full text of our legal notices is contained in the file called
27+ * CPYRIGHT, included with this Distribution.
28+ *
29+ * This file contains code adapted from Apple's sample code. The following notice applies
30+ * to the Apple-derived portion of this file.
31+ *
32+       Copyright:      © 2000-2001 by Apple Computer, Inc., all rights reserved.
33+
34+       IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
35+       consideration of your agreement to the following terms, and your use, installation,
36+       modification or redistribution of this Apple software constitutes acceptance of these
37+       terms.  If you do not agree with these terms, please do not use, install, modify or
38+       redistribute this Apple software.
39+       
40+       In consideration of your agreement to abide by the following terms, and subject to these
41+       terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
42+       this original Apple software (the "Apple Software"), to use, reproduce, modify and
43+       redistribute the Apple Software, with or without modifications, in source and/or binary
44+       forms; provided that if you redistribute the Apple Software in its entirety and without
45+       modifications, you must retain this notice and the following text and disclaimers in all
46+       such redistributions of the Apple Software.  Neither the name, trademarks, service marks
47+       or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
48+       the Apple Software without specific prior written permission from Apple. Except as expressly
49+       stated in this notice, no other rights or licenses, express or implied, are granted by Apple
50+       herein, including but not limited to any patent rights that may be infringed by your
51+       derivative works or by other works in which the Apple Software may be incorporated.
52+       
53+       The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO WARRANTIES,
54+       EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
55+       MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
56+       USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
57+       
58+       IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
59+       DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
60+       OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
61+       REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
62+       WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
63+       OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64+*/
65+#include <CoreServices/CoreServices.h>
66+#include <DirectoryService/DirServices.h>
67+#include <DirectoryService/DirServicesUtils.h>
68+#include <DirectoryService/DirServicesConst.h>
69+
70+  // Liberally borrowed from Apple's Open Directory SDK
71+
72+typedef enum {
73+       // NULL allocation errors
74+       kErrDataBufferAllocate                  = 1,
75+       kErrDataNodeAllocateBlock,
76+       kErrDataNodeAllocateString,
77+       kErrDataListAllocate,
78+       kErrBuildFromPath,
79+       kErrGetPathFromList,
80+       kErrBuildListFromNodes,
81+       kErrBuildListFromStrings,
82+       kErrBuildListFromStringsAlloc,
83+       kErrDataListCopyList,
84+       kErrAllocAttributeValueEntry,
85+
86+       // Error associations
87+       kErrOpenDirSrvc,
88+       kErrCloseDirSrvc,
89+       kErrDataListDeallocate,
90+       kErrDataBufferDeAllocate,
91+       kErrFindDirNodes,
92+       kErrOpenRecord,
93+       kErrCreateRecordAndOpen,
94+       kErrCloseRecord,
95+       kErrDeleteRecord,
96+       kErrDataNodeDeAllocate,
97+
98+       kErrDataBuffDealloc,
99+       kErrCreateRecord,
100+       kErrAddAttribute,
101+       kErrAddAttributeValue,
102+       kErrSetAttributeValue,
103+       kErrGetRecAttrValueByIndex,
104+       kErrGetDirNodeName,
105+       kErrOpenDirNode,
106+       kErrCloseDirNode,
107+       kErrGetRecordList,
108+
109+       kErrGetRecordEntry,
110+       kErrGetAttributeEntry,
111+       kErrGetAttributeValue,
112+       kErrDeallocAttributeValueEntry,
113+       kErrDoDirNodeAuth,
114+       kErrGetRecordNameFromEntry,
115+       kErrGetRecordTypeFromEntry,
116+       kErrGetRecordAttributeInfo,
117+       kErrGetRecordReferenceInfo,
118+       kErrGetDirNodeInfo,
119+
120+       kErrGetDirNodeCount,
121+       kErrGetDirNodeList,
122+       kErrRemoveAttributeValue,
123+       kErr,
124+
125+       kErrMemoryAlloc,
126+       kErrEmptyDataBuff,
127+       kErrEmptyDataParam,
128+       kErrBuffTooSmall,
129+       kErrMaxErrors,
130+       kUnknownErr = 0xFF
131+} eErrCodes;
132+
133+long SetUpAuthBuffs (   tDirReference dsRef, tDataBuffer **outAuthBuff,
134+                       unsigned long inAuthBuffSize,
135+                       tDataBuffer **outStepBuff,
136+                       unsigned long  inStepBuffSize,
137+                       tDataBuffer **outTypeBuff,
138+                        const char *inAuthMethod )
139+{
140+       long            error   = eDSNoErr;
141+       long            error2  = eDSNoErr;
142+
143+       if ( (outAuthBuff == nil) || (outStepBuff == nil) ||
144+                (outTypeBuff == nil) || (inAuthMethod == nil) )
145+       {
146+               return( kErrEmptyDataParam );
147+       }
148+
149+       *outAuthBuff = dsDataBufferAllocate( dsRef, inAuthBuffSize );
150+       if ( *outAuthBuff != nil )
151+       {
152+               *outStepBuff = dsDataBufferAllocate( dsRef, inStepBuffSize );
153+               if ( *outStepBuff != nil )
154+               {
155+                       *outTypeBuff = dsDataNodeAllocateString( dsRef, inAuthMethod );
156+                       if ( *outTypeBuff == nil )
157+                       {
158+                               error = kErrDataNodeAllocateString;
159+                       }
160+               }
161+               else
162+               {
163+                       error = kErrDataBufferAllocate;
164+               }
165+       }
166+       else
167+       {
168+               error = kErrDataBufferAllocate;
169+       }
170+
171+       if ( error != eDSNoErr )
172+       {
173+               if ( *outAuthBuff != nil )
174+               {
175+                       error2 = dsDataBufferDeAllocate( dsRef, *outAuthBuff );
176+               }
177+
178+               if ( *outStepBuff != nil )
179+               {
180+                       error2 = dsDataBufferDeAllocate( dsRef, *outStepBuff );
181+               }
182+
183+               if ( *outTypeBuff != nil )
184+               {
185+                       error2 = dsDataBufferDeAllocate( dsRef, *outTypeBuff );
186+               }
187+       }
188+
189+       return( error );
190+
191+} // SetUpAuthBuffs
192+
193+long FillAuthBuff ( tDataBuffer *inAuthBuff, unsigned long inCount, unsigned long inLen, void *inData, ... )
194+{
195+       long            error           = eDSNoErr;
196+       unsigned long   curr            = 0;
197+       unsigned long   buffSize        = 0;
198+       unsigned long   count           = inCount;
199+       unsigned long   len             = inLen;
200+       void            *data           = inData;
201+       bool            firstPass       = true;
202+       char            *p              = nil;
203+       va_list         args;
204+
205+       // If the buffer is nil, we have nowhere to put the data
206+       if ( inAuthBuff == nil )
207+       {
208+               return( kErrEmptyDataBuff );
209+       }
210+
211+       // If the buffer is nil, we have nowhere to put the data
212+       if ( inAuthBuff->fBufferData == nil )
213+       {
214+               return( kErrEmptyDataBuff );
215+       }
216+
217+       // Make sure we have data to copy
218+       if ( (inLen != 0) && (inData == nil) )
219+       {
220+               return( kErrEmptyDataParam );
221+       }
222+
223+       // Get buffer info
224+       p = inAuthBuff->fBufferData;
225+       buffSize = inAuthBuff->fBufferSize;
226+
227+       // Set up the arg list
228+       va_start( args, inLen );
229+
230+       while ( count-- > 0 )
231+       {
232+               if ( !firstPass )
233+               {
234+                       len = va_arg( args, unsigned long );
235+                       data = va_arg( args, void * );
236+               }
237+
238+               if ( (curr + len) > buffSize )
239+               {
240+                       // This is bad, lets bail
241+                       return( kErrBuffTooSmall );
242+               }
243+
244+               memcpy( &(p[ curr ]), &len, sizeof( long ) );
245+               curr += sizeof( long );
246+
247+               if ( len > 0 )
248+               {
249+                       memcpy( &(p[ curr ]), data, len );
250+                       curr += len;
251+               }
252+               firstPass = false;
253+       }
254+
255+       inAuthBuff->fBufferLength = curr;
256+
257+       return( error );
258+
259+} // FillAuthBuff
260+
261+
262+long DoClearTextAuth ( tDirReference dsRef, tDirNodeReference inNode, char *inName, char *inPasswd )
263+{
264+    long    error= eDSNoErr;
265+    long    error2= eDSNoErr;
266+    tDataBuffer   *pAuthBuff= nil;
267+    tDataBuffer   *pStepBuff= nil;
268+    tDataNode   *pAuthType= nil;
269+
270+    error = SetUpAuthBuffs( dsRef, &pAuthBuff, 2048, &pStepBuff, 2048, &pAuthType, kDSStdAuthNodeNativeClearTextOK );
271+    if ( error == eDSNoErr )
272+    {
273+        error = FillAuthBuff ( pAuthBuff, 2,
274+                                (long)strlen( inName ), inName,
275+                                (long)strlen( inPasswd ), inPasswd );
276+
277+        if ( error == eDSNoErr )
278+        {
279+            error = dsDoDirNodeAuth( inNode, pAuthType, true, pAuthBuff, pStepBuff, nil );
280+        }
281+           
282+        error2 = dsDataBufferDeAllocate( dsRef, pAuthBuff );
283+        error2 = dsDataBufferDeAllocate( dsRef, pStepBuff );
284+        error2 = dsDataBufferDeAllocate( dsRef, pAuthType );
285+    }
286+
287+    return( error );
288+
289+} // DoClearTextAuth
290+
291+static long OpenDirNode ( tDirReference dsRef, char *inNodeName, tDirNodeReference *outNodeRef )
292+{
293+       long        error               = eDSNoErr;
294+       long        error2              = eDSNoErr;
295+       tDataList   *pDataList  = nil;
296+
297+        pDataList = dsBuildFromPath( dsRef, inNodeName, "/" );
298+        if ( pDataList != nil )
299+        {
300+                error = dsOpenDirNode( dsRef, pDataList, outNodeRef );
301+                error2 = dsDataListDeallocate( dsRef, pDataList );
302+        }
303+        else
304+        {
305+                error = kErrBuildFromPath;
306+        }
307+
308+       return( error );
309+
310+} // OpenDirNode
311+
312+static long FindDirectoryNodes (    tDirReference dsRef,
313+                                    char *inNodeName,
314+                                    tDirPatternMatch inMatch,
315+                                    char **outNodeName)
316+{
317+       long                    error                   = eDSNoErr;
318+       long                    error2                  = eDSNoErr;
319+       bool                    done                    = false;
320+       unsigned long                   uiCount                 = 0;
321+       unsigned long                   uiIndex                 = 0;
322+       tDataList          *pNodeNameList       = nil;
323+       tDataList          *pDataList           = nil;
324+       char               *pNodeName           = nil;
325+        tDataBuffer         *buf;
326+
327+               if ( inNodeName != nil )
328+               {
329+                       pNodeNameList = dsBuildFromPath( dsRef, inNodeName, "/" );
330+                       if ( pNodeNameList == nil )
331+                       {
332+                               return( kErrDataNodeAllocateString );
333+                       }
334+               }
335+
336+                buf = dsDataBufferAllocate( dsRef, 1024);
337+               do {
338+                       error = dsFindDirNodes( dsRef, buf, pNodeNameList, inMatch, &uiCount, nil );
339+                       if ( error == eDSBufferTooSmall )
340+                       {
341+                               unsigned long buffSize = buf->fBufferSize;
342+                               dsDataBufferDeAllocate( dsRef, buf );
343+                               buf = nil;
344+                               buf = dsDataBufferAllocate( dsRef, buffSize * 2 );
345+                       }
346+               } while ( error == eDSBufferTooSmall );
347+               if ( error == eDSNoErr )
348+               {
349+
350+                       if ( uiCount != 0 )
351+                       {
352+                               pDataList = dsDataListAllocate( dsRef );
353+                               if ( pDataList != nil )
354+                               {
355+                                       for ( uiIndex = 1; (uiIndex <= uiCount) && (error == eDSNoErr); uiIndex++ )
356+                                       {
357+                                               error = dsGetDirNodeName( dsRef, buf, uiIndex, &pDataList );
358+                                               if ( error == eDSNoErr )
359+                                               {
360+                                                       pNodeName = dsGetPathFromList( dsRef, pDataList, "/" );
361+                                                       if ( pNodeName != nil )
362+                                                       {
363+
364+                                                               if ( (outNodeName != nil) && !done )
365+                                                               {
366+                                                                       *outNodeName = pNodeName;
367+                                                                       done = true;
368+                                                               }
369+                                                               else
370+                                                               {
371+                                                                       free( pNodeName );
372+                                                                       pNodeName = nil;
373+                                                               }
374+
375+                                                               error2 = dsDataListDeallocate( dsRef, pDataList );
376+                                                       }
377+                                                       else
378+                                                       {
379+                                                               error = kErrGetPathFromList;
380+                                                       }
381+                                               }
382+                                       }
383+                               }
384+                               else
385+                               {
386+                                       error = kErrDataListAllocate;
387+                               }
388+                       }
389+               }
390+
391+               if ( pNodeNameList != nil )
392+               {
393+                       error2 = dsDataListDeallocate( dsRef, pNodeNameList );
394+               }
395+
396+        dsDataBufferDeAllocate( dsRef, buf );
397+       return( error );
398+
399+} // FindDirectoryNodes
400+
401+static long MyOpenDirNode ( tDirReference dirRef,
402+                           tDirNodeReference *outNodeRef )
403+{
404+    long    siStatus           = noErr;
405+    char    *pNodeName         = nil;
406+   
407+    // siStatus = OpenDirectoryServices();
408+    if ( siStatus != noErr )
409+    {
410+            return( siStatus );
411+    }
412+   
413+    // Find and open local node
414+    siStatus = FindDirectoryNodes( dirRef, nil, eDSLocalNodeNames, &pNodeName );
415+    if ( siStatus == noErr )
416+    {
417+            siStatus = OpenDirNode( dirRef, pNodeName, outNodeRef );
418+   
419+            free( pNodeName );
420+            pNodeName = nil;
421+    }
422+   
423+    return siStatus;
424+}
425+
426+/* Check password
427+ * Accepts: login passwd struct
428+ *         password string
429+ *         argument count
430+ *         argument vector
431+ * Returns: passwd struct if password validated, NIL otherwise
432+ */
433+
434+struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
435+{
436+    if (pw->pw_passwd && pw->pw_passwd[0] && pw->pw_passwd[1])
437+    {
438+        long dirStatus = eDSNoErr;
439+        tDirNodeReference nodeRef = NULL;
440+        tDirReference dirRef = NULL;
441+       
442+        dirStatus = dsOpenDirService( &dirRef );
443+        if ( dirStatus == eDSNoErr )
444+        {
445+            dirStatus = MyOpenDirNode( dirRef, &nodeRef );
446+        }
447+       
448+        if (dirStatus == eDSNoErr)
449+        {
450+            dirStatus = DoClearTextAuth(dirRef, nodeRef, pw->pw_name, pass);
451+        }
452+       
453+        // Any error causes us to fail (including failure of authentication, above)
454+        if (dirStatus != eDSNoErr)
455+        {
456+            pw = NULL;
457+        }
458+       
459+        if (nodeRef)
460+        {
461+            dsCloseDirNode( nodeRef );
462+        }
463+       
464+        if ( dirRef != NULL )
465+        {
466+            dirStatus = dsCloseDirService( dirRef );
467+        }
468+       
469+        return pw;   
470+    }
471+    else
472+    {
473+        return NULL;
474+    }
475+}