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 |
---|