Ticket #1089: patch-pop_pass.c

File patch-pop_pass.c, 4.5 KB (added by pguyot (Paul Guyot), 20 years ago)

patch for pop_pass.c (goes in files/) to add DirectoryService authentication (instead of crypt() which just doesn't work on Panther)

Line 
1--- popper/pop_pass.c.old       Thu Nov 13 12:11:01 2003
2+++ popper/pop_pass.c   Thu Nov 13 16:58:38 2003
3@@ -12,6 +12,9 @@
4  *
5  * Revisions:
6  *
7+ *     11/13/03  [pguyot]
8+ *             - Added DirectoryService authentication for MacOS X (required on
9+ *               10.3+).
10  *     01/16/03  [rcg]
11  *             - Renamed PASSWD macro to QPASSWD to avoid redefining
12  *               PASSWD in shadow.h.
13@@ -1156,6 +1159,143 @@
14 
15 #    endif /* AIX */
16 
17+
18+/*----------------------------------------------- DARWIN/MacOS X  */
19+#    ifdef DARWIN
20+
21+#      define DECLARED_AUTH_USER
22+
23+/*
24+ * MacOS X specific authentication using OpenDirectory (previously known
25+ * as DirectoryService).
26+ *
27+ * This should work with MacOS X 10.2 and higher (i.e. Darwin 6 and higher).
28+ * It's the only method, except PAM, on MacOS X 10.3 aka Panther (Darwin 7).
29+ * I don't know if this actually works on Darwin/x86.
30+ */
31+
32+#include <DirectoryService/DirServices.h>
33+#include <DirectoryService/DirServicesConst.h>
34+#include <DirectoryService/DirServicesTypes.h>
35+#include <DirectoryService/DirServicesUtils.h>
36+
37+static int
38+auth_user ( POP *p, struct passwd *pw )
39+{
40+    int                rslt            = POP_FAILURE;
41+    tDirReference      theDirRef       = NULL;
42+    tDirStatus         theDirErr       = eDSNoErr;
43+
44+       /*
45+        * Create a reference to the OpenDirectory service.
46+        */
47+       theDirErr = dsOpenDirService( &theDirRef );
48+       if (theDirErr == eDSNoErr)
49+       {
50+               /*
51+                * Build the path to the node.
52+                */
53+               tDataListPtr theNodePath = dsBuildFromPath( theDirRef, "/NetInfo/root/", "/" );
54+               
55+               if (theNodePath != NULL)
56+               {
57+                       /*
58+                        * Open the node.
59+                        */
60+                       tDirNodeReference theNodeRef = NULL;
61+                       theDirErr = dsOpenDirNode( theDirRef, theNodePath, &theNodeRef );
62+                       if (theDirErr == eDSNoErr)
63+                       {
64+                               /*
65+                                * Do the actual authentication work.
66+                                */
67+                               tDataNodePtr theAuthTypeToUse = NULL;
68+                               tDataBufferPtr theAuthDataBuffer = NULL;
69+                               tDataBufferPtr theAuthRespBuffer = NULL;
70+                               long theNameLength = strlen( p->user );
71+                               long thePassLength = strlen( p->pop_parm[1] );
72+                               long theBufferCursor = 0;
73+                               tContextData theContinueData = NULL;
74+                               
75+                               /* We allow clear text passwords */
76+                               theAuthTypeToUse =
77+                                       dsDataNodeAllocateString( theDirRef, kDSStdAuthNodeNativeClearTextOK );
78+                               
79+                           theAuthDataBuffer = dsDataBufferAllocate(
80+                                                                       theDirRef,
81+                                                                       sizeof(long) + theNameLength
82+                                                                       + sizeof(long) + thePassLength );
83+                               theAuthRespBuffer = dsDataBufferAllocate( theDirRef, 512 );
84+
85+                               /* Store data in the buffer */
86+                               /* the length, the name, the length, the password */
87+                               memcpy( &theAuthDataBuffer->fBufferData[theBufferCursor],
88+                                       &theNameLength, sizeof( theNameLength ) );
89+                               theBufferCursor += sizeof( theNameLength );
90+                               memcpy( &theAuthDataBuffer->fBufferData[theBufferCursor],
91+                                       p->user, theNameLength );
92+                               theBufferCursor += theNameLength;
93+                               memcpy( &theAuthDataBuffer->fBufferData[theBufferCursor],
94+                                       &thePassLength, sizeof( thePassLength ) );
95+                               theBufferCursor += sizeof( thePassLength );
96+                               memcpy( &theAuthDataBuffer->fBufferData[theBufferCursor],
97+                                       p->pop_parm[1], thePassLength );
98+                               theAuthDataBuffer->fBufferLength = theBufferCursor + thePassLength;
99+
100+                               if (dsDoDirNodeAuth(
101+                                               theNodeRef,
102+                                               theAuthTypeToUse,
103+                                               1 /* true */,
104+                                               theAuthDataBuffer,
105+                                               theAuthRespBuffer,
106+                                               &theContinueData ) == eDSNoErr)
107+                               {
108+                                       rslt = POP_SUCCESS;
109+                               } else {
110+                                       pop_log ( p, POP_NOTICE, HERE, "Authentication failed for user %s", p->user );
111+                               }
112+                               
113+                               /* clean up */
114+                               (void) dsDataBufferDeAllocate( theDirRef, theAuthDataBuffer );
115+                               (void) dsDataBufferDeAllocate( theDirRef, theAuthRespBuffer );
116+                               (void) dsDataNodeDeAllocate( theDirRef, theAuthTypeToUse );
117+                       }
118+                       
119+                       if (theNodeRef != NULL)
120+                       {
121+                               (void) dsCloseDirNode( theNodeRef );
122+                       }
123+                       
124+                       dsDataListDeallocate( theDirRef, theNodePath );
125+                       free( theNodePath );
126+               }
127+       }
128+       
129+       /*
130+        * Clean up.
131+        */
132+       if (theDirRef != NULL)
133+       {
134+               (void) dsCloseDirService( theDirRef );
135+       }
136+
137+       if (rslt != POP_SUCCESS)
138+       {
139+               if (theDirErr != eDSNoErr)
140+               {
141+                       pop_log( p, POP_NOTICE, HERE,
142+                                       "An error occurred with OpenDirectory authentication for user %s (%i)",
143+                                       p->user, theDirErr );
144+               }
145+               
146+               sleep  ( SLEEP_SECONDS );
147+               pop_msg ( p, POP_FAILURE, HERE, ERRMSG_PW, p->user );
148+       }
149+
150+    return rslt;
151+}
152+
153+#    endif /* DARWIN/MacOS X */
154 
155 /*----------------------------------------------- generic AUTH_USER */
156 #    ifndef DECLARED_AUTH_USER