如何使用R运行ldap查询?

时间:2014-04-01 18:23:25

标签: r ldap statistics rcurl ldap-query

我想针对LDAP目录查询员工如何在部门和组中分发......

类似于:“给我一个组的所有成员的部门名称”,然后使用R进行频率分析,但我找不到任何关于如何连接和运行的示例使用R。

的LDAP查询

RCurl似乎有某种支持(http://cran.r-project.org/web/packages/RCurl/index.html):

  

此外,基础实施是强大而广泛的,   支持FTP / FTPS / TFTP(上传和下载),SSL / HTTPS,telnet,   dict, ldap ,还支持cookie,重定向,身份验证等。

但我不是R的专家,并且无法使用RCurl(或任何其他R库)找到一个例子来做这件事。

现在我正在使用 CURL 来获取群组成员:

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

这里的任何人都知道如何在RC中使用RCurl做同样的事情吗?

4 个答案:

答案 0 :(得分:7)

自己找到答案:

首先运行此命令以确保安装RCurl(如http://www.programmingr.com/content/webscraping-using-readlines-and-rcurl/中所述):

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

然后使用ldap网址向用户getURL(如http://www.ietf.org/rfc/rfc2255.txt中所述,但在我阅读http://docs.oracle.com/cd/E19396-01/817-7616/ldurl.html并看到ldap[s]://hostname:port/base_dn?attributes?scope?filter之前我无法理解):

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

答案 1 :(得分:5)

我已在此处编写了一个函数来将ldap输出解析为数据帧,并且我使用提供的示例作为参考来获取所有内容。

我希望它有所帮助!

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)
}

答案 2 :(得分:0)

我遵循了这个策略:

  1. 运行带有LDAP查询的Perl脚本,将数据作为JSON写入光盘。
  2. 用R读入json结构,创建一个数据帧。
  3. 对于步骤(1),我使用了这个脚本:

    Session lSession = Session.getDefaultInstance(props);
    MStorStore lStore = new MStorStore(lSession , new URLName("mstor:c:/some_path/" + _mailModel.account.login));
    lStore.connect(_mailModel.account.imap, _mailModel.account.login, _mailModel.account.password);
    Folder lInbox = lStore.getDefaultFolder().getFolder("Inbox");
    

    您可能需要检查ldap服务器返回的条目的最大大小限制。 见https://serverfault.com/questions/328671/paging-using-ldapsearch

    对于步骤(2),我使用了这个R代码:

    #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 "$@";
    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;
    

答案 3 :(得分:0)

我编写了一个R库,用于使用openldap库访问ldap服务器。 详细地,函数searchldap是openldap方法searchldap的包装。 https://github.com/LukasK13/ldapr