2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 #include <sys/param.h>
29 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <sys/ioctl.h>
39 #include <sys/dirent.h>
41 #include <DirectoryService/DirServices.h>
42 #include <DirectoryService/DirServicesConst.h>
43 #include <DirectoryService/DirServicesTypes.h>
44 #include <DirectoryService/DirServicesUtils.h>
46 // password server can store 511 characters + a terminator.
47 #define kMaxPassword 512
49 //-------------------------------------------------------------------------------------
51 //-------------------------------------------------------------------------------------
54 ds_getpasswd(const char *loginUser
, char *name
, int isroot
, int wasroot
, int changePassOnSelf
, char **old_clear
, char **new_clear
)
58 static char obuf
[kMaxPassword
];
59 static char nbuf
[kMaxPassword
];
60 char prompt
[MAXNAMLEN
+ 16];
62 printf("Changing password for %s.\n", name
);
68 if ( changePassOnSelf
)
70 strcpy( prompt
, "Old password:" );
74 snprintf( prompt
, sizeof(prompt
), "password for %s:", loginUser
);
77 p
= getpass( prompt
);
78 snprintf( obuf
, sizeof(obuf
), "%s", p
);
87 p
= getpass("New password:");
90 printf("Password unchanged.\n");
97 snprintf( nbuf
, sizeof(nbuf
), "%s", p
);
98 if (!strcmp(nbuf
, getpass("Retype new password:"))) break;
100 printf("Mismatch; try again, EOF to quit.\n");
109 //-------------------------------------------------------------------------------------
111 //-------------------------------------------------------------------------------------
114 ds_passwd(char *uname
, char *locn
)
116 tDirReference dsRef
= 0;
117 tDataBuffer
*tDataBuff
= NULL
;
118 tDirNodeReference nodeRef
= 0;
119 long status
= eDSNoErr
;
120 tContextData context
= NULL
;
121 unsigned long nodeCount
= 0;
122 unsigned long attrIndex
= 0;
123 tDataList
*nodeName
= NULL
;
124 tAttributeEntryPtr pAttrEntry
= NULL
;
125 tDataList
*pRecName
= NULL
;
126 tDataList
*pRecType
= NULL
;
127 tDataList
*pAttrType
= NULL
;
128 unsigned long recCount
= 0;
129 tRecordEntry
*pRecEntry
= NULL
;
130 tAttributeListRef attrListRef
= 0;
131 char *pUserLocation
= NULL
;
132 char *pUserName
= NULL
;
133 tAttributeValueListRef valueRef
= 0;
134 tAttributeValueEntry
*pValueEntry
= NULL
;
135 tDataList
*pUserNode
= NULL
;
136 tDirNodeReference userNodeRef
= 0;
137 tDataBuffer
*pStepBuff
= NULL
;
138 tDataNode
*pAuthType
= NULL
;
139 unsigned long uiCurr
= 0;
140 unsigned long uiLen
= 0;
141 char *old_clear
= NULL
;
142 char *new_clear
= NULL
;
145 char *loginUser
= NULL
;
146 int changePassOnSelf
= 1;
151 loginUser
= getlogin();
152 if ( loginUser
!= NULL
)
153 changePassOnSelf
= ( strcmp( loginUser
, uname
) == 0 );
155 status
= dsOpenDirService( &dsRef
);
156 if (status
!= eDSNoErr
)
161 if ( tDataBuff
== NULL
)
162 tDataBuff
= dsDataBufferAllocate( dsRef
, 4096 );
163 if (tDataBuff
== NULL
) break;
167 nodeName
= dsBuildFromPath( dsRef
, locn
, "/" );
168 if ( nodeName
== NULL
) break;
171 status
= dsFindDirNodes( dsRef
, tDataBuff
, nodeName
, eDSiExact
, &nodeCount
, &context
);
175 // find on search node
176 status
= dsFindDirNodes( dsRef
, tDataBuff
, NULL
, eDSSearchNodeName
, &nodeCount
, &context
);
179 if (status
!= eDSNoErr
) break;
180 if ( nodeCount
< 1 ) {
181 status
= eDSNodeNotFound
;
187 // we already tried SetPasswordAsRoot and it didn't work
188 // get the old (current) password and try again
198 ds_getpasswd( loginUser
, uname
, isroot
, wasroot
, changePassOnSelf
, &old_clear
, &new_clear
);
200 status
= dsGetDirNodeName( dsRef
, tDataBuff
, 1, &nodeName
);
201 if (status
!= eDSNoErr
) continue;
203 status
= dsOpenDirNode( dsRef
, nodeName
, &nodeRef
);
204 dsDataListDeallocate( dsRef
, nodeName
);
207 if (status
!= eDSNoErr
) continue;
209 pRecName
= dsBuildListFromStrings( dsRef
, uname
, NULL
);
210 pRecType
= dsBuildListFromStrings( dsRef
, kDSStdRecordTypeUsers
, NULL
);
211 pAttrType
= dsBuildListFromStrings( dsRef
, kDSNAttrMetaNodeLocation
, kDSNAttrRecordName
, NULL
);
214 status
= dsGetRecordList( nodeRef
, tDataBuff
, pRecName
, eDSExact
, pRecType
,
215 pAttrType
, 0, &recCount
, &context
);
216 if ( status
!= eDSNoErr
) break;
217 if ( recCount
== 0 ) {
218 status
= eDSAuthUnknownUser
;
222 status
= dsGetRecordEntry( nodeRef
, tDataBuff
, 1, &attrListRef
, &pRecEntry
);
223 if ( status
!= eDSNoErr
) break;
225 for ( attrIndex
= 1; (attrIndex
<= pRecEntry
->fRecordAttributeCount
) && (status
== eDSNoErr
); attrIndex
++ )
227 status
= dsGetAttributeEntry( nodeRef
, tDataBuff
, attrListRef
, attrIndex
, &valueRef
, &pAttrEntry
);
228 if ( status
== eDSNoErr
&& pAttrEntry
!= NULL
)
230 if ( strcmp( pAttrEntry
->fAttributeSignature
.fBufferData
, kDSNAttrMetaNodeLocation
) == 0 )
232 status
= dsGetAttributeValue( nodeRef
, tDataBuff
, 1, valueRef
, &pValueEntry
);
233 if ( status
== eDSNoErr
&& pValueEntry
!= NULL
)
235 pUserLocation
= (char *) calloc( pValueEntry
->fAttributeValueData
.fBufferLength
+ 1, sizeof(char) );
236 memcpy( pUserLocation
, pValueEntry
->fAttributeValueData
.fBufferData
, pValueEntry
->fAttributeValueData
.fBufferLength
);
240 if ( strcmp( pAttrEntry
->fAttributeSignature
.fBufferData
, kDSNAttrRecordName
) == 0 )
242 status
= dsGetAttributeValue( nodeRef
, tDataBuff
, 1, valueRef
, &pValueEntry
);
243 if ( status
== eDSNoErr
&& pValueEntry
!= NULL
)
245 pUserName
= (char *) calloc( pValueEntry
->fAttributeValueData
.fBufferLength
+ 1, sizeof(char) );
246 memcpy( pUserName
, pValueEntry
->fAttributeValueData
.fBufferData
, pValueEntry
->fAttributeValueData
.fBufferLength
);
250 if ( pValueEntry
!= NULL
)
251 dsDeallocAttributeValueEntry( dsRef
, pValueEntry
);
254 dsDeallocAttributeEntry( dsRef
, pAttrEntry
);
256 dsCloseAttributeValueList( valueRef
);
261 pUserNode
= dsBuildFromPath( dsRef
, pUserLocation
, "/" );
262 status
= dsOpenDirNode( dsRef
, pUserNode
, &userNodeRef
);
263 if ( status
!= eDSNoErr
) break;
265 pStepBuff
= dsDataBufferAllocate( dsRef
, 128 );
269 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthSetPasswdAsRoot
);
273 uiLen
= strlen( pUserName
);
274 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
275 uiCurr
+= sizeof( unsigned long );
276 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
280 uiLen
= strlen( new_clear
);
281 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
282 uiCurr
+= sizeof( unsigned long );
283 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
286 tDataBuff
->fBufferLength
= uiCurr
;
288 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
291 if ( changePassOnSelf
)
293 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthChangePasswd
);
297 uiLen
= strlen( pUserName
);
298 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
299 uiCurr
+= sizeof( unsigned long );
300 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
304 uiLen
= strlen( old_clear
);
305 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
306 uiCurr
+= sizeof( unsigned long );
307 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), old_clear
, uiLen
);
311 uiLen
= strlen( new_clear
);
312 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
313 uiCurr
+= sizeof( unsigned long );
314 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
317 tDataBuff
->fBufferLength
= uiCurr
;
319 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
323 pAuthType
= dsDataNodeAllocateString( dsRef
, kDSStdAuthSetPasswd
);
327 uiLen
= strlen( pUserName
);
328 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
329 uiCurr
+= sizeof( unsigned long );
330 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), pUserName
, uiLen
);
334 uiLen
= strlen( new_clear
);
335 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
336 uiCurr
+= sizeof( unsigned long );
337 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), new_clear
, uiLen
);
340 // Authenticator name
341 uiLen
= strlen( loginUser
);
342 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
343 uiCurr
+= sizeof( unsigned long );
344 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), loginUser
, uiLen
);
348 uiLen
= strlen( old_clear
);
349 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), &uiLen
, sizeof( unsigned long ) );
350 uiCurr
+= sizeof( unsigned long );
351 memcpy( &(tDataBuff
->fBufferData
[ uiCurr
]), old_clear
, uiLen
);
354 tDataBuff
->fBufferLength
= uiCurr
;
356 status
= dsDoDirNodeAuth( userNodeRef
, pAuthType
, 1, tDataBuff
, pStepBuff
, NULL
);
359 while ( isroot
== 1 && status
!= eDSNoErr
);
361 /* old_clear and new_clear are statics (don't call free) */
362 if (old_clear
!= NULL
) {
363 memset(old_clear
, 0, strlen(old_clear
));
365 if (new_clear
!= NULL
) {
366 memset(new_clear
, 0, strlen(new_clear
));
368 if (tDataBuff
!= NULL
) {
369 memset(tDataBuff
, 0, tDataBuff
->fBufferSize
);
370 dsDataBufferDeAllocate( dsRef
, tDataBuff
);
374 if (pStepBuff
!= NULL
) {
375 dsDataBufferDeAllocate( dsRef
, pStepBuff
);
378 if (pUserLocation
!= NULL
) {
380 pUserLocation
= NULL
;
382 if (pRecName
!= NULL
) {
383 dsDataListDeallocate( dsRef
, pRecName
);
387 if (pRecType
!= NULL
) {
388 dsDataListDeallocate( dsRef
, pRecType
);
392 if (pAttrType
!= NULL
) {
393 dsDataListDeallocate( dsRef
, pAttrType
);
398 dsCloseDirNode(nodeRef
);
402 dsCloseDirService(dsRef
);
406 if ( status
!= eDSNoErr
) {
408 fprintf(stderr
, "Sorry\n");