2014-04-01 22 views
5

chcę zrobić kwerendę przeciwko katalogu LDAP, jak pracownicy są dystrybuowane w działów i grup ...Jak uruchomić zapytanie ldap za pomocą R?

Coś jak: „Daj mi nazwę oddziału wszystkich członków grupy”, a następnie użyć R dokonać analizy częstotliwości, ale nie mogę znaleźć żadnych przykładów, w jaki sposób podłączyć i uruchomić kwerendę LDAP przy użyciu R.

RCurl wydaje się mieć jakieś wsparcie (http://cran.r-project.org/web/packages/RCurl/index.html):

Dodatkowo podstawowe wdrożenie jest solidne i rozległe, wspierające FTP/FTPS/TFTP (dodane i pliki do pobrania), SSL/HTTPS, Telnet, dict, LDAP, i obsługuje również pliki cookie, przekierowania, uwierzytelnianie, itp

ale ja nie jestem ekspertem w dziedzinie badań i nie udało się znaleźć ani jednego przykładu używając RCurl (lub jakąkolwiek inną bibliotekę R), aby to zrobić ..

teraz używam CURL tak aby uzyskać członków grupy:

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

Ktoś tutaj wie, jak to zrobić w R z RCurl?

+2

Chcemy wiedzieć nieco więcej o konfiguracji serwera LDAP. Przykładowe zapytanie LDAP za pośrednictwem 'curl -u USERNAME 'ldap: //192.168.0.66/CN=Users,DC=training,DC=local \? SAMAccountName? Sub? (ObjectClass = *)'' (pochodzi z przykładu IBM) . To nie zadziała, ponieważ musisz znać odpowiednie parametry wyszukiwania. Łatwo jest uruchomić to poprzez 'RCurl', a następnie przetworzyć wyniki, ale jeśli powinieneś najpierw uzyskać zapytanie działające z' curl' na linii poleceń. – hrbrmstr

+1

W tej chwili pobieram listę członków grupy podobnej do tej: 'ldapsearch -t -h ldap.replaceme.com -x -b" o = replaceme.com "" (cn = nazwa grupy) "memberuid' – Luxspes

+0

@hrbrmstr, jeśli potrafisz przetłumaczyć moje 'ldapsearch' na' curl', a następnie na 'R' przy pomocy' RCurl', to byłaby dokładna odpowiedź, której szukam ... – Luxspes

Odpowiedz

5

znaleźć odpowiedź sobie:

Pierwsze uruchomienie tego polecenia, aby upewnić RCurl jest zainstalowany (jak opisano w http://www.programmingr.com/content/webscraping-using-readlines-and-rcurl/):

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

I wtedy użytkownik getURL z LDAP URL (jak opisano w http://www.ietf.org/rfc/rfc2255.txt chociaż nie mogłem tego zrozumieć, dopóki nie przeczytałem http://docs.oracle.com/cd/E19396-01/817-7616/ldurl.html i zobaczył ldap[s]://hostname:port/base_dn?attributes?scope?filter):

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

W związku z tym jest to doskonały przewodnik na temat korzystania z RCurl http://www.omegahat.org/RCurl/RCurlJSS. pdf – Luxspes

5

Napisałem tutaj funkcję do parsowania danych wyjściowych ldap w ramkę danych, a ja użyłem przykładów dostarczonych jako odniesienie do uzyskania wszystkiego.

Mam nadzieję, że komuś pomóż!

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

Śledziłem tę strategię:

  1. uruchomić skrypt Perl z kwerendy LDAP, zapis danych na płycie jako JSON.
  2. odczytać w strukturze json za pomocą R, utworzyć ramkę danych.

dla etapu (1), użyłem tego skryptu:

#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; 

Być może trzeba sprawdzić limit rozmiaru max wpisów zwróconych przez serwer LDAP. Zobacz https://serverfault.com/questions/328671/paging-using-ldapsearch

Na etapie (2), użyłem tego kodu R:

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) 
Powiązane problemy