2014-04-01 5 views
5

ich eine Abfrage für ein LDAP-Verzeichnis, wie die Mitarbeiter verteilt werden in Abteilungen und Gruppen ...Wie führe ich eine ldap Abfrage mit R?

So etwas machen will: „Gib mir die Abteilungsnamen aller Mitglieder einer Gruppe“ und anschließend mit R, um eine Frequenzanalyse zu machen, aber ich kann keine Beispiele finden, wie eine LDAP-Abfrage mit R.

RCurl irgendeine Art von Unterstützung zu verbinden und führt zu haben scheint (http://cran.r-project.org/web/packages/RCurl/index.html):

Zusätzlich Die zugrunde liegende Implementierung ist robust und umfangreich, unterstützt FTP/FTPS/TFTP (Up- und Downloads), SSL/HTTPS, Telnet, dict, ldap und unterstützt auch Cookies, Umleitungen, Authentifizierung etc.

Aber ich bin kein Experte in R und konnte nicht ein einziges Beispiel mit RCurl (oder anderer R Bibliothek) finden, dies zu tun ..

Im Moment bin ich mit ROTATION wie dies die Mitglieder einer Gruppe zu erhalten:

curl "ldap://ldap.replaceme.com/o=replaceme.com?memberuid?sub?(cn=group-name)" 

Jeder hier weiß, wie man das gleiche in R mit RCurl macht?

+2

Wir bräuchten ein bisschen mehr über die LDAP-Server-Konfiguration kennen. Eine Beispiel-LDAP-Abfrage über 'curl -u USERNAME 'ldap: //192.168.0.66/CN=Users,DC=training,DC=local \' sAMAccountName? Sub? (ObjectClass = *) '' (aus einem IBM-Beispiel) . Es wird nicht für Sie arbeiten, da Sie die richtigen Suchparameter kennen müssen. Es ist ziemlich einfach, das über 'RCurl' zu starten und dann die Ergebnisse zu verarbeiten, aber wenn Sie die Abfrage von' curl' in der Befehlszeile starten sollten. – hrbrmstr

+1

Im Moment lade ich die Liste der Mitglieder einer Gruppe wie folgt ab: 'ldapsearch -t -h ldap.replaceme.com -x -b" o = replaceme.com "" (cn = Gruppenname) "memberuid' – Luxspes

+0

@hrbrmstr Wenn du mein 'ldapsearch' in' curl' und dann in 'R' mit' RCurl' übersetzen kannst, wäre das genau die Antwort, die ich suche ... – Luxspes

Antwort

5

die Antwort selbst gefunden:

Erstausstrahlung diese sicher RCurl machen Befehle installiert ist (wie in http://www.programmingr.com/content/webscraping-using-readlines-and-rcurl/ beschrieben):

install.packages("RCurl", dependencies = TRUE) 
library("RCurl") 

Und dann mit einem LDAP-URL Benutzer getURL (wie in http://www.ietf.org/rfc/rfc2255.txt beschrieben obwohl ich es nicht verstehen konnte, bis ich http://docs.oracle.com/cd/E19396-01/817-7616/ldurl.html lesen und sah ldap[s]://hostname:port/base_dn?attributes?scope?filter):

getURL("ldap://ldap.replaceme.com/o=replaceme.com?memberuid?sub?(cn=group-name)") 
+0

Auf eine verwandte Anmerkung ist dies eine ausgezeichnete Anleitung zur Verwendung von RCurl http://www.omegahat.org/RCurl/RCurlJSS. pdf – Luxspes

5

Ich habe hier eine Funktion geschrieben, um ldap-Ausgabe in einen Datenrahmen zu parsen, und ich habe die Beispiele als Referenz verwendet, um alles in Gang zu bringen.

Ich hoffe, es hilft jemandem!

library(RCurl) 
library(gtools) 

parseldap<-function(url, userpwd=NULL) 
{ 
    ldapraw<-getURL(url, userpwd=userpwd) 
    # seperate by two new lines 
    ldapraw<-gsub("(DN: .*?)\n", "\\1\n\n", ldapraw) 
    ldapsplit<-strsplit(ldapraw, "\n\n") 
    ldapsplit<-unlist(ldapsplit) 
    # init list and count 
    mylist<-list() 
    count<-0 
    for (ldapline in ldapsplit) { 
    # if this is the beginning of the entry 
    if(grepl("^DN:", ldapline)) { 
     count<-count+1 
     # after the first 
     if(count == 2) { 
     df<-data.frame(mylist) 
     mylist<-list() 
     } 
     if(count > 2) { 
     df<-smartbind(df, mylist) 
     mylist<-list() 
     } 
     mylist["DN"] <-gsub("^DN: ", "", ldapline) 
    } else { 
     linesplit<-unlist(strsplit(ldapline, "\n")) 
     if(length(linesplit) > 1) { 
     for(line in linesplit) { 
      linesplit2<-unlist(strsplit(line, "\t")) 
      linesplit2<-unlist(strsplit(linesplit2[2], ": ")) 
      if(!is.null(unlist(mylist[linesplit2[1]]))) { 
      x<-strsplit(unlist(mylist[linesplit2[1]]), "|", fixed=TRUE) 

      x<-append(unlist(x), linesplit2[2]) 
      x<-paste(x, sep="", collapse="|") 
      mylist[linesplit2[1]] <- x 
      } else { 
      mylist[linesplit2[1]] <- linesplit2[2] 
      } 
     } 
     } else { 
     ldaplinesplit<-unlist(strsplit(ldapline, "\t")) 
     ldaplinesplit<-unlist(strsplit(ldaplinesplit[2], ": ")) 
     mylist[ldaplinesplit[1]] <- ldaplinesplit[2] 
     } 

    } 

    } 
    if(count == 1) { 
    df<-data.frame(mylist) 
    } else { 
    df<-smartbind(df, mylist) 
    } 
    return(df) 
} 
0

Ich folgte diese Strategie:

  1. Laufe eines Perl-Skript mit einer LDAP-Abfrage, Schreiben von Daten auf Disk als JSON.
  2. lesen Sie in der JSON-Struktur mit R, erstellen Sie einen Datenrahmen.

Für Schritt (1), habe ich dieses Skript:

#use Modern::Perl; 
use strict; 
use warnings; 
use feature 'say'; 
use Net::LDAP; 
use JSON; 
chdir("~/git/_my/R_one-offs/R_grabbag"); 
my $ldap = Net::LDAP->new('ldap.mydomain.de') or die "[email protected]"; 
my $outfile = "ldapentries_mydomain_ldap.json"; 
my $mesg = $ldap->bind ; # an anonymous bind 
# get all cn's (= all names) 
$mesg = $ldap->search(
       base => " ou=People,dc=mydomain,dc=de", 
       filter => "(cn=*)" 
      ); 

my $json_text = ""; 
my @entries; 

foreach my $entry ($mesg->entries){ 
my %entry; 
foreach my $attr ($entry->attributes) { 
    foreach my $value ($entry->get_value($attr)) { 
     $entry{$attr} = $value; 
    } 
    } 
    push @entries, \%entry; 
} 

$json_text = to_json(\@entries); 
say "Length json_text: " . length($json_text); 


open(my $FH, ">", $outfile); 
print $FH $json_text; 
close($FH); 
$mesg = $ldap->unbind; 

Sie könnten die eine maximale Größe Grenze von Einträgen vom LDAP-Server zurückgegeben müssen überprüfen. Siehe https://serverfault.com/questions/328671/paging-using-ldapsearch

Für Schritt (2), ich diesen R-Code verwendet:

setwd("~/git/_my/R_one-offs/R_grabbag") 
library(rjson) 
# read into R list, from file, created from perl script 
json <- rjson::fromJSON(file="ldapentries_mydomain_ldap.json",method = "C") 
head(json) 

# create a data frame from list 
library(reshape2) 
library(dplyr) 
library(tidyr) 

# not really efficient, maybe thre's a better way to do it 
df.ldap <- json %>% melt %>% spread(L2,value) 

# optional: 
# turn factors into characters 
i <- sapply(df.ldap, is.factor) 
df.ldap[i] <- lapply(df.ldap[i], as.character) 
Verwandte Themen