2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
27 #include <sys/param.h>
28 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <sys/ioctl.h>
38 #include <sys/dirent.h>
40 #include <DirectoryService/DirServices.h>
41 #include <DirectoryService/DirServicesConst.h>
42 #include <DirectoryService/DirServicesTypes.h>
43 #include <DirectoryService/DirServicesUtils.h>
45 // password server can store 511 characters + a terminator.
46 #define kMaxPassword 512
48 //-------------------------------------------------------------------------------------
50 //-------------------------------------------------------------------------------------
53 ds_getpasswd(const char *loginUser
, char *name
, int isroot
, int wasroot
, int changePassOnSelf
, char **old_clear
, char **new_clear
)
57 static char obuf
[kMaxPassword
];
58 static char nbuf
[kMaxPassword
];
59 char prompt
[MAXNAMLEN
+ 16];
61 printf("Changing password for %s.\n", name
);
67 if ( changePassOnSelf
)
69 strcpy( prompt
, "Old password:" );
73 snprintf( prompt
, sizeof(prompt
), "password for %s:", loginUser
);
76 p
= getpass( prompt
);
77 snprintf( obuf
, sizeof(obuf
), "%s", p
);
86 p
= getpass("New password:");
89 printf("Password unchanged.\n");
96 snprintf( nbuf
, sizeof(nbuf
), "%s", p
);
97 if (!strcmp(nbuf
, getpass("Retype new password:"))) break;
99 printf("Mismatch; try again, EOF to quit.\n");
108 //-------------------------------------------------------------------------------------
110 //-------------------------------------------------------------------------------------
113 ds_passwd(char *uname
, char *locn
)
115 tDirReference dsRef
= 0;
116 tDataBuffer
*tDataBuff
= NULL
;
117 tDirNodeReference nodeRef
= 0;
118 long status
= eDSNoErr
;
119 tContextData context
= NULL
;
120 unsigned long nodeCount
= 0;
121 unsigned long attrIndex
= 0;
122 tDataList
*nodeName
= NULL
;
123 tAttributeEntryPtr pAttrEntry
= NULL
;
124 tDataList
*pRecName
= NULL
;
125 tDataList
*pRecType
= NULL
;
126 tDataList
*pAttrType
= NULL
;
127 unsigned long recCount
= 0;
128 tRecordEntry
*pRecEntry
= NULL
;
129 tAttributeListRef attrListRef
= 0;
130 char *pUserLocation
= NULL
;
131 char *pUserName
= NULL
;
132 tAttributeValueListRef valueRef
= 0;
133 tAttributeValueEntry
*pValueEntry
= NULL
;
134 tDataList
*pUserNode
= NULL
;
135 tDirNodeReference userNodeRef
= 0;
136 tDataBuffer
*pStepBuff
= NULL
;
137 tDataNode
*pAuthType
= NULL
;
138 unsigned long uiCurr
= 0;
139 unsigned long uiLen
= 0;
140 char *old_clear
= NULL
;
141 char *new_clear
= NULL
;
144 char *loginUser
= NULL
;
145 int changePassOnSelf
= 1;
150 loginUser
= getlogin();
151 if ( loginUser
!= NULL
)
152 changePassOnSelf
= ( strcmp( loginUser
, uname
) == 0 );
154 status
= dsOpenDirService( &dsRef
);
155 if (status
!= eDSNoErr
)
160 if ( tDataBuff
== NULL
)
161 tDataBuff
= dsDataBufferAllocate( dsRef
, 4096 );
162 if (tDataBuff
== NULL
) break;
166 nodeName
= dsBuildFromPath( dsRef
, locn
, "/" );
167 if ( nodeName
== NULL
) break;
170 status
= dsFindDirNodes( dsRef
, tDataBuff
, nodeName
, eDSiExact
, &nodeCount
, &context
);
174 // find on search node
175 status
= dsFindDirNodes( dsRef
, tDataBuff
, NULL
, eDSSearchNodeName
, &nodeCount
, &context
);
178 if (status
!= eDSNoErr
) break;
179 if ( nodeCount
< 1 ) {
180 status
= eDSNodeNotFound
;
186 // we already tried SetPasswordAsRoot and it didn't work
187 // get the old (current) password and try again
197 ds_getpasswd( loginUser
, uname
, isroot
, wasroot
, changePassOnSelf
, &old_clear
, &new_clear
);
199 status
= dsGetDirNodeName( dsRef
, tDataBuff
, 1, &nodeName
);
200 if (status
!= eDSNoErr
) continue;
202 status
= dsOpenDirNode( dsRef
, nodeName
, &nodeRef
);
203 dsDataListDeallocate( dsRef
, nodeName
);
206 if (status
!= eDSNoErr
) continue;
208 pRecName
= dsBuildListFromStrings( dsRef
, uname
, NULL
);
209 pRecType
= dsBuildListFromStrings( dsRef
, kDSStdRecordTypeUsers
, NULL
);
210 pAttrType
= dsBuildListFromStrings( dsRef
, kDSNAttrMetaNodeLocation
, kDSNAttrRecordName
, NULL
);
213 status
= dsGetRecordList( nodeRef
, tDataBuff
, pRecName
, eDSExact
, pRecType
,
214 pAttrType
, 0, &recCount
, &context
);
215 if ( status
!= eDSNoErr
) break;
216 if ( recCount
== 0 ) {
217 status
= eDSAuthUnknownUser
;
221 status
= dsGetRecordEntry( nodeRef
, tDataBuff
, 1, &attrListRef
, &pRecEntry
);
222 if ( status
!= eDSNoErr
) break;
224 for ( attrIndex
= 1; (attrIndex
<= pRecEntry
->fRecordAttributeCount
) && (status
== eDSNoErr
); attrIndex
++ )
226 status
= dsGetAttributeEntry( nodeRef
, tDataBuff
, attrListRef
, attrIndex
, &valueRef
, &pAttrEntry
);
227 if ( status
== eDSNoErr
&& pAttrEntry
!= NULL
)
229 if ( strcmp( pAttrEntry
->fAttributeSignature
.fBufferData
, kDSNAttrMetaNodeLocation
) == 0 )
231 status
= dsGetAttributeValue( nodeRef
, tDataBuff
, 1, valueRef
, &pValueEntry
);
232 if ( status
== eDSNoErr
&& pValueEntry
!= NULL
)
234 pUserLocation
= (char *) calloc( pValueEntry
->fAttributeValueData
.fBufferLength
+ 1, sizeof(char) );
235 memcpy( pUserLocation
, pValueEntry
->fAttributeValueData
.fBufferData
, pValueEntry
->fAttributeValueData
.fBufferLength
);
239 if ( strcmp( pAttrEntry
->fAttributeSignature
.fBufferData
, kDSNAttrRecordName
) == 0 )
241 status
= dsGetAttributeValue( nodeRef
, tDataBuff
, 1, valueRef
, &pValueEntry
);
242 if ( status
== eDSNoErr
&& pValueEntry
!= NULL
)
244 pUserName
= (char *) calloc( pValueEntry
->fAttributeValueData
.fBufferLength
+ 1, sizeof(char) );
245 memcpy( pUserName
, pValueEntry
->fAttributeValueData
.fBufferData
, pValueEntry
->fAttributeValueData
.fBufferLength
);
249 if ( pValueEntry
!= NULL
)
250 dsDeallocAttributeValueEntry( dsRef
, pValueEntry
);
253 dsDeallocAttributeEntry( dsRef
, pAttrEntry
);
255 dsCloseAttributeValueList( valueRef
);
260 pUserNode
= dsBuildFromPath( dsRef
, pUserLocation
, "/" );
261 status
= dsOpenDirNode( dsRef
, pUserNode
, &userNodeRef
);
262 if ( status
!= eDSNoErr
) break;
264 pStepBuff
= dsDataBufferAllocate( dsRef
, 128 );
268 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthSetPasswdAsRoot
);
272 uiLen
= strlen( pUserName
);
273 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
274 uiCurr
+= sizeof( unsigned long );
275 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
279 uiLen
= strlen( new_clear
);
280 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
281 uiCurr
+= sizeof( unsigned long );
282 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
285 tDataBuff
->fBufferLength
= uiCurr
;
287 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
290 if ( changePassOnSelf
)
292 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthChangePasswd
);
296 uiLen
= strlen( pUserName
);
297 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
298 uiCurr
+= sizeof( unsigned long );
299 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
303 uiLen
= strlen( old_clear
);
304 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
305 uiCurr
+= sizeof( unsigned long );
306 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), old_clear
, uiLen
);
310 uiLen
= strlen( new_clear
);
311 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
312 uiCurr
+= sizeof( unsigned long );
313 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
316 tDataBuff
->fBufferLength
= uiCurr
;
318 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
322 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthSetPasswd
);
326 uiLen
= strlen( pUserName
);
327 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
328 uiCurr
+= sizeof( unsigned long );
329 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
333 uiLen
= strlen( new_clear
);
334 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
335 uiCurr
+= sizeof( unsigned long );
336 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
339 // Authenticator name
340 uiLen
= strlen( loginUser
);
341 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
342 uiCurr
+= sizeof( unsigned long );
343 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), loginUser
, uiLen
);
347 uiLen
= strlen( old_clear
);
348 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
349 uiCurr
+= sizeof( unsigned long );
350 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), old_clear
, uiLen
);
353 tDataBuff
->fBufferLength
= uiCurr
;
355 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
358 while ( isroot
== 1 && status
!= eDSNoErr
);
360 /* old_clear and new_clear are statics (don't call free) */
361 if (old_clear
!= NULL
) {
362 memset(old_clear
, 0, strlen(old_clear
));
364 if (new_clear
!= NULL
) {
365 memset(new_clear
, 0, strlen(new_clear
));
367 if (tDataBuff
!= NULL
) {
368 memset(tDataBuff
, 0, tDataBuff
->fBufferSize
);
369 dsDataBufferDeAllocate( dsRef
, tDataBuff
);
373 if (pStepBuff
!= NULL
) {
374 dsDataBufferDeAllocate( dsRef
, pStepBuff
);
377 if (pUserLocation
!= NULL
) {
379 pUserLocation
= NULL
;
381 if (pRecName
!= NULL
) {
382 dsDataListDeallocate( dsRef
, pRecName
);
386 if (pRecType
!= NULL
) {
387 dsDataListDeallocate( dsRef
, pRecType
);
391 if (pAttrType
!= NULL
) {
392 dsDataListDeallocate( dsRef
, pAttrType
);
397 dsCloseDirNode(nodeRef
);
401 dsCloseDirService(dsRef
);
405 if ( status
!= eDSNoErr
) {
407 fprintf(stderr
, "Sorry\n");