mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-29 20:54:04 +00:00
394 lines
7.8 KiB
C
394 lines
7.8 KiB
C
#ifdef UWSGI_LDAP
|
|
|
|
#include "uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
#include <ldap.h>
|
|
|
|
#ifndef LDAP_OPT_SUCCESS
|
|
#define LDAP_OPT_SUCCESS LDAP_SUCCESS
|
|
#endif
|
|
|
|
#ifndef ldap_unbind_ext_s
|
|
#define ldap_unbind_ext_s ldap_unbind_ext
|
|
#endif
|
|
|
|
void ldap2uwsgi(char *ldapname, char *uwsginame) {
|
|
char *ptr = uwsginame;
|
|
|
|
int i;
|
|
|
|
for(i=0;i< (int) strlen(ldapname);i++) {
|
|
if (isupper( (int)ldapname[i])) {
|
|
*ptr++ = '-';
|
|
*ptr++ = tolower( (int) ldapname[i]);
|
|
}
|
|
else {
|
|
*ptr++ = ldapname[i];
|
|
}
|
|
}
|
|
|
|
*ptr++= 0;
|
|
}
|
|
|
|
int calc_ldap_name(char *name) {
|
|
int i;
|
|
int counter = 0;
|
|
|
|
for(i=0;i< (int)strlen(name);i++) {
|
|
if (isupper( (int) name[i])) {
|
|
counter++;
|
|
}
|
|
}
|
|
|
|
return strlen(name) + counter;
|
|
}
|
|
|
|
struct uwsgi_ldap_entry {
|
|
int num;
|
|
char names[1024];
|
|
int has_arg;
|
|
};
|
|
|
|
|
|
void uwsgi_name_to_ldap(char *src, char *dst) {
|
|
|
|
int i;
|
|
char *ptr = dst;
|
|
|
|
memset(dst, 0, 1024);
|
|
|
|
strcat(dst, " 'uWSGI");
|
|
|
|
ptr+= 7;
|
|
|
|
for(i=0;i< (int)strlen(src);i++) {
|
|
if (src[i] == '-') {
|
|
i++;
|
|
*ptr++= toupper( (int) src[i]);
|
|
}
|
|
else {
|
|
*ptr++= src[i];
|
|
}
|
|
}
|
|
|
|
strcat(dst, "'");
|
|
|
|
}
|
|
|
|
struct uwsgi_ldap_entry *get_ldap_by_num(struct uwsgi_ldap_entry *root, int num, int count) {
|
|
|
|
int i;
|
|
struct uwsgi_ldap_entry *ule;
|
|
|
|
for(i=0;i<count;i++) {
|
|
ule = &root[i];
|
|
if (ule->num == num) {
|
|
return ule;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *name, int count) {
|
|
int i;
|
|
struct uwsgi_ldap_entry *ule;
|
|
|
|
for(i=0;i<count;i++) {
|
|
ule = &root[i];
|
|
if (uwsgi_list_has_str(ule->names, name+1)) {
|
|
return ule;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct uwsgi_ldap_entry *get_ldap_names(int *count) {
|
|
|
|
struct option *aopt, *lopt;
|
|
struct uwsgi_ldap_entry *ule, *entry;
|
|
char ldap_name[1024];
|
|
static int counter = 30000000;
|
|
|
|
*count = 0;
|
|
lopt = uwsgi.long_options;
|
|
|
|
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry)*count_options(lopt));
|
|
|
|
while( (aopt = lopt) ) {
|
|
if (!aopt->name)
|
|
break;
|
|
|
|
uwsgi_name_to_ldap((char *)aopt->name, ldap_name);
|
|
|
|
entry = search_ldap_cache(ule, ldap_name, *count);
|
|
|
|
if (entry) goto next;
|
|
|
|
if (aopt->flag) {
|
|
entry = &ule[*count] ;
|
|
entry->num = counter;
|
|
strcpy(entry->names, ldap_name);
|
|
counter++;
|
|
*count = *count+1;
|
|
}
|
|
else {
|
|
entry = get_ldap_by_num(ule, aopt->val, *count);
|
|
if (entry) {
|
|
strcat(entry->names, ldap_name);
|
|
}
|
|
else {
|
|
entry = &ule[*count] ;
|
|
entry->num = aopt->val;
|
|
strcpy(entry->names, ldap_name);
|
|
*count = *count+1;
|
|
}
|
|
}
|
|
|
|
entry->has_arg = aopt->has_arg;
|
|
|
|
next:
|
|
lopt++;
|
|
}
|
|
|
|
return ule;
|
|
}
|
|
|
|
void uwsgi_ldap_schema_dump_ldif() {
|
|
|
|
int i;
|
|
int items;
|
|
|
|
uwsgi_log("\n");
|
|
uwsgi_log("dn: cn=uwsgi,cn=schema,cn=config\n");
|
|
uwsgi_log("objectClass: olcSchemaConfig\n");
|
|
uwsgi_log("cn: uwsgi\n");
|
|
|
|
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
|
|
|
for(i=0;i<items;i++) {
|
|
|
|
entry = &ule[i];
|
|
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
|
|
|
if (entry->has_arg) {
|
|
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
|
}
|
|
else {
|
|
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
|
}
|
|
}
|
|
|
|
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
|
|
|
|
|
uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
|
|
|
|
|
for(i=0;i<items;i++) {
|
|
|
|
entry = &ule[i];
|
|
|
|
char *list2 = uwsgi_concat2(entry->names+1, "");
|
|
char *p = strtok(list2, " ");
|
|
while (p != NULL) {
|
|
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
|
p = strtok(NULL, " ");
|
|
}
|
|
|
|
free(list2);
|
|
|
|
}
|
|
|
|
uwsgi_log("uWSGInull ))\n");
|
|
|
|
uwsgi_log("\n");
|
|
|
|
exit(0);
|
|
}
|
|
|
|
void uwsgi_ldap_schema_dump() {
|
|
|
|
int i;
|
|
int items;
|
|
|
|
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
|
|
|
for(i=0;i<items;i++) {
|
|
|
|
entry = &ule[i];
|
|
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
|
|
|
if (entry->has_arg) {
|
|
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
|
}
|
|
else {
|
|
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
|
}
|
|
}
|
|
|
|
|
|
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
|
|
|
uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
|
|
|
for(i=0;i<items;i++) {
|
|
|
|
entry = &ule[i];
|
|
|
|
char *list2 = uwsgi_concat2(entry->names+1, "");
|
|
char *p = strtok(list2, " ");
|
|
while (p != NULL) {
|
|
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
|
p = strtok(NULL, " ");
|
|
}
|
|
|
|
free(list2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uwsgi_log("uWSGInull ))\n");
|
|
|
|
exit(0);
|
|
}
|
|
|
|
void uwsgi_ldap_config() {
|
|
|
|
LDAP *ldp;
|
|
LDAPMessage *results, *entry;
|
|
BerElement *ber;
|
|
struct berval **bervalues;
|
|
char *attr;
|
|
char *uwsgi_attr;
|
|
|
|
char *url = "ldap:///";
|
|
char *url_slash;
|
|
|
|
int desired_version = LDAP_VERSION3;
|
|
int ret;
|
|
|
|
LDAPURLDesc *ldap_url;
|
|
|
|
if (uwsgi.ldap) {
|
|
url = uwsgi.ldap;
|
|
}
|
|
|
|
if (!ldap_is_ldap_url(url)) {
|
|
uwsgi_log("invalid LDAP url.\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (ldap_url_parse(url, &ldap_url) != LDAP_SUCCESS) {
|
|
uwsgi_log("unable to parse LDAP url.\n");
|
|
exit(1);
|
|
}
|
|
|
|
uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);
|
|
|
|
url_slash = strchr(url, '/');
|
|
url_slash = strchr(url_slash + 1, '/');
|
|
|
|
url_slash = strchr(url_slash + 1, '/');
|
|
if (url_slash) {
|
|
url_slash[0] = 0;
|
|
}
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("LDAP URL: %s\n", url);
|
|
uwsgi_debug("LDAP BASE DN: %s\n", ldap_url->lud_dn);
|
|
#endif
|
|
|
|
#if LDAP_API_VERSION >= 3000
|
|
if ( (ret = ldap_initialize( &ldp, url)) != LDAP_SUCCESS) {
|
|
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
|
exit(1);
|
|
}
|
|
#else
|
|
if ( (ldp = ldap_init( ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
|
|
uwsgi_error("ldap_init()");
|
|
exit(1);
|
|
}
|
|
#endif
|
|
|
|
|
|
if ( (ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
|
|
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
|
exit(1);
|
|
}
|
|
|
|
|
|
if ( (ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
|
|
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
|
exit(1);
|
|
}
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("LDAP connection initialized %p\n", ldp);
|
|
#endif
|
|
|
|
free(ldap_url);
|
|
|
|
if (ldap_count_entries(ldp, results) < 1) {
|
|
uwsgi_log("no LDAP entry found\n");
|
|
exit(1);
|
|
}
|
|
|
|
entry = ldap_first_entry(ldp, results);
|
|
|
|
int found = 0;
|
|
for( attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
|
|
if (!strncmp(attr,"uWSGI",5)) {
|
|
|
|
found = 1;
|
|
uwsgi_attr = malloc( calc_ldap_name(attr) + 1 );
|
|
if (!uwsgi_attr) {
|
|
uwsgi_error("malloc()");
|
|
exit(1);
|
|
}
|
|
|
|
ldap2uwsgi(attr+5, uwsgi_attr);
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_debug("LDAP attribute: %s = --%s\n", attr, uwsgi_attr);
|
|
#endif
|
|
bervalues = ldap_get_values_len(ldp, entry, attr);
|
|
if (bervalues) {
|
|
// do not free uwsgi_attr/uwsgi_val;
|
|
char *uwsgi_val = malloc( bervalues[0]->bv_len + 1 );
|
|
if (!uwsgi_val) {
|
|
uwsgi_error("malloc()");
|
|
exit(1);
|
|
}
|
|
|
|
memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
|
|
uwsgi_val[bervalues[0]->bv_len] = 0;
|
|
|
|
add_exported_option((char*) uwsgi_attr, uwsgi_val, 0);
|
|
free(bervalues);
|
|
}
|
|
else {
|
|
free(uwsgi_attr);
|
|
}
|
|
}
|
|
free(attr);
|
|
}
|
|
|
|
if (!found) {
|
|
uwsgi_log("no uWSGI LDAP entry found\n");
|
|
exit(1);
|
|
}
|
|
|
|
free(ber);
|
|
free(results);
|
|
|
|
ldap_unbind_ext_s(ldp, NULL, NULL);
|
|
|
|
}
|
|
#endif
|