Index: nslcd/pam.c =================================================================== --- nslcd/pam.c (revision 1068) +++ nslcd/pam.c (working copy) @@ -28,13 +28,20 @@ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ +#include #include "common.h" #include "log.h" #include "myldap.h" #include "cfg.h" #include "attmap.h" +#include "common/dict.h" +#include "common/expr.h" +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif /* not HOST_NAME_MAX */ + /* set up a connection and try to bind with the specified DN and password returns a NSLCD_PAM_* error code */ static int try_bind(const char *userdn,const char *password) @@ -174,6 +181,50 @@ return 0; } +static const char *entry_expand(const char *name,void *expander_attr) +{ + DICT *dict=(DICT *)expander_attr; + return (const char *)dict_get(dict,name); + /* FIXME: perform proper escaping of the values using myldap_escape() + (maybe before it gets put in the dict?) */ + /* TODO: if not set use entry to get attribute name (entry can be an + element in the dict) */ +} + +static int try_autzsearch(MYLDAP_SESSION *session,DICT *dict,const char *searchfilter) +{ + char filter_buffer[1024]; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + static const char *attrs[2]; + int rc; + /* build the search filter */ + if (expr_parse(searchfilter,filter_buffer,sizeof(filter_buffer),entry_expand,(void *)dict)==NULL) + { + log_log(LOG_ERR,"authorisation search \"%s\" is invalid",searchfilter); + return -1; + } + /* perform the search */ + attrs[0]="dn"; + attrs[1]=NULL; + search=myldap_search(session,nslcd_cfg->ldc_bases[0],LDAP_SCOPE_SUB, + filter_buffer,attrs); + if (search==NULL) + { + log_log(LOG_ERR,"authorisation search \"%s\" failed",filter_buffer); + return -1; + } + /* try to get an entry */ + entry=myldap_get_entry(search,&rc); + if (entry==NULL) + { + log_log(LOG_ERR,"no entry found"); + return -1; + } + /* we've found an entry so it's OK */ + return 0; +} + /* check authorisation of the user */ int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session) { @@ -184,6 +235,9 @@ char ruser[32]; char rhost[256]; char tty[256]; + char hostname[HOST_NAME_MAX+1]; + const char *searchfilter="(&(objectClass=posixAccount)(uid=$username)(|(authorizedService=$service)(!authorizedService=*)))"; + DICT *dict; /* read request parameters */ READ_STRING(fp,username); READ_STRING(fp,userdn); @@ -204,6 +258,21 @@ return -1; } /* TODO: perform any authorisation checks */ + dict=dict_new(); + dict_put(dict,"username",username); + dict_put(dict,"service",servicename); + dict_put(dict,"ruser",ruser); + dict_put(dict,"rhost",rhost); + dict_put(dict,"tty",tty); + if (gethostname(hostname,sizeof(hostname))==0) + dict_put(dict,"hostname",hostname); + dict_put(dict,"dn",userdn); + dict_put(dict,"uid",userdn); + if (try_autzsearch(session,dict,searchfilter)) + { + log_log(LOG_DEBUG,"authorisation failed"); + } + dict_free(dict); /* write response */ WRITE_INT32(fp,NSLCD_RESULT_BEGIN); WRITE_STRING(fp,username);