unsigned long fPID;
unsigned long fPort;
unsigned long fIPAddress;
+ mach_msg_audit_trailer_t fTail;
sObject obj[ 10 ];
char data[ 1 ];
} sComData;
unsigned long fPort;
sObject obj[ 10 ];
char fData[ kIPCMsgLen ];
- mach_msg_security_trailer_t fTail;
+ mach_msg_audit_trailer_t fTail; // this is the largest trailer struct
+ // we have the bucket large enough to receive it
} sIPCMsg;
typedef enum {
};
// end copied from SharedConsts.h
+int checkpw_internal( const struct passwd* pw, const char* password );
+
int checkpw( const char* userName, const char* password )
{
struct passwd* pw = NULL;
int status;
+
+ // Check username, NULL can crash in getpwnam
+ if (!userName)
+ return CHECKPW_UNKNOWNUSER;
pw = getpwnam( userName );
if (pw == NULL)
return CHECKPW_UNKNOWNUSER;
- status = checkpw_internal(userName, password, pw);
+ status = checkpw_internal(pw, password);
endpwent();
return status;
}
-int checkpw_internal( const char* userName, const char* password, const struct passwd* pw )
+int checkpw_internal( const struct passwd* pw, const char* password )
{
int siResult = CHECKPW_FAILURE;
kern_return_t result = err_none;
break;
}
+ // check password, NULL crashes crypt()
+ if (!password)
+ {
+ siResult = CHECKPW_BADPASSWORD;
+ break;
+ }
// Correct password hash
if (strcmp(crypt(password, pw->pw_passwd), pw->pw_passwd) == 0) {
siResult = CHECKPW_SUCCESS;
msg->obj[0].offset = offsetof(struct sComData, data);
// User Name
- len = strlen( userName );
+ len = strlen( pw->pw_name );
+ if (curr + len + sizeof(unsigned long) > kIPCMsgLen)
+ {
+ siResult = CHECKPW_FAILURE;
+ break;
+ }
memcpy( &(msg->fData[ curr ]), &len, sizeof( unsigned long ) );
curr += sizeof( unsigned long );
- memcpy( &(msg->fData[ curr ]), userName, len );
+ memcpy( &(msg->fData[ curr ]), pw->pw_name, len );
curr += len;
// Password
len = strlen( password );
+ if (curr + len + sizeof(unsigned long) > kIPCMsgLen)
+ {
+ siResult = CHECKPW_FAILURE;
+ break;
+ }
memcpy( &(msg->fData[ curr ]), &len, sizeof( unsigned long ) );
curr += sizeof ( unsigned long );
memcpy( &(msg->fData[ curr ]), password, len );
msg->obj[0].length = curr;
msg->fHeader.msgh_bits = MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND );
- msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_security_trailer_t );
+ msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_audit_trailer_t );
msg->fHeader.msgh_id = kCheckUserNameAndPassword;
msg->fHeader.msgh_remote_port = serverPort;
msg->fHeader.msgh_local_port = replyPort;
// get reply
memset( msg, 0, kIPCMsgLen );
- result = mach_msg( (mach_msg_header_t *)msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT,
+ result = mach_msg( (mach_msg_header_t *)msg,
+ MACH_RCV_MSG | MACH_RCV_TIMEOUT |
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0),
0, kIPCMsgSize, replyPort, 300 * 1000, MACH_PORT_NULL );
if ( result != MACH_MSG_SUCCESS ) {
msg = NULL;
}
+ // deallocate the serverPort
+ mach_port_deallocate( mach_task_self(), serverPort);
+
if ( replyPort != 0 )
- mach_port_deallocate( mach_task_self(), replyPort );
+ mach_port_destroy( mach_task_self(), replyPort );
return siResult;