📄 pgpldap.c
字号:
}
else /* Timeout */
{
*messageType = kPGPldapType_None;
break;
}
endTime = PGPGetTime();
tv.tv_sec -= ( endTime - startTime );
}
}
if( found )
{
if( *messageType != kPGPldapResponse_SearchEntry )
{
err = pgpLDAPGetMessageErrno( pgpLDAP, lastResult ); CKERR;
}
else
{
/*
* This is a pretty rare case, where we called PGPldapGetResult
* after doing a search, but didn't get the search result (yet).
* Since we don't have the LDAPResult, we can't fill in the
* PGPldapContext result fields. Since there technically wasn't
* an error, we'll just say that everything went fine, but
* *messageType will indicate that we didn't find the search
* result.
*/
pgpLDAP->result = kPGPldapResult_Success;
if( IsntNull( pgpLDAP->matched ) )
(void) PGPFreeData( pgpLDAP->matched );
pgpLDAP->matched = NULL;
if( IsntNull( pgpLDAP->message ) )
(void) PGPFreeData( pgpLDAP->message );
pgpLDAP->message = NULL;
}
}
else
{
/* Timeout */
pgpLDAP->result = kPGPldapResult_Timeout;
if( IsntNull( pgpLDAP->matched ) )
(void) PGPFreeData( pgpLDAP->matched );
pgpLDAP->matched = NULL;
if( IsntNull( pgpLDAP->message ) )
(void) PGPFreeData( pgpLDAP->message );
pgpLDAP->message = NULL;
}
goto done;
error:
*messageType = kPGPldapType_None;
done:
return err;
}
PGPError
PGPldapAbandon(
PGPldapContextRef pgpLDAP,
PGPldapMessageID messageID )
{
PGPError err = kPGPError_NoErr;
PGPberElementRef ber = kInvalidPGPberElementRef;
err = pgpNewBERElement( pgpLDAP->memMgr, &ber ); CKERR;
err = PGPberAppend( ber, "{iti}",
++( pgpLDAP->nextMessageID ),
kPGPldapRequest_Abandon,
messageID ); CKERR;
err = pgpLDAPSend( pgpLDAP, ber ); CKERR;
error:
if( PGPberElementRefIsValid( ber ) )
(void) PGPFreeBERElement( ber );
return err;
}
PGPError
PGPldapGetMessageID(
PGPldapContextRef pgpLDAP,
PGPldapMessageRef result,
PGPldapMessageID * messageID )
{
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidateLDAPMessageRef( result );
PGPValidatePtr( messageID );
(void) pgpLDAP;
*messageID = result->messageID;
return kPGPError_NoErr;
}
PGPError
PGPldapSearchSync(
PGPldapContextRef pgpLDAP,
char * base,
PGPldapScope scope,
char * filter,
char * attrs[],
PGPBoolean attrsOnly,
PGPldapMessageRef resultMessage )
{
return PGPldapSearchSyncTimeout( pgpLDAP, base, scope, filter, attrs,
attrsOnly, NULL, resultMessage );
}
PGPError
PGPldapSearchSyncTimeout(
PGPldapContextRef pgpLDAP,
char * base,
PGPldapScope scope,
char * filter,
char * attrs[],
PGPBoolean attrsOnly,
PGPSocketsTimeValue * tv,
PGPldapMessageRef resultMessage )
{
PGPError err = kPGPError_NoErr;
PGPldapMessageID messageID = kInvalidPGPldapMessageID;
PGPldapType messageType = kPGPldapType_None;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidatePtr( filter );
PGPValidateLDAPMessageRef( resultMessage );
err = PGPldapSearch( pgpLDAP, base, scope, filter, attrs, attrsOnly,
&messageID ); CKERR;
err = PGPldapGetResult( pgpLDAP, messageID, TRUE, tv, resultMessage,
&messageType ); CKERR;
error:
return( err ? err : PGPldapResultToError( pgpLDAP, pgpLDAP->result ) );
}
static PGPError
pgpLDAPGetFilterType(
char * filter,
PGPldapFilter * filterType )
{
PGPUInt32 i = 0;
PGPUInt32 j = 0;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( filter );
PGPValidatePtr( filterType );
/* filter[0] should be '(' */
if( filter[0] != '(' )
{
err = kPGPError_BadParams;
goto error;
}
switch( filter[1] )
{
case '&':
*filterType = kPGPldapFilter_And;
break;
case '|':
*filterType = kPGPldapFilter_Or;
break;
case '!':
*filterType = kPGPldapFilter_Not;
break;
default:
for( i = 0;
( filter[i] != '=' ) && ( filter[i] != '<' ) &&
( filter[i] != '>' ) && ( filter[i] != '~' ) &&
( filter[i] != '\0');
i++ )
; /* NULL */
if( filter[i] == '\0' )
{
err = kPGPError_BadParams;
goto error;
}
switch( filter[i] )
{
case '=':
if( ( filter[i+1] == '*' ) && ( filter[i+2] == ')' ) )
{
*filterType = kPGPldapFilter_Present;
break; /* out of the switch(...) */
}
for( j = i + 1;
( filter[j] != ')' ) &&
( filter[j] != '\0');
j++ )
{
if( filter[j] == '*' )
{
*filterType = kPGPldapFilter_Substrings;
break; /* out of the for(...) */
}
}
if( *filterType != kPGPldapFilter_Substrings )
*filterType = kPGPldapFilter_Equal;
break;
case '<':
if( filter[i+1] != '=' )
{
err = kPGPError_BadParams;
goto error;
}
*filterType = kPGPldapFilter_LE;
break;
case '>':
if( filter[i+1] != '=' )
{
err = kPGPError_BadParams;
goto error;
}
*filterType = kPGPldapFilter_GE;
break;
case '~':
if( filter[i+1] != '=' )
{
err = kPGPError_BadParams;
goto error;
}
*filterType = kPGPldapFilter_Approx;
break;
default:
err = kPGPError_BadParams;
goto error;
}
}
error:
return err;
}
PGPError
pgpLDAPGetSubstring(
char * value,
char * substring,
PGPldapSubstring * substringType,
PGPSize * inc )
{
PGPBoolean start = FALSE;
PGPBoolean end = FALSE;
PGPUInt32 i = 0;
PGPUInt32 j = 0;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( value );
PGPValidatePtr( substring );
PGPValidatePtr( substringType );
PGPValidatePtr( inc );
if( value[0] == '*' )
{
start = TRUE;
value++;
}
for( i = 0, j = 0; ( value[j] != '*' ) && ( value[j] != '\0' ); i++, j++ )
{
if( value[j] == '\\' )
j++;
substring[i] = value[j];
}
substring[i] = '\0';
*inc = j;
if( value[j] == '*' )
end = TRUE;
/*
* If we didn't find any *'s in the value, we should assume that
* we've already found them all in previous calls to
* pgpLDAPGetSubstrings, and this is just the end of value, as in:
*
* "*string1*string2"
*
* In which case the first call would have found
* "string1", kPGPldapSubstring_Any,
* and the second call would have found
* "string2", kPGPldapSubstring_Final
*/
if( start && end )
*substringType = kPGPldapSubstring_Any;
else if( end )
*substringType = kPGPldapSubstring_Initial;
else
*substringType = kPGPldapSubstring_Final;
return err;
}
PGPError
pgpLDAPGetSubfilter(
char * filter,
char * subfilter )
{
PGPUInt32 i = 0;
PGPUInt32 j = 0;
PGPUInt32 parens = 0;
PGPValidatePtr( filter );
PGPValidatePtr( subfilter );
/*
* filter is of the form (...)(...)(...)...
* All we really need to do is copy everything in the first set of (...)
* to subfilter (including the parens).
*/
for( i = 0, j = 0; filter[i] != '\0'; i++, j++ )
{
subfilter[j] = filter[i];
if( filter[i] == '(' )
parens++;
if( filter[i] == ')' )
parens--;
if( filter[i] == ')' && parens == 0 )
break;
}
subfilter[j] = ')';
subfilter[j+1] = '\0';
return kPGPError_NoErr;
}
PGPError
pgpLDAPAddFilter(
PGPldapContextRef pgpLDAP,
PGPberElementRef ber,
char * inFilter )
{
PGPError err = kPGPError_NoErr;
PGPUInt32 i = 0;
PGPUInt32 j = 0;
char * subfilter = NULL;
char * filter = NULL;
PGPldapFilter filterType = kPGPldapFilter_None;
char * attr = NULL;
char * value = NULL;
char * substring = NULL;
PGPSize length = 0;
PGPSize offset = 0;
PGPSize valueIndex = 0;
PGPSize valueInc = 0;
PGPldapSubstring substringType = kPGPldapSubstring_None;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidateBERElementRef( ber );
PGPValidatePtr( inFilter );
/*
* A Filter looks like this:
* Filter ::=
* CHOICE {
* and [0] SET OF Filter,
* or [1] SET OF Filter,
* not [2] Filter,
* equalityMatch [3] AttributeValueAssertion,
* substrings [4] SubstringFilter,
* greaterOrEqual [5] AttributeValueAssertion,
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,
* approxMatch [8] AttributeValueAssertion
* }
* Note: tags in a choice are always explicit
*/
length = strlen( (char *)inFilter );
length++;
if( ( inFilter[0] != '(' ) && ( inFilter[length-2] !=')' ) )
length += 2;
filter = PGPNewData( pgpLDAP->memMgr, length, kPGPMemoryMgrFlags_Clear );
if( IsNull( filter ) )
goto error;
if( ( inFilter[0] != '(' ) && ( inFilter[length-2] !=')' ) )
{
filter[0] = '(';
pgpCopyMemory( inFilter, filter + 1, length - 3 );
filter[length-2] = ')';
filter[length-1] = '\0';
}
else
pgpCopyMemory( inFilter, filter, length );
attr = PGPNewData( pgpLDAP->memMgr, length, kPGPMemoryMgrFlags_Clear );
if( IsNull( attr ) )
goto error;
substring = PGPNewData( pgpLDAP->memMgr, length, kPGPMemoryMgrFlags_Clear );
if( IsNull( substring ) )
goto error;
subfilter = PGPNewData( pgpLDAP->memMgr, length, kPGPMemoryMgrFlags_Clear );
if( IsNull( subfilter ) )
goto error;
value = PGPNewData( pgpLDAP->memMgr, length, kPGPMemoryMgrFlags_Clear );
if( IsNull( value ) )
goto error;
err = pgpLDAPGetFilterType( filter, &filterType );
if( IsPGPError( err ) )
goto error;
switch( filterType )
{
case kPGPldapFilter_And:
case kPGPldapFilter_Or:
/*
* Both kPGPldapFilter_And and kPGPldapFilter_Or append
* a "SET OF Filter" to the ber
*/
/* filter[length-1] is NULL, filter[length-2] is ')' */
filter[length - 2] = '\0';
offset = 2; /* skip the "(&" or "(|" */
err = PGPberAppend( ber, "t[", filterType ); CKERR;
while( offset < ( length - 2 ) )
{
err = pgpLDAPGetSubfilter( filter + offset, subfilter ); CKERR;
offset += strlen( (char *)subfilter );
err = pgpLDAPAddFilter( pgpLDAP, ber, subfilter ); CKERR;
}
err = PGPberAppend( ber, "]" ); CKERR;
break;
case kPGPldapFilter_Not:
err = PGPberAppend( ber, "t{", filterType ); CKERR;
filter[length - 2] = '\0';
err = pgpLDAPAddFilter( pgpLDAP, ber, filter + 2 ); CKERR;
err = PGPberAppend( ber, "}" ); CKERR;
break;
case kPGPldapFilter_Equal:
case kPGPldapFilter_GE:
case kPGPldapFilter_LE:
case kPGPldapFilter_Approx:
/* Append an "AttributeTypeAssertion" to the ber */
for( i = 1, j = 0;
( filter[i] != '=' ) && ( filter[i] != '<' ) &&
( filter[i] != '>' ) && ( filter[i] != '~' );
i++, j++ )
{
attr[j] = filter[i];
}
attr[j] = '\0';
if( filter[i] != '=' )
i++;
for( i++, j = 0; filter[i] != ')'; i++, j++ )
value[j] = filter[i];
value[j] = '\0';
err = PGPberAppend( ber, "t{ss}",
filterType,
attr,
value ); CKERR;
break;
case kPGPldapFilter_Substrings:
/* filter: "(attr=<value>)" */
for( i = 1; filter[i] != '='; i++ )
attr[i-1] = filter[i];
attr[i-1] = '\0';
/* i points to the '=' */
i++;
for( j = i; filter[j] != ')'; j++ )
value[j-i] = filter[j];
value[j-i] = '\0';
err = PGPberAppend( ber, "t{s{",
kPGPldapFilter_Substrings,
attr ); CKERR;
while( valueIndex < strlen( (char *)value ) )
{
if( ( value[valueIndex] == '*' ) && ( value[valueIndex+1] == '\0' ) )
break;
err = pgpLDAPGetSubstring( value + valueIndex, substring,
&substringType, &valueInc ); CKERR;
if( value[valueIndex] == '*' )
valueIndex++;
valueIndex += valueInc;
if( substring[0] == '\0' )
{
/* Empty string - don't do anything */
/* valueIndex++; */
continue;
}
err = PGPberAppend( ber, "ts",
substringType,
substring ); CKERR;
}
err = PGPberAppend( ber, "}}" ); CKERR;
break;
case kPGPldapFilter_Present:
for( i = 1, j = 0; filter[i] != '='; i++, j++ )
attr[j] = filter[i];
attr[j] = '\0';
err = PGPberAppend( ber, "ts",
filterType,
attr ); CKERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -