static char *filter_add_strn(char *f, char *flimit, char *v, size_t vlen) /* Copy v into f. If flimit is too small, return NULL; * otherwise return (f + vlen). */ { auto size_t flen = flimit - f; if (vlen > flen) { /* flimit is too small */ if (flen > 0) SAFEMEMCPY(f, v, flen); return NULL; } if (vlen > 0) SAFEMEMCPY(f, v, vlen); return f + vlen; }
static int ldap_control_copy_contents(LDAPControl *ctrl_dst, LDAPControl *ctrl_src) { size_t len; if (NULL == ctrl_dst || NULL == ctrl_src) { return (LDAP_PARAM_ERROR); } ctrl_dst->ldctl_iscritical = ctrl_src->ldctl_iscritical; /* fill in the fields of this new control */ if ((ctrl_dst->ldctl_oid = strdup(ctrl_src->ldctl_oid)) == NULL) { return (LDAP_NO_MEMORY); } len = (size_t)(ctrl_src->ldctl_value).bv_len; if (ctrl_src->ldctl_value.bv_val == NULL || len <= 0) { ctrl_dst->ldctl_value.bv_len = 0; ctrl_dst->ldctl_value.bv_val = NULL; } else { ctrl_dst->ldctl_value.bv_len = len; if ((ctrl_dst->ldctl_value.bv_val = malloc(len)) == NULL) { free(ctrl_dst->ldctl_oid); return (LDAP_NO_MEMORY); } SAFEMEMCPY(ctrl_dst->ldctl_value.bv_val, ctrl_src->ldctl_value.bv_val, len); } return (LDAP_SUCCESS); }
static int add_addr( LDAP *ld, struct sockaddr *sap ) { struct sockaddr *newsap, **addrs; if (( newsap = (struct sockaddr *)malloc( sizeof( struct sockaddr ))) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( -1 ); } if ( ld->ld_sb.sb_naddr == 0 ) { addrs = (struct sockaddr **)malloc( sizeof(struct sockaddr *)); } else { addrs = (struct sockaddr **)realloc( ld->ld_sb.sb_addrs, ( ld->ld_sb.sb_naddr + 1 ) * sizeof(struct sockaddr *)); } if ( addrs == NULL ) { free( newsap ); ld->ld_errno = LDAP_NO_MEMORY; return( -1 ); } SAFEMEMCPY( (char *)newsap, (char *)sap, sizeof( struct sockaddr )); addrs[ ld->ld_sb.sb_naddr++ ] = newsap; ld->ld_sb.sb_addrs = (void **)addrs; return( 0 ); }
/* * duplicate the contents of "ctrl_src" and place in "ctrl_dst" */ static int /* LDAP_CALL */ /* keep this routine internal for now */ ldap_control_copy_contents( LDAPControl *ctrl_dst, LDAPControl *ctrl_src ) { size_t len; if ( NULL == ctrl_dst || NULL == ctrl_src ) { return( LDAP_PARAM_ERROR ); } ctrl_dst->ldctl_iscritical = ctrl_src->ldctl_iscritical; /* fill in the fields of this new control */ if (( ctrl_dst->ldctl_oid = nsldapi_strdup( ctrl_src->ldctl_oid )) == NULL ) { return( LDAP_NO_MEMORY ); } len = (size_t)(ctrl_src->ldctl_value).bv_len; if ( ctrl_src->ldctl_value.bv_val == NULL || len <= 0 ) { ctrl_dst->ldctl_value.bv_len = 0; ctrl_dst->ldctl_value.bv_val = NULL; } else { ctrl_dst->ldctl_value.bv_len = len; if (( ctrl_dst->ldctl_value.bv_val = NSLDAPI_MALLOC( len )) == NULL ) { NSLDAPI_FREE( ctrl_dst->ldctl_oid ); return( LDAP_NO_MEMORY ); } SAFEMEMCPY( ctrl_dst->ldctl_value.bv_val, ctrl_src->ldctl_value.bv_val, len ); } return ( LDAP_SUCCESS ); }
LDAP * cldap_open( char *host, int port ) { int s; in_addr_t address; struct sockaddr_in sock; struct hostent *hp; LDAP *ld; char *p; int i; #ifdef SUN struct hostent hpret; char hpbuf[NSS_BUFLEN_HOSTS]; int hperrno; #endif in_addr_t inet_addr(const char *); int close(int); Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113, "ldap_open\n"), 0, 0, 0 ); if ( port == 0 ) { port = LDAP_PORT; } if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { return( NULL ); } sock.sin_addr.s_addr = 0; sock.sin_family = AF_INET; sock.sin_port = 0; if ( bind(s, (struct sockaddr *) &sock, sizeof(sock)) < 0) { close( s ); return( NULL ); } if (( ld = ldap_init( host, port )) == NULL ) { close( s ); return( NULL ); } if ( (ld->ld_sb.sb_fromaddr = (void *) calloc( 1, sizeof( struct sockaddr ))) == NULL ) { free( ld ); close( s ); return( NULL ); } ld->ld_sb.sb_sd = s; ld->ld_sb.sb_naddr = 0; ld->ld_version = LDAP_VERSION; sock.sin_family = AF_INET; sock.sin_port = htons( port ); /* * 'host' may be a space-separated list. */ if ( host != NULL ) { for ( ; host != NULL; host = p ) { if (( p = strchr( host, ' ' )) != NULL ) { for (*p++ = '\0'; *p == ' '; p++) { ; } } if ( (address = inet_addr( host )) == -1 ) { #ifdef SUN if ( (hp = gethostbyname_r( host, &hpret, hpbuf, NSS_BUFLEN_HOSTS, &hperrno)) == NULL ) { errno = EHOSTUNREACH; continue; } #else if ( (hp = gethostbyname( host )) == NULL ) { errno = EHOSTUNREACH; continue; } #endif for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) { SAFEMEMCPY( (char *)&sock.sin_addr.s_addr, (char *)hp->h_addr_list[ i ], sizeof(sock.sin_addr.s_addr)); if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } } else { sock.sin_addr.s_addr = address; if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } if ( ld->ld_host == NULL ) { ld->ld_host = strdup( host ); } } } else { address = INADDR_LOOPBACK; sock.sin_addr.s_addr = htonl( address ); if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } if ( ld->ld_sb.sb_addrs == NULL #ifdef LDAP_REFERRALS || ( ld->ld_defconn = new_connection( ld, NULL, 1,0,0 )) == NULL #endif /* LDAP_REFERRALS */ ) { free( ld ); return( NULL ); } ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ]; cldap_setretryinfo( ld, 0, 0 ); #ifdef LDAP_DEBUG putchar( '\n' ); for ( i = 0; i < ld->ld_sb.sb_naddr; ++i ) { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 114, "end of cldap_open address %1$d is %2$s\n"), i, inet_ntoa( ((struct sockaddr_in *) ld->ld_sb.sb_addrs[ i ])->sin_addr ), 0 ); } #endif return( ld ); }
LDAP_CALL ldap_init( const char *defhost, int defport ) { LDAP *ld; if ( !nsldapi_initialized ) { nsldapi_initialize_defaults(); } if ( defport < 0 || defport > LDAP_PORT_MAX ) { LDAPDebug( LDAP_DEBUG_ANY, "ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n", defport, LDAP_PORT_MAX, 0 ); #if !defined( macintosh ) && !defined( DOS ) errno = EINVAL; #endif return( NULL ); } LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 ); if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) { return( NULL ); } /* copy defaults */ SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap )); if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) { if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC( sizeof( struct ldap_io_fns ))) == NULL ) { NSLDAPI_FREE( (char *)ld ); return( NULL ); } /* struct copy */ *(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr); } /* call the new handle I/O callback if one is defined */ if ( ld->ld_extnewhandle_fn != NULL ) { /* * We always pass the session extended I/O argument to * the new handle callback. */ if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg ) != LDAP_SUCCESS ) { NSLDAPI_FREE( (char*)ld ); return( NULL ); } } /* allocate session-specific resources */ if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL || ( defhost != NULL && ( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) || ((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) { if ( ld->ld_sbp != NULL ) { ber_sockbuf_free( ld->ld_sbp ); } if( ld->ld_mutex != NULL ) { NSLDAPI_FREE( ld->ld_mutex ); } NSLDAPI_FREE( (char*)ld ); return( NULL ); } /* install Sockbuf I/O functions if set in LDAP * */ if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) { struct lber_x_ext_io_fns lberiofns; memset( &lberiofns, 0, sizeof( lberiofns )); lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE; lberiofns.lbextiofn_read = ld->ld_extread_fn; lberiofns.lbextiofn_write = ld->ld_extwrite_fn; lberiofns.lbextiofn_writev = ld->ld_extwritev_fn; lberiofns.lbextiofn_socket_arg = NULL; ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS, (void *)&lberiofns ); } #ifdef _SOLARIS_SDK /* Install the functions for IPv6 support */ /* code sequencing is critical from here to nsldapi_mutex_alloc_all */ if ( prldap_install_thread_functions( ld, 1 ) != 0 || prldap_install_io_functions( ld, 1 ) != 0 || prldap_install_dns_functions( ld ) != 0 ) { /* go through ld and free resources */ ldap_unbind( ld ); ld = NULL; return( NULL ); } #else /* allocate mutexes */ nsldapi_mutex_alloc_all( ld ); #endif /* set default port */ ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport; return( ld ); }
int nsldapi_connect_to_host( LDAP *ld, Sockbuf *sb, char *host, unsigned long address, int port, int async, int secure ) /* * if host == NULL, connect using address * "address" and "port" must be in network byte order * zero is returned upon success, -1 if fatal error, -2 EINPROGRESS * if -1 is returned, ld_errno is set * async is only used ifndef NO_REFERRALS (non-0 means don't wait for connect) * XXX async is not used yet! */ { void *tcps; short i; int err; InetHostInfo hi; LDAPDebug( LDAP_DEBUG_TRACE, "connect_to_host: %s:%d\n", ( host == NULL ) ? "(by address)" : host, ntohs( port ), 0 ); /* Initialize OpenTransport, or find out from the host app whether it is installed */ (void)tcp_init(); if ( host != NULL && gethostinfobyname( host, &hi ) != noErr ) { LDAP_SET_LDERRNO( ld, LDAP_CONNECT_ERROR, NULL, NULL ); return( -1 ); } if ( ld->ld_socket_fn == NULL ) { tcps = tcpopen( NULL, TCP_BUFSIZ ); } else { tcps = ld->ld_socket_fn( AF_INET, SOCK_STREAM, 0 ); } if ( tcps == NULL ) { LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL ); return( -1 ); } if ( secure && ld->ld_ssl_enable_fn( tcps ) < 0 ) { if ( ld->ld_close_fn == NULL ) { tcpclose( (tcpstream *)tcps ); } else { ld->ld_close_fn( tcps ); } LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL ); return( -1 ); } for ( i = 0; host == NULL || hi.addrs[ i ] != 0; ++i ) { if ( host != NULL ) { SAFEMEMCPY( (char *)&address, (char *)&hi.addrs[ i ], sizeof( long )); } if ( ld->ld_connect_fn == NULL ) { if ( tcpconnect( tcps, address, port ) == 0 ) { err = -1; } else { err = 0; } } else { struct sockaddr_in sin; (void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in )); sin.sin_family = AF_INET; sin.sin_port = port; sin.sin_addr.s_addr = address; err = ld->ld_connect_fn( tcps, (struct sockaddr *)&sin, sizeof( struct sockaddr_in )); } if ( err == 0 ) { sb->sb_sd = (void *)tcps; return( 0 ); } if ( host == NULL ) { /* using single address -- not hi.addrs array */ break; } } LDAPDebug( LDAP_DEBUG_TRACE, "tcpconnect failed\n", 0, 0, 0 ); LDAP_SET_LDERRNO( ld, LDAP_CONNECT_ERROR, NULL, NULL ); LDAP_SET_ERRNO( ld, EHOSTUNREACH ); /* close enough */ if ( ld->ld_close_fn == NULL ) { tcpclose( (tcpstream *)tcps ); } else { ld->ld_close_fn( tcps ); } return( -1 ); }
void ldap_build_filter( char *filtbuf, unsigned long buflen, char *pattern, char *prefix, char *suffix, char *attr, char *value, char **valwords ) { char *p, *f; size_t slen; int i, wordcount, wordnum, endwordnum; if ( valwords == NULL ) { wordcount = 0; } else { for ( wordcount = 0; valwords[ wordcount ] != NULL; ++wordcount ) { ; } } f = filtbuf; if ( prefix != NULL ) { strcpy( f, prefix ); f += strlen( prefix ); } for ( p = pattern; *p != '\0'; ++p ) { if ( *p == '%' ) { ++p; if ( *p == 'v' ) { if ( isdigit( *(p+1))) { ++p; wordnum = *p - '1'; if ( *(p+1) == '-' ) { ++p; if ( isdigit( *(p+1))) { ++p; endwordnum = *p - '1'; /* e.g., "%v2-4" */ if ( endwordnum > wordcount - 1 ) { endwordnum = wordcount - 1; } } else { endwordnum = wordcount - 1; /* e.g., "%v2-" */ } } else { endwordnum = wordnum; /* e.g., "%v2" */ } if ( wordcount > 0 ) { for ( i = wordnum; i <= endwordnum; ++i ) { if ( i > wordnum ) { /* add blank btw words */ *f++ = ' '; } slen = strlen( valwords[ i ] ); SAFEMEMCPY( f, valwords[ i ], slen ); f += slen; } } } else if ( *(p+1) == '$' ) { ++p; if ( wordcount > 0 ) { wordnum = wordcount - 1; slen = strlen( valwords[ wordnum ] ); SAFEMEMCPY( f, valwords[ wordnum ], slen ); f += slen; } } else if ( value != NULL ) { slen = strlen( value ); SAFEMEMCPY( f, value, slen ); f += slen; } } else if ( *p == 'a' && attr != NULL ) { slen = strlen( attr ); SAFEMEMCPY( f, attr, slen ); f += slen; } else { *f++ = *p; } } else { *f++ = *p; } if ( (unsigned long) (f - filtbuf) > buflen ) { /* sanity check */ --f; break; } } if ( suffix != NULL && (unsigned long) ( f - filtbuf ) < buflen ) { strcpy( f, suffix ); } else { *f = '\0'; } }
/* * Populate *bvp from "value" of length "vlen." * * If recognize_url_syntax is non-zero, :<fileurl is recognized. * If always_try_file is recognized and no file URL was found, an * attempt is made to stat and read the value as if it were the name * of a file. * * If reporterrs is non-zero, specific error messages are printed to * stderr. * * If successful, LDAPTOOL_FILEURL_SUCCESS is returned and bvp->bv_len * and bvp->bv_val are set (the latter is set to malloc'd memory). * Upon failure, a different LDAPTOOL_FILEURL_ error code is returned. */ int ldaptool_berval_from_ldif_value( const char *value, int vlen, struct berval *bvp, int recognize_url_syntax, int always_try_file, int reporterrs ) { int rc = LDAPTOOL_FILEURL_SUCCESS; /* optimistic */ const char *url = NULL; struct stat fstats; /* recognize "attr :< url" syntax if LDIF version is >= 1 */ if ( recognize_url_syntax && *value == '<' ) { for ( url = value + 1; isspace( *url ); ++url ) { ; /* NULL */ } if (strlen(url) < 6 || strncasecmp(url, "file:/", 6) != 0) { /* * We only support file:// like URLs for now. */ url = NULL; } } if ( NULL != url ) { char *path; rc = ldaptool_fileurl2path( url, &path ); switch( rc ) { case LDAPTOOL_FILEURL_NOTAFILEURL: if ( reporterrs ) fprintf( stderr, "%s: unsupported URL \"%s\";" " use a file:// URL instead.\n", ldaptool_progname, url ); break; case LDAPTOOL_FILEURL_MISSINGPATH: if ( reporterrs ) fprintf( stderr, "%s: unable to process URL \"%s\" --" " missing path.\n", ldaptool_progname, url ); break; case LDAPTOOL_FILEURL_NONLOCAL: if ( reporterrs ) fprintf( stderr, "%s: unable to process URL \"%s\" -- only" " local file:// URLs are supported.\n", ldaptool_progname, url ); break; case LDAPTOOL_FILEURL_NOMEMORY: if ( reporterrs ) perror( "ldaptool_fileurl2path" ); break; case LDAPTOOL_FILEURL_SUCCESS: if ( stat( path, &fstats ) != 0 ) { if ( reporterrs ) perror( path ); } else if ( fstats.st_mode & S_IFDIR ) { if ( reporterrs ) fprintf( stderr, "%s: %s is a directory, not a file\n", ldaptool_progname, path ); rc = LDAPTOOL_FILEURL_FILEIOERROR; } else { rc = berval_from_file( path, bvp, reporterrs ); } free( path ); break; default: if ( reporterrs ) fprintf( stderr, "%s: unable to process URL \"%s\"" " -- unknown error\n", ldaptool_progname, url ); } } else if ( always_try_file && (stat( value, &fstats ) == 0) && !(fstats.st_mode & S_IFDIR)) { /* get value from file */ rc = berval_from_file( value, bvp, reporterrs ); } else { /* use value as-is */ bvp->bv_len = vlen; if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) { if ( reporterrs ) perror( "malloc" ); rc = LDAPTOOL_FILEURL_NOMEMORY; } else { SAFEMEMCPY( bvp->bv_val, value, vlen ); bvp->bv_val[ vlen ] = '\0'; } } return( rc ); }