⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 squid_ldap_auth.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 2 页
字号:
	    basedn = value;	    break;	case 'f':	    searchfilter = value;	    break;	case 'u':	    userattr = value;	    break;	case 'U':	    passwdattr = value;	    break;	case 's':	    if (strcmp(value, "base") == 0)		searchscope = LDAP_SCOPE_BASE;	    else if (strcmp(value, "one") == 0)		searchscope = LDAP_SCOPE_ONELEVEL;	    else if (strcmp(value, "sub") == 0)		searchscope = LDAP_SCOPE_SUBTREE;	    else {		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown search scope '%s'\n", value);		exit(1);	    }	    break;	case 'E':#if defined(NETSCAPE_SSL)	    sslpath = value;	    if (port == LDAP_PORT)		port = LDAPS_PORT;#else	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");	    exit(1);#endif	    break;	case 'c':	    connect_timeout = atoi(value);	    break;	case 't':	    timelimit = atoi(value);	    break;	case 'a':	    if (strcmp(value, "never") == 0)		aliasderef = LDAP_DEREF_NEVER;	    else if (strcmp(value, "always") == 0)		aliasderef = LDAP_DEREF_ALWAYS;	    else if (strcmp(value, "search") == 0)		aliasderef = LDAP_DEREF_SEARCHING;	    else if (strcmp(value, "find") == 0)		aliasderef = LDAP_DEREF_FINDING;	    else {		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown alias dereference method '%s'\n", value);		exit(1);	    }	    break;	case 'D':	    binddn = value;	    break;	case 'w':	    bindpasswd = value;	    break;	case 'W':	    readSecret(value);	    break;	case 'P':	    persistent = !persistent;	    break;	case 'O':	    bind_once = !bind_once;	    break;	case 'p':	    port = atoi(value);	    break;	case 'R':	    noreferrals = !noreferrals;	    break;#ifdef LDAP_VERSION3	case 'v':	    switch (atoi(value)) {	    case 2:		version = LDAP_VERSION2;		break;	    case 3:		version = LDAP_VERSION3;		break;	    default:		fprintf(stderr, "Protocol version should be 2 or 3\n");		exit(1);	    }	    break;	case 'Z':	    if (version == LDAP_VERSION2) {		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",		    version);		exit(1);	    }	    version = LDAP_VERSION3;	    use_tls = 1;	    break;#endif	case 'd':	    debug++;	    break;	default:	    fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown command line option '%c'\n", option);	    exit(1);	}    }    while (argc > 1) {	char *value = argv[1];	if (ldapServer) {	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;	    char *newhost = malloc(len);	    snprintf(newhost, len, "%s %s", ldapServer, value);	    free(ldapServer);	    ldapServer = newhost;	} else {	    ldapServer = strdup(value);	}	argc--;	argv++;    }    if (!ldapServer)	ldapServer = strdup("localhost");    if (!basedn) {	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn [options] [ldap_server_name[:port]]...\n\n");	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under which to search\n");	fprintf(stderr, "\t-f filter\t\tsearch filter to locate user DN\n");	fprintf(stderr, "\t-u userattr\t\tusername DN attribute\n");	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");#if HAS_URI_SUPPORT	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");#endif	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");	fprintf(stderr, "\t-p port\t\t\tLDAP server port\n");	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");#if defined(NETSCAPE_SSL)	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");#endif	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");#ifdef LDAP_VERSION3	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires LDAP version 3\n");#endif	fprintf(stderr, "\n");	fprintf(stderr, "\tIf no search filter is specified, then the dn <userattr>=user,basedn\n\twill be used (same as specifying a search filter of '<userattr>=',\n\tbut quicker as as there is no need to search for the user DN)\n\n");	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");	exit(1);    }/* On windows ldap_start_tls_s is available starting from Windows XP,  * so we need to bind at run-time with the function entry point */#ifdef _SQUID_MSWIN_    if (use_tls) {	HMODULE WLDAP32Handle;	WLDAP32Handle = GetModuleHandle("wldap32");	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");	    exit(1);	}    }#endif    while (fgets(buf, 256, stdin) != NULL) {	user = strtok(buf, " \r\n");	passwd = strtok(NULL, "\r\n");	if (!user || !passwd || !passwd[0]) {	    printf("ERR\n");	    continue;	}	rfc1738_unescape(user);	rfc1738_unescape(passwd);	if (!validUsername(user)) {	    printf("ERR No such user\n");	    continue;	}	tryagain = (ld != NULL);      recover:	if (ld == NULL && persistent)	    ld = open_ldap_connection(ldapServer, port);	if (checkLDAP(ld, user, passwd, ldapServer, port) != 0) {	    if (tryagain && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS) {		tryagain = 0;		ldap_unbind(ld);		ld = NULL;		goto recover;	    }	    printf("ERR %s\n", ldap_err2string(squid_ldap_errno(ld)));	} else {	    printf("OK\n");	}	if (ld && (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {	    ldap_unbind(ld);	    ld = NULL;	}    }    if (ld)	ldap_unbind(ld);    return 0;}static intldap_escape_value(char *escaped, int size, const char *src){    int n = 0;    while (size > 4 && *src) {	switch (*src) {	case '*':	case '(':	case ')':	case '\\':	    n += 3;	    size -= 3;	    if (size > 0) {		*escaped++ = '\\';		snprintf(escaped, 3, "%02x", (unsigned char) *src++);		escaped += 2;	    }	    break;	default:	    *escaped++ = *src++;	    n++;	    size--;	}    }    *escaped = '\0';    return n;}/* Check the userid & password. * Return 0 on success, 1 on failure */static intcheckLDAP(LDAP * persistent_ld, const char *userid, const char *password, const char *ldapServer, int port){    char dn[256];    int ret = 0;    LDAP *bind_ld = NULL;    int rc;    if (!*password) {	/* LDAP can't bind with a blank password. Seen as "anonymous"	 * and always granted access	 */	if (debug)	    fprintf(stderr, "Blank password given\n");	return 1;    }    if (searchfilter) {	char filter[256];	char escaped_login[256];	LDAPMessage *res = NULL;	LDAPMessage *entry;	char *searchattr[] =	{LDAP_NO_ATTRS, NULL};	char *userdn;	LDAP *search_ld = persistent_ld;	if (!search_ld)	    search_ld = open_ldap_connection(ldapServer, port);	ldap_escape_value(escaped_login, sizeof(escaped_login), userid);	if (binddn) {	    rc = ldap_simple_bind_s(search_ld, binddn, bindpasswd);	    if (rc != LDAP_SUCCESS) {		fprintf(stderr, PROGRAM_NAME ": WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));		ret = 1;		goto search_done;	    }	}	snprintf(filter, sizeof(filter), searchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login);	if (debug)	    fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, basedn);	rc = ldap_search_s(search_ld, basedn, searchscope, filter, searchattr, 1, &res);	if (rc != LDAP_SUCCESS) {	    if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {		/* Everything is fine. This is expected when referrals		 * are disabled.		 */		if (debug)		    fprintf(stderr, "noreferrals && rc == LDAP_PARTIAL_RESULTS\n");	    } else {		fprintf(stderr, PROGRAM_NAME ": WARNING, LDAP search error '%s'\n", ldap_err2string(rc));#if defined(NETSCAPE_SSL)		if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {		    int sslerr = PORT_GetError();		    fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));		}#endif		ret = 1;		goto search_done;	    }	}	entry = ldap_first_entry(search_ld, res);	if (!entry) {	    if (debug)		fprintf(stderr, "Ldap search returned nothing\n");	    ret = 1;	    goto search_done;	}	userdn = ldap_get_dn(search_ld, entry);	if (!userdn) {	    fprintf(stderr, PROGRAM_NAME ": ERROR, could not get user DN for '%s'\n", userid);	    ret = 1;	    goto search_done;	}	snprintf(dn, sizeof(dn), "%s", userdn);	squid_ldap_memfree(userdn);	if (ret == 0 && (!binddn || !bind_once || passwdattr)) {	    /* Reuse the search connection for comparing the user password attribute */	    bind_ld = search_ld;	    search_ld = NULL;	}      search_done:	if (res) {	    ldap_msgfree(res);	    res = NULL;	}	if (search_ld && search_ld != persistent_ld) {	    ldap_unbind(search_ld);	    search_ld = NULL;	}	if (ret != 0)	    return ret;    } else {	snprintf(dn, sizeof(dn), "%s=%s,%s", userattr, userid, basedn);    }    if (debug)	fprintf(stderr, "attempting to authenticate user '%s'\n", dn);    if (!bind_ld && !bind_once)	bind_ld = persistent_ld;    if (!bind_ld)	bind_ld = open_ldap_connection(ldapServer, port);    if (passwdattr) {	if (ldap_compare_s(bind_ld, dn, passwdattr, password) != LDAP_COMPARE_TRUE) {	    ret = 1;	}    } else if (ldap_simple_bind_s(bind_ld, dn, password) != LDAP_SUCCESS)	ret = 1;    if (bind_ld != persistent_ld) {	ldap_unbind(bind_ld);	bind_ld = NULL;    }    return ret;}intreadSecret(const char *filename){    char buf[BUFSIZ];    char *e = NULL;    FILE *f;    char *passwd = NULL;    if (!(f = fopen(filename, "r"))) {	fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename);	return 1;    }    if (!fgets(buf, sizeof(buf) - 1, f)) {	fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename);	fclose(f);	return 1;    }    /* strip whitespaces on end */    if ((e = strrchr(buf, '\n')))	*e = 0;    if ((e = strrchr(buf, '\r')))	*e = 0;    passwd = (char *) calloc(sizeof(char), strlen(buf) + 1);    if (!passwd) {	fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n");	exit(1);    }    strcpy(passwd, buf);    bindpasswd = passwd;    fclose(f);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -