/* * Parse the value from an LDAPv3 "Persistent Search" control. They look * like this: * * PersistentSearch ::= SEQUENCE { * changeTypes INTEGER, * -- the changeTypes field is the logical OR of * -- one or more of these values: add (1), delete (2), * -- modify (4), modDN (8). It specifies which types of * -- changes will cause an entry to be returned. * changesOnly BOOLEAN, -- skip initial search? * returnECs BOOLEAN, -- return "Entry Change" controls? * } * * Return an LDAP error code (LDAP_SUCCESS if all goes well). * * This function is standalone; it does not require initialization of * the PS subsystem. */ int ps_parse_control_value( struct berval *psbvp, ber_int_t *changetypesp, int *changesonlyp, int *returnecsp ) { int rc= LDAP_SUCCESS; if ( psbvp->bv_len == 0 || psbvp->bv_val == NULL ) { rc= LDAP_PROTOCOL_ERROR; } else { BerElement *ber= ber_init( psbvp ); if ( ber == NULL ) { rc= LDAP_OPERATIONS_ERROR; } else { if ( ber_scanf( ber, "{ibb}", changetypesp, changesonlyp, returnecsp ) == LBER_ERROR ) { rc= LDAP_PROTOCOL_ERROR; } /* the ber encoding is no longer needed */ ber_free(ber,1); } } return( rc ); }
int allocate_oid_info_list(struct oid_info_head *list, msgpack_object *o, struct cid_info *ci) { int i; struct oid_info *oi; char tmp_buf[2048]; struct ber e; for (i = 0; i < o->via.array.size; i++) { if (o->via.array.ptr[i].type != MSGPACK_OBJECT_RAW) goto not_good; e = ber_init(tmp_buf, 2048); if (encode_string_oid(o->via.array.ptr[i].via.raw.ptr, o->via.array.ptr[i].via.raw.size, &e) < 0) goto not_good; oi = malloc(sizeof(*oi)); if (!oi) croak(2, "allocate_oid_info_list: malloc(oid_info)"); PS.active_oid_infos++; PS.total_oid_infos++; bzero(oi, sizeof(*oi)); oi->cid = ci->cid; oi->fd = ci->fd; oi->oid = ber_dup(&e); TAILQ_INSERT_TAIL(list, oi, oid_list); } return o->via.array.size; not_good: free_oid_info_list(list); return 0; }
int main(int argc, char **argv) { BerElement *dummy; char *foo = "bar"; dummy = ber_init(ber_bvstrdup(foo)); return 0; }
/** Converts the reply into server version and a return code * * This function takes the reply BER Value and decodes the NMAS server version and return code and if a non * null retData buffer was supplied, tries to decode the the return data and length. * @verbatim ResponseBer contents: server_version INTEGER error INTEGER data OCTET STRING @endverbatim * * @param[in] reply_bv reply data from extended request. * @param[out] server_version that responded. * @param[out] out data. * @param[out] outlen Length of data written to out. * @return 0 on success, and < 0 on error. */ static int ber_decode_login_data(struct berval *reply_bv, int *server_version, void *out, size_t *outlen) { int rc = 0; int err = 0; BerElement *reply_ber = NULL; rad_assert(out != NULL); rad_assert(outlen != NULL); if ((reply_ber = ber_init(reply_bv)) == NULL) { err = NMAS_E_SYSTEM_RESOURCES; goto finish; } rc = ber_scanf(reply_ber, "{iis}", server_version, &err, out, outlen); if (rc == -1) { err = NMAS_E_FRAG_FAILURE; goto finish; } finish: if(reply_ber) ber_free(reply_ber, 1); return err; }
/*********************************************************************** * ber_init (WLDAP32.@) * * Initialise a berelement structure from a berval structure. * * PARAMS * berval [I] Pointer to a berval structure. * * RETURNS * Success: Pointer to a berelement structure. * Failure: NULL * * NOTES * Call ber_free to free the returned berelement structure. */ BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) { #ifdef HAVE_LDAP return ber_init( berval ); #else return NULL; #endif }
static BerElement *get_control_data(LDAPControl **list, const char *repoid) { struct berval data; int ret; ret = find_control_data(list, repoid, &data); if (ret != LDAP_SUCCESS) return NULL; return ber_init(&data); }
int ldap_parse_virtuallist_control(LDAP *ld, LDAPControl **ctrls, unsigned long *target_posp, unsigned long *list_sizep, int *errcodep) { BerElement *ber; int i, foundListControl; LDAPControl *listCtrlp; if (NULL == ld) return (LDAP_PARAM_ERROR); /* only ldapv3 or higher can do virtual lists. */ if (ld->ld_version != LDAP_VERSION3) { ld->ld_errno = LDAP_NOT_SUPPORTED; return (LDAP_NOT_SUPPORTED); } /* find the listControl in the list of controls if it exists */ if (ctrls == NULL) { ld->ld_errno = LDAP_NOT_SUPPORTED; return (LDAP_NOT_SUPPORTED); } foundListControl = 0; for (i = 0; ((ctrls[i] != NULL) && (!foundListControl)); i++) { foundListControl = !(strcmp(ctrls[i]->ldctl_oid, LDAP_CONTROL_VLVRESPONSE)); } if (!foundListControl) { ld->ld_errno = LDAP_CONTROL_NOT_FOUND; return (LDAP_CONTROL_NOT_FOUND); } else { /* let local var point to the listControl */ listCtrlp = ctrls[i-1]; } /* allocate a Ber element with the contents of the list_control's */ /* struct berval */ if ((ber = ber_init(&listCtrlp->ldctl_value)) == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return (LDAP_NO_MEMORY); } /* decode the result from the Berelement */ if (LBER_ERROR == ber_scanf(ber, "{iie}", target_posp, list_sizep, errcodep)) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free(ber, 1); return (LDAP_DECODING_ERROR); } /* the ber encoding is no longer needed */ ber_free(ber, 1); return (LDAP_SUCCESS); }
int ldap_parse_refresh( LDAP *ld, LDAPMessage *res, ber_int_t *newttl ) { int rc; struct berval *retdata = NULL; ber_tag_t tag; BerElement *ber; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( res != NULL ); assert( newttl != NULL ); *newttl = 0; rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 ); if ( rc != LDAP_SUCCESS ) { return rc; } if ( ld->ld_errno != LDAP_SUCCESS ) { return ld->ld_errno; } if ( retdata == NULL ) { rc = ld->ld_errno = LDAP_DECODING_ERROR; return rc; } ber = ber_init( retdata ); if ( ber == NULL ) { rc = ld->ld_errno = LDAP_NO_MEMORY; goto done; } /* check the tag */ tag = ber_scanf( ber, "{i}", newttl ); ber_free( ber, 1 ); if ( tag != LDAP_TAG_EXOP_REFRESH_RES_TTL ) { *newttl = 0; rc = ld->ld_errno = LDAP_DECODING_ERROR; } done: ; if ( retdata ) { ber_bvfree( retdata ); } return rc; }
int ipapwd_get_cur_kvno(Slapi_Entry *target) { Slapi_Attr *krbPrincipalKey = NULL; Slapi_ValueSet *svs; Slapi_Value *sv; BerElement *be = NULL; const struct berval *cbval; ber_tag_t tag, tmp; ber_int_t tkvno; int hint; int kvno; int ret; /* retrieve current kvno and and keys */ ret = slapi_entry_attr_find(target, "krbPrincipalKey", &krbPrincipalKey); if (ret != 0) { return 0; } kvno = 0; slapi_attr_get_valueset(krbPrincipalKey, &svs); hint = slapi_valueset_first_value(svs, &sv); while (hint != -1) { cbval = slapi_value_get_berval(sv); if (!cbval) { LOG_TRACE("Error retrieving berval from Slapi_Value\n"); goto next; } be = ber_init(discard_const(cbval)); if (!be) { LOG_TRACE("ber_init() failed!\n"); goto next; } tag = ber_scanf(be, "{xxt[i]", &tmp, &tkvno); if (tag == LBER_ERROR) { LOG_TRACE("Bad OLD key encoding ?!\n"); ber_free(be, 1); goto next; } if (tkvno > kvno) { kvno = tkvno; } ber_free(be, 1); next: hint = slapi_valueset_next_value(svs, hint, &sv); } return kvno; }
static inline void vfss_init(VFSS_TYPE* vfss) { vfss->volume.process = INVALID_HANDLE; vfss->io = io_create(FAT_SECTOR_SIZE + sizeof(STORAGE_STACK)); vfss->io_size = FAT_SECTOR_SIZE; #if (VFS_BER) ber_init(vfss); #endif //VFS_BER #if (VFS_NO_FS == 0) #if (VFS_SFS) sfs_init(vfss); #else fat16_init(vfss); #endif // VFS_SFS #endif // VFS_NO_FS }
int ldap_parse_passwd( LDAP *ld, LDAPMessage *res, struct berval *newpasswd ) { int rc; struct berval *retdata = NULL; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( res != NULL ); assert( newpasswd != NULL ); newpasswd->bv_val = NULL; newpasswd->bv_len = 0; rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 ); if ( rc != LDAP_SUCCESS ) { return rc; } if ( retdata != NULL ) { ber_tag_t tag; BerElement *ber = ber_init( retdata ); if ( ber == NULL ) { rc = ld->ld_errno = LDAP_NO_MEMORY; goto done; } /* we should check the tag */ tag = ber_scanf( ber, "{o}", newpasswd ); ber_free( ber, 1 ); if ( tag == LBER_ERROR ) { rc = ld->ld_errno = LDAP_DECODING_ERROR; } } done:; ber_bvfree( retdata ); return rc; }
int ldap_parse_pageresponse_control( LDAP *ld, LDAPControl *ctrl, ber_int_t *countp, struct berval *cookie ) { BerElement *ber; ber_tag_t tag; ber_int_t count; if ( ld == NULL || ctrl == NULL || cookie == NULL ) { if ( ld ) ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } /* Create a BerElement from the berval returned in the control. */ ber = ber_init( &ctrl->ldctl_value ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } /* Extract the count and cookie from the control. */ tag = ber_scanf( ber, "{io}", &count, cookie ); ber_free( ber, 1 ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; } else { ld->ld_errno = LDAP_SUCCESS; if ( countp != NULL ) { *countp = (unsigned long)count; } } return ld->ld_errno; }
int ldap_parse_page_control(LDAP *ld, LDAPControl **controls, unsigned int *totalcount, struct berval **cookie) { int i, rc; BerElement *theBer; LDAPControl *listCtrlp; for (i = 0; controls[i] != NULL; i++){ if (strcmp(controls[i]->ldctl_oid, "1.2.840.113556.1.4.319") == 0) { listCtrlp = controls[i]; if ((theBer = ber_init(&listCtrlp->ldctl_value)) == NULLBER){ return (LDAP_NO_MEMORY); } if ((rc = ber_scanf(theBer, "{iO}", totalcount, cookie)) == LBER_ERROR){ ber_free(theBer, 1); return (LDAP_DECODING_ERROR); } ber_free(theBer, 1); return (LDAP_SUCCESS); } } return (LDAP_CONTROL_NOT_FOUND); }
/*********************************************************************** * ldap_parse_page_controlW (WLDAP32.@) */ ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls, ULONG *count, struct WLDAP32_berval **cookie ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP LDAPControlW *control = NULL; BerElement *ber; ber_tag_t tag; ULONG i; TRACE( "(%p, %p, %p, %p)\n", ld, ctrls, count, cookie ); if (!ld || !ctrls || !count || !cookie) return WLDAP32_LDAP_PARAM_ERROR; for (i = 0; ctrls[i]; i++) { if (!lstrcmpW( LDAP_PAGED_RESULT_OID_STRING_W, ctrls[i]->ldctl_oid )) control = ctrls[i]; } if (!control) return WLDAP32_LDAP_CONTROL_NOT_FOUND; ber = ber_init( &((LDAPControl *)control)->ldctl_value ); if (!ber) return WLDAP32_LDAP_NO_MEMORY; tag = ber_scanf( ber, "{iO}", count, cookie ); if ( tag == LBER_ERROR ) ret = WLDAP32_LDAP_DECODING_ERROR; else ret = WLDAP32_LDAP_SUCCESS; ber_free( ber, 1 ); #endif return ret; }
struct oid_info * allocate_oid_info(msgpack_object *o, struct cid_info *ci) { struct oid_info *oi; char tmp_buf[2048]; struct ber e; if (o->type != MSGPACK_OBJECT_RAW) return NULL; e = ber_init(tmp_buf, 2048); if (encode_string_oid(o->via.raw.ptr, o->via.raw.size, &e) < 0) return NULL; oi = malloc(sizeof(*oi)); if (!oi) croak(2, "allocate_oid_info: malloc(oid_info)"); PS.active_oid_infos++; PS.total_oid_infos++; bzero(oi, sizeof(*oi)); oi->cid = ci->cid; oi->fd = ci->fd; oi->oid = ber_dup(&e); return oi; }
static int berDecodeLoginData( struct berval *replyBV, int *serverVersion, size_t *retDataLen, void *retData ) { int err = 0; BerElement *replyBer = NULL; char *retOctStr = NULL; size_t retOctStrLen = 0; if ((replyBer = ber_init(replyBV)) == NULL) { err = LDAP_OPERATIONS_ERROR; goto Cleanup; } if (retData) { retOctStrLen = *retDataLen + 1; retOctStr = SMB_MALLOC_ARRAY(char, retOctStrLen); if (!retOctStr) { err = LDAP_OPERATIONS_ERROR; goto Cleanup; } if (ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != -1) { if (*retDataLen >= retOctStrLen) { memcpy(retData, retOctStr, retOctStrLen); } else if (!err) { err = LDAP_NO_MEMORY; } *retDataLen = retOctStrLen; } else if (!err) { err = LDAP_DECODING_ERROR; } } else { if (ber_scanf(replyBer, "{ii}", serverVersion, &err) == -1) {
int ldap_parse_passwordpolicy_control( LDAP *ld, LDAPControl *ctrl, ber_int_t *expirep, ber_int_t *gracep, LDAPPasswordPolicyError *errorp ) { BerElement *ber; int exp = -1, grace = -1; ber_tag_t tag; ber_len_t berLen; char *last; int err = PP_noError; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( ctrl != NULL ); /* Create a BerElement from the berval returned in the control. */ ber = ber_init(&ctrl->ldctl_value); if (ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return(ld->ld_errno); } tag = ber_peek_tag( ber, &berLen ); if (tag != LBER_SEQUENCE) goto exit; for( tag = ber_first_element( ber, &berLen, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &berLen, last ) ) { switch (tag) { case PPOLICY_WARNING: ber_skip_tag(ber, &berLen ); tag = ber_peek_tag( ber, &berLen ); switch( tag ) { case PPOLICY_EXPIRE: if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit; break; case PPOLICY_GRACE: if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit; break; default: goto exit; } break; case PPOLICY_ERROR: if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit; break; default: goto exit; } } ber_free(ber, 1); /* Return data to the caller for items that were requested. */ if (expirep) *expirep = exp; if (gracep) *gracep = grace; if (errorp) *errorp = err; ld->ld_errno = LDAP_SUCCESS; return(ld->ld_errno); exit: ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); }
int ldap_parse_vlvresponse_control( LDAP *ld, LDAPControl *ctrl, ber_int_t *target_posp, ber_int_t *list_countp, struct berval **contextp, ber_int_t *errcodep ) { BerElement *ber; ber_int_t pos, count, err; ber_tag_t tag, berTag; ber_len_t berLen; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); if (contextp) { *contextp = NULL; /* Make sure we return a NULL if error occurs. */ } if (ctrl == NULL) { ld->ld_errno = LDAP_PARAM_ERROR; return(ld->ld_errno); } if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) { /* Not VLV Response control */ ld->ld_errno = LDAP_CONTROL_NOT_FOUND; return(ld->ld_errno); } /* Create a BerElement from the berval returned in the control. */ ber = ber_init(&ctrl->ldctl_value); if (ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return(ld->ld_errno); } /* Extract the data returned in the control. */ tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err); if( tag == LBER_ERROR) { ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); } /* Since the context is the last item encoded, if caller doesn't want it returned, don't decode it. */ if (contextp) { if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) { tag = ber_scanf(ber, "tO", &berTag, contextp); if( tag == LBER_ERROR) { ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); } } } ber_free(ber, 1); /* Return data to the caller for items that were requested. */ if (target_posp) *target_posp = pos; if (list_countp) *list_countp = count; if (errcodep) *errcodep = err; ld->ld_errno = LDAP_SUCCESS; return(ld->ld_errno); }
int ldap_parse_session_tracking_control( LDAP *ld, LDAPControl *ctrl, struct berval *ip, struct berval *name, struct berval *oid, struct berval *id ) { BerElement *ber; ber_tag_t tag; ber_len_t len; if ( ld == NULL || ctrl == NULL || ip == NULL || name == NULL || oid == NULL || id == NULL ) { if ( ld ) { ld->ld_errno = LDAP_PARAM_ERROR; } /* NOTE: we want the caller to get all or nothing; * we could allow some of the pointers to be NULL, * if one does not want part of the data */ return LDAP_PARAM_ERROR; } BER_BVZERO( ip ); BER_BVZERO( name ); BER_BVZERO( oid ); BER_BVZERO( id ); ber = ber_init( &ctrl->ldctl_value ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_skip_tag( ber, &len ); if ( tag != LBER_SEQUENCE ) { tag = LBER_ERROR; goto error; } /* sessionSourceIp */ tag = ber_peek_tag( ber, &len ); if ( tag == LBER_DEFAULT ) { tag = LBER_ERROR; goto error; } if ( len == 0 ) { tag = ber_skip_tag( ber, &len ); } else { if ( len > 128 ) { /* should be LDAP_DECODING_ERROR, * but we're liberal in what we accept */ } tag = ber_scanf( ber, "o", ip ); } /* sessionSourceName */ tag = ber_peek_tag( ber, &len ); if ( tag == LBER_DEFAULT ) { tag = LBER_ERROR; goto error; } if ( len == 0 ) { tag = ber_skip_tag( ber, &len ); } else { if ( len > 65536 ) { /* should be LDAP_DECODING_ERROR, * but we're liberal in what we accept */ } tag = ber_scanf( ber, "o", name ); } /* formatOID */ tag = ber_peek_tag( ber, &len ); if ( tag == LBER_DEFAULT ) { tag = LBER_ERROR; goto error; } if ( len == 0 ) { ld->ld_errno = LDAP_DECODING_ERROR; goto error; } else { if ( len > 1024 ) { /* should be LDAP_DECODING_ERROR, * but we're liberal in what we accept */ } tag = ber_scanf( ber, "o", oid ); } /* FIXME: should check if it is an OID... leave it to the caller */ /* sessionTrackingIdentifier */ tag = ber_peek_tag( ber, &len ); if ( tag == LBER_DEFAULT ) { tag = LBER_ERROR; goto error; } if ( len == 0 ) { tag = ber_skip_tag( ber, &len ); } else { #if 0 if ( len > 65536 ) { /* should be LDAP_DECODING_ERROR, * but we're liberal in what we accept */ } #endif tag = ber_scanf( ber, "o", id ); } /* closure */ tag = ber_skip_tag( ber, &len ); if ( tag == LBER_DEFAULT && len == 0 ) { tag = 0; } error:; (void)ber_free( ber, 1 ); if ( tag == LBER_ERROR ) { return LDAP_DECODING_ERROR; } return ld->ld_errno; }
/* * handle the LDAP_RES_SEARCH_RESULT response */ static int ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) { int err; char *matched = NULL, *msg = NULL; LDAPControl **ctrls = NULL; int rc; int refreshDeletes = -1; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot LDAP_RES_SEARCH_RESULT\n" ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( res != NULL ); /* should not happen in refreshAndPersist... */ rc = ldap_parse_result( ls->ls_ld, res, &err, &matched, &msg, NULL, &ctrls, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tldap_parse_result(%d, \"%s\", \"%s\") == %d\n", err, matched ? matched : "", msg ? msg : "", rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc == LDAP_SUCCESS ) { rc = err; } ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; switch ( rc ) { case LDAP_SUCCESS: { int i; BerElement *ber = NULL; ber_len_t len; struct berval cookie = { 0 }; rc = LDAP_OTHER; /* deal with control; then fallthru to handler */ if ( ctrls == NULL ) { goto done; } /* lookup the sync state control */ for ( i = 0; ctrls[ i ] != NULL; i++ ) { if ( strcmp( ctrls[ i ]->ldctl_oid, LDAP_CONTROL_SYNC_DONE ) == 0 ) { break; } } /* control must be present; there might be other... */ if ( ctrls[ i ] == NULL ) { goto done; } /* extract data */ ber = ber_init( &ctrls[ i ]->ldctl_value ); if ( ber == NULL ) { goto done; } if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) { goto ber_done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto ber_done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } refreshDeletes = 0; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { goto ber_done; } if ( refreshDeletes ) { refreshDeletes = 1; } } if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) { rc = LDAP_SUCCESS; } ber_done:; ber_free( ber, 1 ); if ( rc != LDAP_SUCCESS ) { break; } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDeletes=%s\n", refreshDeletes ? "TRUE" : "FALSE" ); #endif /* LDAP_SYNC_TRACE */ /* FIXME: what should we do with the refreshDelete? */ switch ( refreshDeletes ) { case 0: ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS; break; default: ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES; break; } } /* fallthru */ case LDAP_SYNC_REFRESH_REQUIRED: /* TODO: check for Sync Done Control */ /* FIXME: perhaps the handler should be called * also in case of failure; we'll deal with this * later when implementing refreshOnly */ if ( ls->ls_search_result ) { err = ls->ls_search_result( ls, res, refreshDeletes ); } break; } done:; if ( matched != NULL ) { ldap_memfree( matched ); } if ( msg != NULL ) { ldap_memfree( msg ); } if ( ctrls != NULL ) { ldap_controls_free( ctrls ); } ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; return rc; }
static struct ipapwd_krbcfg *ipapwd_getConfig(void) { krb5_error_code krberr; struct ipapwd_krbcfg *config = NULL; krb5_keyblock *kmkey = NULL; Slapi_Entry *realm_entry = NULL; Slapi_Entry *config_entry = NULL; Slapi_Attr *a; Slapi_Value *v; BerElement *be = NULL; ber_tag_t tag, tvno; ber_int_t ttype; const struct berval *bval; struct berval *mkey = NULL; char **encsalts; char **tmparray; char *tmpstr; int i, ret; config = calloc(1, sizeof(struct ipapwd_krbcfg)); if (!config) { LOG_OOM(); goto free_and_error; } kmkey = calloc(1, sizeof(krb5_keyblock)); if (!kmkey) { LOG_OOM(); goto free_and_error; } config->kmkey = kmkey; krberr = krb5_init_context(&config->krbctx); if (krberr) { LOG_FATAL("krb5_init_context failed\n"); goto free_and_error; } ret = krb5_get_default_realm(config->krbctx, &config->realm); if (ret) { LOG_FATAL("Failed to get default realm?!\n"); goto free_and_error; } /* get the Realm Container entry */ ret = ipapwd_getEntry(ipa_realm_dn, &realm_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No realm Entry?\n"); goto free_and_error; } /*** get the Kerberos Master Key ***/ ret = slapi_entry_attr_find(realm_entry, "krbMKey", &a); if (ret == -1) { LOG_FATAL("No master key??\n"); goto free_and_error; } /* there should be only one value here */ ret = slapi_attr_first_value(a, &v); if (ret == -1) { LOG_FATAL("No master key??\n"); goto free_and_error; } bval = slapi_value_get_berval(v); if (!bval) { LOG_FATAL("Error retrieving master key berval\n"); goto free_and_error; } be = ber_init(discard_const(bval)); if (!be) { LOG_FATAL("ber_init() failed!\n"); goto free_and_error; } tag = ber_scanf(be, "{i{iO}}", &tvno, &ttype, &mkey); if (tag == LBER_ERROR) { LOG_FATAL("Bad Master key encoding ?!\n"); goto free_and_error; } config->mkvno = tvno; kmkey->magic = KV5M_KEYBLOCK; kmkey->enctype = ttype; kmkey->length = mkey->bv_len; kmkey->contents = malloc(mkey->bv_len); if (!kmkey->contents) { LOG_OOM(); goto free_and_error; } memcpy(kmkey->contents, mkey->bv_val, mkey->bv_len); ber_bvfree(mkey); ber_free(be, 1); mkey = NULL; be = NULL; /*** get the Supported Enc/Salt types ***/ encsalts = slapi_entry_attr_get_charray(realm_entry, "krbSupportedEncSaltTypes"); if (encsalts) { for (i = 0; encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, (const char * const *)encsalts, i, &config->supp_encsalts, &config->num_supp_encsalts); slapi_ch_array_free(encsalts); } else { LOG("No configured salt types use defaults\n"); for (i = 0; ipapwd_def_encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, ipapwd_def_encsalts, i, &config->supp_encsalts, &config->num_supp_encsalts); } if (ret) { LOG_FATAL("Can't get Supported EncSalt Types\n"); goto free_and_error; } /*** get the Preferred Enc/Salt types ***/ encsalts = slapi_entry_attr_get_charray(realm_entry, "krbDefaultEncSaltTypes"); if (encsalts) { for (i = 0; encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, (const char * const *)encsalts, i, &config->pref_encsalts, &config->num_pref_encsalts); slapi_ch_array_free(encsalts); } else { LOG("No configured salt types use defaults\n"); for (i = 0; ipapwd_def_encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, ipapwd_def_encsalts, i, &config->pref_encsalts, &config->num_pref_encsalts); } if (ret) { LOG_FATAL("Can't get Preferred EncSalt Types\n"); goto free_and_error; } slapi_entry_free(realm_entry); /* get the Realm Container entry */ ret = ipapwd_getEntry(ipa_pwd_config_dn, &config_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No config Entry? Impossible!\n"); goto free_and_error; } config->passsync_mgrs = slapi_entry_attr_get_charray(config_entry, "passSyncManagersDNs"); /* now add Directory Manager, it is always added by default */ tmpstr = slapi_ch_strdup("cn=Directory Manager"); slapi_ch_array_add(&config->passsync_mgrs, tmpstr); if (config->passsync_mgrs == NULL) { LOG_OOM(); goto free_and_error; } for (i = 0; config->passsync_mgrs[i]; i++) /* count */ ; config->num_passsync_mgrs = i; slapi_entry_free(config_entry); /* get the ipa etc/ipaConfig entry */ config->allow_nt_hash = false; ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No config Entry?\n"); goto free_and_error; } else { tmparray = slapi_entry_attr_get_charray(config_entry, "ipaConfigString"); for (i = 0; tmparray && tmparray[i]; i++) { if (strcasecmp(tmparray[i], "AllowNThash") == 0) { config->allow_nt_hash = true; continue; } } if (tmparray) slapi_ch_array_free(tmparray); } slapi_entry_free(config_entry); return config; free_and_error: if (mkey) ber_bvfree(mkey); if (be) ber_free(be, 1); if (kmkey) { free(kmkey->contents); free(kmkey); } if (config) { if (config->krbctx) { if (config->realm) krb5_free_default_realm(config->krbctx, config->realm); krb5_free_context(config->krbctx); } free(config->pref_encsalts); free(config->supp_encsalts); slapi_ch_array_free(config->passsync_mgrs); free(config); } slapi_entry_free(config_entry); slapi_entry_free(realm_entry); return NULL; }
int LDAP_CALL ldap_parse_sort_control ( LDAP *ld, LDAPControl **ctrlp, unsigned long *result, char **attribute ) { BerElement *ber; int i, foundSortControl; LDAPControl *sortCtrlp; unsigned long len, tag; char *attr; if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || result == NULL || attribute == NULL ) { return( LDAP_PARAM_ERROR ); } /* find the sortControl in the list of controls if it exists */ if ( ctrlp == NULL ) { LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); return ( LDAP_CONTROL_NOT_FOUND ); } foundSortControl = 0; for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundSortControl )); i++ ) { foundSortControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_SORTRESPONSE ); } if ( !foundSortControl ) { LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); return ( LDAP_CONTROL_NOT_FOUND ); } else { /* let local var point to the sortControl */ sortCtrlp = ctrlp[i-1]; } /* allocate a Ber element with the contents of the sort_control's struct berval */ if ( ( ber = ber_init( &sortCtrlp->ldctl_value ) ) == NULL ) { LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); return( LDAP_NO_MEMORY ); } /* decode the result from the Berelement */ if ( ber_scanf( ber, "{i", result ) == LBER_ERROR ) { LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); ber_free( ber, 1 ); return( LDAP_DECODING_ERROR ); } /* if the server returned one, decode the attribute from the Ber element */ if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SR_ATTRTYPE ) { if ( ber_scanf( ber, "ta", &tag, &attr ) == LBER_ERROR ) { LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); ber_free( ber, 1 ); return( LDAP_DECODING_ERROR ); } *attribute = attr; } else { *attribute = NULL; } if ( ber_scanf( ber, "}" ) == LBER_ERROR ) { LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); ber_free( ber, 1 ); return( LDAP_DECODING_ERROR ); } /* the ber encoding is no longer needed */ ber_free(ber,1); return( LDAP_SUCCESS ); }
static int proxyOld_parse( Operation *op, SlapReply *rs, LDAPControl *ctrl ) { int rc; BerElement *ber; ber_tag_t tag; struct berval dn = BER_BVNULL; struct berval authzDN = BER_BVNULL; /* We hijack the flag for the new control. Clearly only one or the * other can be used at any given time. */ if ( op->o_proxy_authz != SLAP_CONTROL_NONE ) { rs->sr_text = "proxy authorization control specified multiple times"; return LDAP_PROTOCOL_ERROR; } op->o_proxy_authz = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; /* Parse the control value * proxyAuthzControlValue ::= SEQUENCE { * proxyDN LDAPDN * } */ ber = ber_init( &ctrl->ldctl_value ); if ( ber == NULL ) { rs->sr_text = "ber_init failed"; return LDAP_OTHER; } tag = ber_scanf( ber, "{m}", &dn ); if ( tag == LBER_ERROR ) { rs->sr_text = "proxyOld control could not be decoded"; rc = LDAP_OTHER; goto done; } if ( BER_BVISEMPTY( &dn )) { Debug( LDAP_DEBUG_TRACE, "proxyOld_parse: conn=%lu anonymous\n", op->o_connid, 0, 0 ); authzDN.bv_val = ch_strdup(""); } else { Debug( LDAP_DEBUG_ARGS, "proxyOld_parse: conn %lu ctrl DN=\"%s\"\n", op->o_connid, dn.bv_val, 0 ); rc = dnNormalize( 0, NULL, NULL, &dn, &authzDN, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { goto done; } rc = slap_sasl_authorized( op, &op->o_ndn, &authzDN ); if ( rc ) { op->o_tmpfree( authzDN.bv_val, op->o_tmpmemctx ); rs->sr_text = "not authorized to assume identity"; /* new spec uses LDAP_PROXY_AUTHZ_FAILURE */ rc = LDAP_INSUFFICIENT_ACCESS; goto done; } } free( op->o_ndn.bv_val ); free( op->o_dn.bv_val ); op->o_ndn = authzDN; ber_dupbv( &op->o_dn, &authzDN ); Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu PROXYOLD dn=\"%s\"\n", op->o_connid, op->o_opid, authzDN.bv_len ? authzDN.bv_val : "anonymous", 0, 0 ); rc = LDAP_SUCCESS; done: ber_free( ber, 1 ); return rc; }
int ldap_parse_sortresponse_control( LDAP *ld, LDAPControl *ctrl, ber_int_t *returnCode, char **attribute ) { BerElement *ber; ber_tag_t tag, berTag; ber_len_t berLen; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); if (ld == NULL) { return LDAP_PARAM_ERROR; } if (ctrl == NULL) { ld->ld_errno = LDAP_PARAM_ERROR; return(ld->ld_errno); } if (attribute) { *attribute = NULL; } if ( strcmp(LDAP_CONTROL_SORTRESPONSE, ctrl->ldctl_oid) != 0 ) { /* Not sort result control */ ld->ld_errno = LDAP_CONTROL_NOT_FOUND; return(ld->ld_errno); } /* Create a BerElement from the berval returned in the control. */ ber = ber_init(&ctrl->ldctl_value); if (ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return(ld->ld_errno); } /* Extract the result code from the control. */ tag = ber_scanf(ber, "{e" /*}*/, returnCode); if( tag == LBER_ERROR ) { ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); } /* If caller wants the attribute name, and if it's present in the control, extract the attribute name which caused the error. */ if (attribute && (LDAP_ATTRTYPES_IDENTIFIER == ber_peek_tag(ber, &berLen))) { tag = ber_scanf(ber, "ta", &berTag, attribute); if (tag == LBER_ERROR ) { ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); } } ber_free(ber,1); ld->ld_errno = LDAP_SUCCESS; return(ld->ld_errno); }
/* * handle the LDAP_RES_SEARCH_ENTRY response */ static int ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res ) { LDAPControl **ctrls = NULL; int rc = LDAP_OTHER, i; BerElement *ber = NULL; struct berval entryUUID = { 0 }, cookie = { 0 }; int state = -1; ber_len_t len; ldap_sync_refresh_t phase; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot LDAP_RES_SEARCH_ENTRY\n" ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( res != NULL ); phase = ls->ls_refreshPhase; /* OK */ /* extract: * - data * - entryUUID * * check that: * - Sync State Control is "add" */ /* the control MUST be present */ /* extract controls */ ldap_get_entry_controls( ls->ls_ld, res, &ctrls ); if ( ctrls == NULL ) { goto done; } /* lookup the sync state control */ for ( i = 0; ctrls[ i ] != NULL; i++ ) { if ( strcmp( ctrls[ i ]->ldctl_oid, LDAP_CONTROL_SYNC_STATE ) == 0 ) { break; } } /* control must be present; there might be other... */ if ( ctrls[ i ] == NULL ) { goto done; } /* extract data */ ber = ber_init( &ctrls[ i ]->ldctl_value ); if ( ber == NULL ) { goto done; } /* scan entryUUID in-place ("m") */ if ( ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID ) == LBER_ERROR || entryUUID.bv_len == 0 ) { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { /* scan cookie in-place ("m") */ if ( ber_scanf( ber, /*"{"*/ "m}", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } switch ( state ) { case LDAP_SYNC_PRESENT: case LDAP_SYNC_DELETE: case LDAP_SYNC_ADD: case LDAP_SYNC_MODIFY: /* NOTE: ldap_sync_refresh_t is defined * as the corresponding LDAP_SYNC_* * for the 4 above cases */ phase = state; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot syncState=%s\n", ldap_sync_state2str( state ) ); #endif /* LDAP_SYNC_TRACE */ break; default: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot unknown syncState=%d\n", state ); #endif /* LDAP_SYNC_TRACE */ goto done; } rc = ls->ls_search_entry ? ls->ls_search_entry( ls, res, &entryUUID, phase ) : LDAP_SUCCESS; done:; if ( ber != NULL ) { ber_free( ber, 1 ); } if ( ctrls != NULL ) { ldap_controls_free( ctrls ); } return rc; }
int ldap_parse_verify_credentials( LDAP *ld, LDAPMessage *res, int * code, char ** diagmsg, struct berval **cookie, struct berval **screds, LDAPControl ***ctrls) { int rc; char *retoid = NULL; struct berval *retdata = NULL; assert(ld != NULL); assert(LDAP_VALID(ld)); assert(res != NULL); assert(code != NULL); assert(diagmsg != NULL); rc = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0); if( rc != LDAP_SUCCESS ) { ldap_perror(ld, "ldap_parse_verify_credentials"); return rc; } if (retdata) { ber_tag_t tag; ber_len_t len; ber_int_t i; BerElement * ber = ber_init(retdata); struct berval diagmsg_bv = BER_BVNULL; if (!ber) { rc = ld->ld_errno = LDAP_NO_MEMORY; goto done; } ber_scanf(ber, "{im" /*"}"*/, &i, &diagmsg_bv); if ( diagmsg != NULL ) { *diagmsg = LDAP_MALLOC( diagmsg_bv.bv_len + 1 ); AC_MEMCPY( *diagmsg, diagmsg_bv.bv_val, diagmsg_bv.bv_len ); (*diagmsg)[diagmsg_bv.bv_len] = '\0'; } *code = i; tag = ber_peek_tag(ber, &len); if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE) { ber_scanf(ber, "O", cookie); tag = ber_peek_tag(ber, &len); } if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS) { ber_scanf(ber, "O", screds); tag = ber_peek_tag(ber, &len); } if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS) { int nctrls = 0; char * opaque; *ctrls = LDAP_MALLOC(1 * sizeof(LDAPControl *)); if (!*ctrls) { rc = LDAP_NO_MEMORY; goto done; } *ctrls[nctrls] = NULL; for(tag = ber_first_element(ber, &len, &opaque); tag != LBER_ERROR; tag = ber_next_element(ber, &len, opaque)) { LDAPControl *tctrl; LDAPControl **tctrls; tctrl = LDAP_CALLOC(1, sizeof(LDAPControl)); /* allocate pointer space for current controls (nctrls) * + this control + extra NULL */ tctrls = !tctrl ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); if (!tctrls) { /* allocation failure */ if (tctrl) LDAP_FREE(tctrl); ldap_controls_free(*ctrls); *ctrls = NULL; rc = LDAP_NO_MEMORY; goto done; } tctrls[nctrls++] = tctrl; tctrls[nctrls] = NULL; tag = ber_scanf(ber, "{a" /*"}"*/, &tctrl->ldctl_oid); if (tag == LBER_ERROR) { *ctrls = NULL; ldap_controls_free(tctrls); rc = LDAP_DECODING_ERROR; goto done; } tag = ber_peek_tag(ber, &len); if (tag == LBER_BOOLEAN) { ber_int_t crit; tag = ber_scanf(ber, "b", &crit); tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; tag = ber_peek_tag(ber, &len); } if (tag == LBER_OCTETSTRING) { tag = ber_scanf( ber, "o", &tctrl->ldctl_value ); } else { BER_BVZERO( &tctrl->ldctl_value ); } *ctrls = tctrls; } } ber_free(ber, 1); } done: ber_bvfree(retdata); ber_memfree(retoid); return rc; }
/* * handle the LDAP_RES_INTERMEDIATE response */ static int ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDone ) { int rc; char *retoid = NULL; struct berval *retdata = NULL; BerElement *ber = NULL; ber_len_t len; ber_tag_t syncinfo_tag; struct berval cookie; int refreshDeletes = 0; BerVarray syncUUIDs = NULL; ldap_sync_refresh_t phase; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot LDAP_RES_INTERMEDIATE\n" ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( res != NULL ); assert( refreshDone != NULL ); *refreshDone = 0; rc = ldap_parse_intermediate( ls->ls_ld, res, &retoid, &retdata, NULL, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t%sldap_parse_intermediate(%s) == %d\n", rc != LDAP_SUCCESS ? "!!! " : "", retoid == NULL ? "\"\"" : retoid, rc ); #endif /* LDAP_SYNC_TRACE */ /* parsing must be successful, and yield the OID * of the sync info intermediate response */ if ( rc != LDAP_SUCCESS ) { goto done; } rc = LDAP_OTHER; if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) { goto done; } /* init ber using the value in the response */ ber = ber_init( retdata ); if ( ber == NULL ) { goto done; } syncinfo_tag = ber_peek_tag( ber, &len ); switch ( syncinfo_tag ) { case LDAP_TAG_SYNC_NEW_COOKIE: if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ break; case LDAP_TAG_SYNC_REFRESH_DELETE: case LDAP_TAG_SYNC_REFRESH_PRESENT: if ( syncinfo_tag == LDAP_TAG_SYNC_REFRESH_DELETE ) { #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDelete\n" ); #endif /* LDAP_SYNC_TRACE */ switch ( ls->ls_refreshPhase ) { case LDAP_SYNC_CAPI_NONE: case LDAP_SYNC_CAPI_PRESENTS: ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES; break; default: /* TODO: impossible; handle */ goto done; } } else { #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshPresent\n" ); #endif /* LDAP_SYNC_TRACE */ switch ( ls->ls_refreshPhase ) { case LDAP_SYNC_CAPI_NONE: ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS; break; default: /* TODO: impossible; handle */ goto done; } } if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } *refreshDone = 1; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) { if ( ber_scanf( ber, "b", refreshDone ) == LBER_ERROR ) { goto done; } } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDone=%s\n", *refreshDone ? "TRUE" : "FALSE" ); #endif /* LDAP_SYNC_TRACE */ if ( ber_scanf( ber, /*"{"*/ "}" ) == LBER_ERROR ) { goto done; } if ( *refreshDone ) { ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; } if ( ls->ls_intermediate ) { ls->ls_intermediate( ls, res, NULL, ls->ls_refreshPhase ); } break; case LDAP_TAG_SYNC_ID_SET: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot syncIdSet\n" ); #endif /* LDAP_SYNC_TRACE */ if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { goto done; } } if ( ber_scanf( ber, /*"{"*/ "[W]}", &syncUUIDs ) == LBER_ERROR || syncUUIDs == NULL ) { goto done; } if ( refreshDeletes ) { phase = LDAP_SYNC_CAPI_DELETES_IDSET; } else { phase = LDAP_SYNC_CAPI_PRESENTS_IDSET; } /* FIXME: should touch ls->ls_refreshPhase? */ if ( ls->ls_intermediate ) { ls->ls_intermediate( ls, res, syncUUIDs, phase ); } ber_bvarray_free( syncUUIDs ); break; default: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tunknown tag!\n" ); #endif /* LDAP_SYNC_TRACE */ goto done; } rc = LDAP_SUCCESS; done:; if ( ber != NULL ) { ber_free( ber, 1 ); } if ( retoid != NULL ) { ldap_memfree( retoid ); } if ( retdata != NULL ) { ber_bvfree( retdata ); } return rc; }
static int _ger_parse_control ( Slapi_PBlock *pb, char **subjectndn, int *iscritical, char **errbuf ) { LDAPControl **requestcontrols; struct berval *subjectber; BerElement *ber; size_t subjectndnlen = 0; char *orig = NULL; char *normed = NULL; if (NULL == subjectndn) { return LDAP_OPERATIONS_ERROR; } *subjectndn = NULL; /* * Get the control */ slapi_pblock_get ( pb, SLAPI_REQCONTROLS, (void *) &requestcontrols ); slapi_control_present ( requestcontrols, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS, &subjectber, iscritical ); if ( subjectber == NULL || subjectber->bv_val == NULL || subjectber->bv_len == 0 ) { aclutil_str_append ( errbuf, "get-effective-rights: missing subject" ); slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf ); if (iscritical) return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */ else return LDAP_INVALID_SYNTAX; } if ( strncasecmp ( "dn:", subjectber->bv_val, 3 ) == 0 ) { /* * This is a non-standard support to allow the subject being a plain * or base64 encoding string. Hence users using -J option in * ldapsearch don't have to do BER encoding for the subject. */ orig = slapi_ch_malloc ( subjectber->bv_len + 1 ); strncpy ( orig, subjectber->bv_val, subjectber->bv_len ); *(orig + subjectber->bv_len) = '\0'; } else { ber = ber_init (subjectber); if ( ber == NULL ) { aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" ); slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf ); if (iscritical) return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */ else return LDAP_OPERATIONS_ERROR; } /* "a" means to allocate storage as needed for octet string */ if ( ber_scanf (ber, "a", &orig) == LBER_ERROR ) { aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" ); slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf ); ber_free ( ber, 1 ); if (iscritical) return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */ else return LDAP_INVALID_SYNTAX; } ber_free ( ber, 1 ); } /* * The current implementation limits the subject to authorization ID * (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId" * flavor, which looks like "dn:<DN>" where null <DN> is for anonymous. */ subjectndnlen = orig ? strlen(orig) : 0; if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 ) { aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" ); slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf ); slapi_ch_free_string(&orig); if (iscritical) return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */ else return LDAP_INVALID_SYNTAX; } /* memmove is safe for overlapping copy */ normed = slapi_create_dn_string("%s", orig + 3); if (NULL == normed) { aclutil_str_append (errbuf, "get-effective-rights: failed to normalize dn: "); aclutil_str_append (errbuf, orig); slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf); slapi_ch_free_string(&orig); if (iscritical) return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */ else return LDAP_INVALID_SYNTAX; } slapi_ch_free_string(&orig); *subjectndn = normed; slapi_dn_ignore_case(*subjectndn); return LDAP_SUCCESS; }
int LDAP_CALL ldap_parse_userstatus_control(LDAP *ld, LDAPControl **ctrlp, LDAPuserstatus *us) { BerElement *ber = NULL; int i, foundUSControl; LDAPControl *USCtrlp = NULL; ber_tag_t tag; if (!NSLDAPI_VALID_LDAP_POINTER(ld) || us == NULL) { return (LDAP_PARAM_ERROR); } /* find the control in the list of controls if it exists */ if (ctrlp == NULL) { LDAP_SET_LDERRNO(ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL); return (LDAP_CONTROL_NOT_FOUND); } foundUSControl = 0; for (i = 0; ((ctrlp[i] != NULL) && (!foundUSControl)); i++) { foundUSControl = !strcmp(ctrlp[i]->ldctl_oid, LDAP_CONTROL_ACCOUNT_USABLE); } if (!foundUSControl) { LDAP_SET_LDERRNO(ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL); return (LDAP_CONTROL_NOT_FOUND); } else { /* let local var point to the control */ USCtrlp = ctrlp[i - 1]; } /* allocate a Ber element with the contents of the control's struct berval */ if ((ber = ber_init(&USCtrlp->ldctl_value)) == NULL) { LDAP_SET_LDERRNO(ld, LDAP_NO_MEMORY, NULL, NULL); return (LDAP_NO_MEMORY); } memset(us, 0, sizeof(struct LDAPuserstatus)); /* * The control value should look like this: * * ACCOUNT_USABLE_RESPONSE::= CHOICE { * is_available [0] INTEGER, ** seconds before expiration ** * is_not_available [1] More_info * } * More_info::= SEQUENCE { * inactive [0] BOOLEAN DEFAULT FALSE, * reset [1] BOOLEAN DEFAULT FALSE, * expired [2] BOOLEAN DEFAULT FALSE, * remaining_grace [3] INTEGER OPTIONAL, * seconds_before_unlock [4] INTEGER OPTIONAL * } */ if ((ber_scanf(ber, "t", &tag)) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } tag = ((tag & LBER_CONSTRUCTED) == LBER_CONSTRUCTED) ? 1 : 0; if (!tag) { us->us_available = 1; if (ber_scanf(ber, "i", &us->us_expire) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } } else { us->us_available = 0; tag = 0; if ((ber_scanf(ber, "{t", &tag)) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } while (tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET) { tag = tag & (~LBER_CLASS_CONTEXT); switch (tag) { case 0: if (ber_scanf(ber, "b", &us->us_inactive) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } us->us_inactive = (us->us_inactive != 0) ? 1 : 0; break; case 1: if (ber_scanf(ber, "b", &us->us_reset) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } us->us_reset = (us->us_reset != 0) ? 1 : 0; break; case 2: if (ber_scanf(ber, "b", &us->us_expired) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } us->us_expired = (us->us_expired != 0) ? 1 : 0; break; case 3: if (ber_scanf(ber, "i", &us->us_remaining) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } break; case 4: if (ber_scanf(ber, "i", &us->us_seconds) == LBER_ERROR) { LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } break; default: LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL); ber_free(ber, 1); return (LDAP_DECODING_ERROR); } ber_scanf(ber, "t", &tag); } } /* the ber encoding is no longer needed */ ber_free(ber, 1); return (LDAP_SUCCESS); }
int main( int argc, char *argv[] ) { int rc; char *user = NULL; LDAP *ld = NULL; struct berval bv = {0, NULL}; BerElement *ber = NULL; int id, code = LDAP_OTHER; LDAPMessage *res; char *matcheddn = NULL, *text = NULL, **refs = NULL; char *retoid = NULL; struct berval *retdata = NULL; prog = lutil_progname( "ldappasswd", argc, argv ); /* LDAPv3 only */ protocol = LDAP_VERSION3; tool_args( argc, argv ); if( argc - optind > 1 ) { usage(); } else if ( argc - optind == 1 ) { user = strdup( argv[optind] ); } else { user = NULL; } if( oldpwfile ) { rc = lutil_get_filed_password( prog, &oldpw ); if( rc ) return EXIT_FAILURE; } if( want_oldpw && oldpw.bv_val == NULL ) { /* prompt for old password */ char *ckoldpw; oldpw.bv_val = strdup(getpassphrase("Old password: "******"Re-enter old password: "******"passwords do not match\n" ); return EXIT_FAILURE; } oldpw.bv_len = strlen( oldpw.bv_val ); } if( newpwfile ) { rc = lutil_get_filed_password( prog, &newpw ); if( rc ) return EXIT_FAILURE; } if( want_newpw && newpw.bv_val == NULL ) { /* prompt for new password */ char *cknewpw; newpw.bv_val = strdup(getpassphrase("New password: "******"Re-enter new password: "******"passwords do not match\n" ); return EXIT_FAILURE; } newpw.bv_len = strlen( newpw.bv_val ); } if( want_bindpw && passwd.bv_val == NULL ) { /* handle bind password */ if ( pw_file ) { rc = lutil_get_filed_password( pw_file, &passwd ); if( rc ) return EXIT_FAILURE; } else { passwd.bv_val = getpassphrase( "Enter LDAP Password: "******"ber_alloc_t" ); ldap_unbind( ld ); return EXIT_FAILURE; } ber_printf( ber, "{" /*}*/ ); if( user != NULL ) { ber_printf( ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); free(user); } if( oldpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &oldpw ); free(oldpw.bv_val); } if( newpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw ); free(newpw.bv_val); } ber_printf( ber, /*{*/ "N}" ); rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { perror( "ber_flatten2" ); ldap_unbind( ld ); return EXIT_FAILURE; } } if ( not ) { rc = LDAP_SUCCESS; goto skip; } rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, NULL, NULL, &id ); ber_free( ber, 1 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_extended_operation" ); ldap_unbind( ld ); return EXIT_FAILURE; } rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); if ( rc < 0 ) { ldap_perror( ld, "ldappasswd: ldap_result" ); return rc; } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_parse_result" ); return rc; } rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_parse_result" ); return rc; } if( retdata != NULL ) { ber_tag_t tag; char *s; ber = ber_init( retdata ); if( ber == NULL ) { perror( "ber_init" ); ldap_unbind( ld ); return EXIT_FAILURE; } /* we should check the tag */ tag = ber_scanf( ber, "{a}", &s); if( tag == LBER_ERROR ) { perror( "ber_scanf" ); } else { printf("New password: %s\n", s); free( s ); } ber_free( ber, 1 ); } if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) { printf( "Result: %s (%d)\n", ldap_err2string( code ), code ); if( text && *text ) { printf( "Additional info: %s\n", text ); } if( matcheddn && *matcheddn ) { printf( "Matched DN: %s\n", matcheddn ); } if( refs ) { int i; for( i=0; refs[i]; i++ ) { printf("Referral: %s\n", refs[i] ); } } } ber_memfree( text ); ber_memfree( matcheddn ); ber_memvfree( (void **) refs ); ber_memfree( retoid ); ber_bvfree( retdata ); skip: /* disconnect from server */ ldap_unbind (ld); return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE; }