Index: ldap_map.h =================================================================== RCS file: /usr/local/src/cvsroot/sendmail.8.9/src/ldap_map.h,v retrieving revision 1.1.1.8 retrieving revision 1.9 diff -u -r1.1.1.8 -r1.9 --- ldap_map.h 1999/02/15 19:35:30 1.1.1.8 +++ ldap_map.h 1999/02/15 20:04:06 1.9 @@ -37,8 +37,8 @@ /* args for ldap_bind_s */ LDAP *ld; char *binddn; - char *passwd; - int method; + char *secret; + int method; /* args for ldap_search_st */ char *base; @@ -55,13 +55,32 @@ #define DEFAULT_LDAP_MAP_PORT LDAP_PORT #define DEFAULT_LDAP_MAP_SCOPE LDAP_SCOPE_SUBTREE #define DEFAULT_LDAP_MAP_BINDDN NULL -#define DEFAULT_LDAP_MAP_PASSWD NULL +#define DEFAULT_LDAP_MAP_SECRET NULL #define DEFAULT_LDAP_MAP_METHOD LDAP_AUTH_SIMPLE #define DEFAULT_LDAP_MAP_TIMELIMIT 5 #define DEFAULT_LDAP_MAP_DEREF LDAP_DEREF_NEVER #define DEFAULT_LDAP_MAP_SIZELIMIT 0 #define DEFAULT_LDAP_MAP_ATTRSONLY 0 #define LDAP_MAP_MAX_FILTER 1024 + +/* authentication methods available */ + +#define LDAP_MAP_AUTH_METHOD_MAX 3 +#define LDAP_MAP_MAX_PASSWD 256 + +char *ldap_map_auth_methods[] = { + "LDAP_AUTH_NONE", + "LDAP_AUTH_SIMPLE", + "LDAP_AUTH_KRBV4" +} ; + +int ldap_map_auth_methods_code[LDAP_MAP_AUTH_METHOD_MAX] = { + LDAP_AUTH_NONE, + LDAP_AUTH_SIMPLE, + LDAP_AUTH_KRBV4 +} ; + + #ifdef LDAP_REFERRALS # define DEFAULT_LDAP_MAP_LDAP_OPTIONS LDAP_OPT_REFERRALS #else /* LDAP_REFERRALS */ Index: map.c =================================================================== RCS file: /usr/local/src/cvsroot/sendmail.8.9/src/map.c,v retrieving revision 1.1.1.11 retrieving revision 1.20 diff -u -r1.1.1.11 -r1.20 --- map.c 1999/02/15 19:35:31 1.1.1.11 +++ map.c 1999/03/30 21:22:41 1.20 @@ -2621,6 +2621,10 @@ #endif return FALSE; } + /* We could call aliaswait here, but it only adds extra + code to the ldap map lookup. The aliaswait "@:@" convention + does not make much sense in the ldap tcp-based model. + */ return TRUE; } @@ -2647,7 +2651,7 @@ LDAP_MAP_STRUCT *lmap; LDAP *ld; register EVENT *ev = NULL; - + register int bind_result; if (tTd(38, 2)) printf("ldap_map_start(%s)\n", map->map_mname); @@ -2713,12 +2717,12 @@ lmap->ld = ld; return TRUE; #else - if (ldap_bind_s(ld, lmap->binddn,lmap->passwd,lmap->method) != LDAP_SUCCESS) + if (ldap_bind_s(ld, lmap->binddn,lmap->secret,lmap->method) != LDAP_SUCCESS) { if (!bitset(MF_OPTIONAL, map->map_mflags)) { - syserr("421 Cannot bind to map %s in ldap server %s", - map->map_mname, lmap->ldaphost); + syserr("421 Cannot bind to map %s in ldap server %s, %s", + map->map_mname, lmap->ldaphost,ldap_err2string(bind_result)); } } else @@ -2727,7 +2731,6 @@ lmap->ld = ld; return TRUE; } - return FALSE; #endif } @@ -2811,13 +2814,13 @@ { LDAP_MAP_STRUCT *lmap = NULL; LDAPMessage *entry; - char *vp; + char *vp,*vp_tmp; auto int vsize; char keybuf[MAXNAME + 1]; char filter[LDAP_MAP_MAX_FILTER + 1]; char **attr_values = NULL; - char *result; - int name_len; + char *result,*tmp; + int name_len,val_count,i; char *fp, *p, *q; if (tTd(38, 20)) @@ -2899,39 +2902,88 @@ } } + result = NULL; + *statp = EX_NOTFOUND; + entry = ldap_first_entry(lmap->ld,lmap->res); if (entry == NULL) { - result = NULL; - *statp = EX_NOTFOUND; goto quick_exit; } - /* Need to build the args for map_rewrite here */ - attr_values = ldap_get_values(lmap->ld,entry,lmap->attr[0]); - if (attr_values == NULL) - { - /* bad things happened */ - result = NULL; - *statp = EX_NOTFOUND; - goto quick_exit; + vp = NULL ; + + /* Cycle through all entries. */ + do { + /* Need to build the args for map_rewrite here */ + attr_values = ldap_get_values(lmap->ld,entry,lmap->attr[0]); + if (attr_values != NULL ) + { + *statp = EX_OK; + + /* + * If there is more that one munge then into + * a comma sep string + */ + val_count = ldap_count_values(attr_values) ; + /* count size */ + vsize = 0 ; + for( i = 0 ; i < val_count && attr_values[i] != NULL ; i++ ) { + vsize += strlen(attr_values[i]) + strlen(", ") ; + } + vp_tmp = (char * ) malloc(vsize) ; + if ( vp_tmp != NULL ) + { + /* first */ + snprintf(vp_tmp,vsize,"%s",attr_values[0]) ; + tmp = vp_tmp + strlen(vp_tmp); + /*rest */ + for( i = 1 ; i < (val_count ) && attr_values[i] != NULL ; i++ ) { + snprintf(tmp,(vsize - strlen(vp_tmp)),", %s",attr_values[i]) ; + tmp = vp_tmp + strlen(vp_tmp) ; + } + + } else { + /* Report memory error */ + if (!bitset(MF_OPTIONAL, map->map_mflags)) + { + syserr("Out of memory in ldap_map_lookup"); + } + } + } + if ( vp == NULL ) + { + vp = vp_tmp ; + } else { + vsize = strlen(vp) + strlen(vp_tmp) + strlen(", ") + 1 ; + tmp = ( char *) malloc( vsize ) ; + snprintf(tmp,vsize,"%s, %s",vp,vp_tmp) ; + /* Free things in correct order. */ + free ( vp_tmp) ; /* vsize malloc above */ + vp_tmp = vp ; /* tmp malloc from previous loop */ + vp = tmp ; + free ( vp_tmp ) ; + } + ldap_value_free(attr_values); + attr_values = NULL ; + + } while ( (entry = ldap_next_entry( lmap->ld, entry ) ) != NULL ) ; + + if ( *statp == EX_OK ) { + + vsize = strlen(vp); + + if (LogLevel > 9) + sm_syslog(LOG_INFO, CurEnv->e_id, + "ldap %.100s => %s", + name, vp); + if (bitset(MF_MATCHONLY, map->map_mflags)) + result = map_rewrite(map, name, strlen(name), NULL); + else + result = map_rewrite(map, vp, vsize, av); + free(vp) ; + } - - *statp = EX_OK; - - /* If there is more that one use the first */ - vp = attr_values[0]; - vsize = strlen(vp); - - if (LogLevel > 9) - sm_syslog(LOG_INFO, CurEnv->e_id, - "ldap %.100s => %s", - name, vp); - if (bitset(MF_MATCHONLY, map->map_mflags)) - result = map_rewrite(map, name, strlen(name), NULL); - else - result = map_rewrite(map, vp, vsize, av); - quick_exit: if (attr_values != NULL) ldap_value_free(attr_values); @@ -2982,8 +3034,12 @@ char *args; { register char *p = args; - register int done; + register int done,i; LDAP_MAP_STRUCT *lmap; + static char m_tmp[MAXPATHLEN+LDAP_MAP_MAX_PASSWD]; + FILE * sfd ; + int sff = SFF_OPENASROOT|SFF_ROOTOK|SFF_NOWLINK|SFF_NOWWFILES|SFF_NOGWFILES; + char *tmp ; /* We need to alloc an LDAP_MAP_STRUCT struct */ lmap = (LDAP_MAP_STRUCT *) xalloc(sizeof(LDAP_MAP_STRUCT)); @@ -3002,7 +3058,8 @@ /* Default char ptrs to NULL */ lmap->binddn = NULL; - lmap->passwd = NULL; + + lmap->secret = NULL; lmap->base = NULL; lmap->ldaphost = NULL; @@ -3088,7 +3145,9 @@ break; case 's': /* search scope */ - if (strncasecmp(++p, "base", 4) == 0) + while (isascii(*++p) && isspace(*p)) + continue; + if (strncasecmp(p, "base", 4) == 0) { lmap->scope = LDAP_SCOPE_BASE; } @@ -3142,7 +3201,36 @@ lmap->timelimit = atoi(p); lmap->timeout.tv_sec = lmap->timelimit; break; - + case 'D': /* Dn to bind to server as */ + while (isascii(*++p) && isspace(*p)) + continue; + lmap->binddn = p; + break; + case 'M': /* Method for binding */ + while (isascii(*++p) && isspace(*p)) + continue; + /* Need to map ascii method to int here */ + tmp = p ; + /* Argh, can't use ldap_map_dequote here */ + if ( *tmp == '"' ) { + while ( isascii(*++tmp) && isspace(*tmp)) + continue; + } + for(i = 0 ; i < LDAP_MAP_AUTH_METHOD_MAX ; i++ ) { + if ( strncmp(tmp,ldap_map_auth_methods[i],strlen(ldap_map_auth_methods[i])) == 0 ) { + lmap->method = ldap_map_auth_methods_code[i] ; + } + } + + break ; + /* This is a string that is dependent on the + * method used defined above. + */ + case 'S': /* Secret for binding */ + while (isascii(*++p) && isspace(*p)) + continue; + lmap->secret = p ; + break ; } /* need to account for quoted strings here arggg... */ @@ -3189,16 +3277,60 @@ return FALSE; } - if (lmap->binddn != NULL) - lmap->binddn = newstr(ldap_map_dequote(lmap->binddn)); + if (lmap->binddn != NULL) { + lmap->binddn = newstr(ldap_map_dequote(lmap->binddn)); + + if ( lmap->secret != NULL ) { + /* need to use method to map secret to passwd string */ + switch(lmap->method) + { + + case LDAP_AUTH_NONE: /* Do nothing */ + break; + case LDAP_AUTH_SIMPLE: /* Secret is the name of a file with + the first line as the pwd. */ + + + sfd = safefopen(ldap_map_dequote(lmap->secret),O_RDONLY,0,sff); + if ( sfd == NULL ) + { + syserr("LDAP map: cannot open secret %s",ldap_map_dequote(lmap->secret)); + return FALSE ; + } else + { + lmap->secret = sfgets(m_tmp,LDAP_MAP_MAX_PASSWD,sfd,0,"ldap_map_parseargs") ; + fclose(sfd) ; + if ( lmap->secret != NULL ) + { + /* chomp newline */ + if (m_tmp[strlen(m_tmp)-1] == '\n') + m_tmp[strlen(m_tmp)-1] = '\0'; + + lmap->secret = newstr(m_tmp) ; + } + } + break ; + case LDAP_AUTH_KRBV4: /* Secret is where the tgt file + is stashed */ + /* We could be paranoid here.. */ + snprintf(m_tmp,MAXPATHLEN+LDAP_MAP_MAX_PASSWD,"KRBTKFILE=%s",ldap_map_dequote(lmap->secret)); + putenv(m_tmp); + lmap->secret = NULL ; + break ; + default : /* Should NEVER get here */ + syserr("LDAP map: Garbage in lmap method" ) ; + return FALSE ; + break ; + } /* end switch */ + } + } else lmap->binddn = DEFAULT_LDAP_MAP_BINDDN; - - if (lmap->passwd != NULL) - lmap->passwd = newstr(ldap_map_dequote(lmap->passwd)); + if (lmap->secret != NULL) + lmap->secret = newstr(ldap_map_dequote(lmap->secret)); else - lmap->passwd = DEFAULT_LDAP_MAP_PASSWD; + lmap->secret = DEFAULT_LDAP_MAP_SECRET; if (lmap->base != NULL) lmap->base = newstr(ldap_map_dequote(lmap->base));