void
LDAPHHA1(RequestData * requestData)
{
    char *password;
    ldapconnect();
    password = getpassword(requestData->user, requestData->realm);
    if (password != NULL) {
	if (encrpass)
	    xstrncpy(requestData->HHA1, password, sizeof(requestData->HHA1));
	else {
	    HASH HA1;
	    DigestCalcHA1("md5", requestData->user, requestData->realm, password, NULL, NULL, HA1, requestData->HHA1);
	}
	free(password);
    } else {
	requestData->error = -1;
    }

}
static int mod_vhost_ldap_translate_name(request_rec *r)
{
	mod_vhost_ldap_request_t *reqc = NULL;
	mod_vhost_ldap_config_t *conf =
	(mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_ng_module);
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER <= 2)
	core_server_config *core =
		(core_server_config *)ap_get_module_config(r->server->module_config, &core_module);
#endif	
	LDAP *ld = NULL;
	char *realfile = NULL;
	char *myfilter = NULL;
	alias_t *alias = NULL, *cursor = NULL;
	int i = 0, ret = 0;
	apr_table_t *e;
	LDAPMessage *ldapmsg = NULL, *vhostentry = NULL;
	
	if (conf->enabled != MVL_ENABLED || !conf->url || !r->hostname){
		ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, 
				"[mod_vhost_ldap_ng.c] Module disabled");
		return DECLINED;
	}

	//Search in cache
	reqc = (mod_vhost_ldap_request_t *)get_from_requestscache(r);
	if(!reqc){
		ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, 
				"[mod_vhost_ldap_ng.c] Cannot resolve data from cache");
		reqc = apr_pcalloc(vhost_ldap_pool, sizeof(mod_vhost_ldap_request_t));
	}
	if (reqc->expires < apr_time_now()){
		//Search ldap
		//TODO: Create a function
		while((ret = ldapconnect(&ld, conf)) != 0 && i<2){
			i++;
			ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, 
				"[mod_vhost_ldap_ng.c] ldapconnect: %s", ldap_err2string(ret));
		}
		if(i == 2){
			conf->enabled = MVL_DISABLED;
			return HTTP_GATEWAY_TIME_OUT;
		}

		myfilter = apr_psprintf(r->pool,"(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))",
									conf->filter, r->hostname, r->hostname);

		ret = ldap_search_s (ld, conf->basedn, conf->scope, myfilter, (char **)attributes, 0, &ldapmsg);
		if(ret != LDAP_SUCCESS){//SIGPIPE?
			return DECLINED;
		}
		if(ldap_count_entries(ld, ldapmsg)!=1){
			if(!conf->fallback_name || !conf->fallback_docroot){
				reqc->name = apr_pstrdup(vhost_ldap_pool, r->hostname);
				reqc->decline = 1;
				reqc->admin = apr_pstrdup(vhost_ldap_pool, r->server->server_admin);
				add_to_requestscache(reqc, r);
				if(ldapmsg)
					ldap_msgfree(ldapmsg);
				ldapdestroy(&ld);
				return DECLINED;
			}else{
				reqc->name = conf->fallback_name;
				reqc->docroot = conf->fallback_docroot;
			}
		}else{
			reqc->aliases = (apr_array_header_t *)apr_array_make(vhost_ldap_pool, 2, sizeof(alias_t));
			reqc->redirects = (apr_array_header_t *)apr_array_make(vhost_ldap_pool, 2, sizeof(alias_t));
			reqc->env = apr_table_make(vhost_ldap_pool, 2);
			vhostentry = ldap_first_entry(ld, ldapmsg);
			reqc->dn = ldap_get_dn(ld, vhostentry);
			i=0;
			while(attributes[i]){
				int k = 0, j;
				char **eValues = ldap_get_values(ld, vhostentry, attributes[i]), *str[3];
				if (eValues){
					k = ldap_count_values (eValues);
					if (strcasecmp(attributes[i], "apacheServerName") == 0){
						reqc->name = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}else if(strcasecmp(attributes[i], "apacheServerAdmin") == 0){
						reqc->admin = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}else if(strcasecmp(attributes[i], "apacheDocumentRoot") == 0){
						reqc->docroot = apr_pstrdup(vhost_ldap_pool, eValues[0]);
						/* Make it absolute, relative to ServerRoot */
						if(conf->rootdir && (strncmp(reqc->docroot, "/", 1) != 0))
							reqc->docroot = apr_pstrcat(vhost_ldap_pool, conf->rootdir, reqc->docroot, NULL);
						reqc->docroot = ap_server_root_relative(vhost_ldap_pool, reqc->docroot);
					}else if(strcasecmp(attributes[i], "apacheAlias") == 0){
						while(k){
							k--;
							for(j = 0; j < 2; j++)
                                str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]);
							if(str[--j] == '\0')
								ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
                                "[mod_vhost_ldap_ng.c]: Wrong apacheAlias parameter: %s",
                                eValues[k]);
							else{
								alias = apr_array_push(reqc->aliases);
								alias->src = apr_pstrdup(vhost_ldap_pool, str[0]);
								alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]);
							}
						}
					}else if(strcasecmp(attributes[i], "apacheScriptAlias") == 0){
						while(k){
							k--; 
							for(j = 0; j < 2; j++)
								str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]);
							if(str[--j] == '\0')
								ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
									"[mod_vhost_ldap_ng.c]: Wrong apacheScriptAlias parameter: %s", eValues[k]);
							else{
								alias = apr_array_push(reqc->aliases);
								alias->src = apr_pstrdup(vhost_ldap_pool, str[0]);
								alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]);
							}
						}
					}else if(strcasecmp (attributes[i], "apacheRedirect") == 0){
						while(k){
							k--; 
							for(j = 0; j < 3; j++)
								str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]);
							if(str[1] == '\0')
								ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
								"[mod_vhost_ldap_ng.c]: Missing apacheRedirect parameter: %s",
								eValues[k]);
							else{
								alias = apr_array_push(reqc->redirects);
								alias->src = apr_pstrdup(vhost_ldap_pool, str[0]);
								if(str[2] != '\0'){
									if(strcasecmp(str[1], "gone") == 0)
										alias->flags |= REDIR_GONE;
									else if (strcasecmp(str[1], "permanent") == 0)
										alias->flags |= REDIR_PERMANENT;
									else if (strcasecmp(str[1], "temp") == 0)
										alias->flags |= REDIR_TEMP;
									else if (strcasecmp(str[1], "seeother") == 0)
										alias->flags |= REDIR_SEEOTHER;
									else{
										alias->flags |= REDIR_PERMANENT;
										ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
										"[mod_vhost_ldap_ng.c]: Wrong apacheRedirect type: %s", str[2]);
									}
									alias->dst = apr_pstrdup(vhost_ldap_pool, str[2]);
								}else
									alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]);
							}
						}
					}else if(strcasecmp(attributes[i], "apacheSuexecUid") == 0){
						reqc->uid = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}else if(strcasecmp(attributes[i], "apacheSuexecGid") == 0){
						reqc->gid = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}else if(strcasecmp (attributes[i], "apacheErrorLog") == 0){
						if(conf->rootdir && (strncmp(eValues[0], "/", 1) != 0))
							r->server->error_fname = apr_pstrcat(vhost_ldap_pool, conf->rootdir, eValues[0], NULL);
						else
							r->server->error_fname = apr_pstrdup(vhost_ldap_pool, eValues[0]);;
						apr_file_open(&r->server->error_log, r->server->error_fname,
								APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE,
								APR_OS_DEFAULT, r->pool);
					}
#ifdef HAVEPHP
					else if(strcasecmp(attributes[i], "phpIncludePath") == 0){
						if(conf->php_includepath)
							reqc->php_includepath = apr_pstrcat(vhost_ldap_pool, conf->php_includepath, ":", eValues[0], NULL);
						else
							reqc->php_includepath = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}else if(strcasecmp(attributes[i], "phpOpenBasedir") == 0){
						if(conf->rootdir && (strncmp(eValues[0], "/", 1) != 0))
							reqc->php_openbasedir = apr_pstrcat(vhost_ldap_pool, conf->rootdir, eValues[0], NULL);
						else
							reqc->php_openbasedir = apr_pstrdup(vhost_ldap_pool, eValues[0]);
					}
					else if(strcasecmp(attributes[i], "php_admin_value") == 0){
					}
#endif
					else if(strcasecmp(attributes[i], "SetEnv") == 0){
						for(j = 0; j < 2; j++)
							str[j] = ap_getword_conf(r->pool, (const char **)&eValues[0]);
						if(str[--j] == '\0')
							ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
							"[mod_vhost_ldap_ng.c]: Wrong apacheScriptAlias parameter: %s", eValues[0]);
						else{
							apr_table_set(reqc->env, str[0], str[1]);
						}
					}else if(strcasecmp(attributes[i], "PassEnv") == 0){
					}
				}
				i++;
			}
		}
		if(ldapmsg)
			ldap_msgfree(ldapmsg);
		ldapdestroy(&ld);
		add_to_requestscache(reqc, r);
	}
	if(reqc->decline)
		return DECLINED;
	
	ap_set_module_config(r->request_config, &vhost_ldap_ng_module, reqc);
	e = r->subprocess_env;
	if(apr_table_elts(reqc->env)->nelts)
		r->subprocess_env = apr_table_overlay(r->pool, e, reqc->env);
#ifdef HAVEPHP
	char *openbasedir, *include;
	if(!reqc->php_includepath)
		include = apr_pstrcat(r->pool, conf->php_includepath, ":", reqc->docroot, NULL);
	else
		include = apr_pstrcat(r->pool, reqc->php_includepath, ":", conf->php_includepath, ":", reqc->docroot, NULL);
	zend_alter_ini_entry("include_path", strlen("include_path") + 1, (void *)include, strlen(include), PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
	if(reqc->php_openbasedir){
		openbasedir = apr_pstrcat(r->pool, reqc->php_openbasedir, ":", include, NULL);
		zend_alter_ini_entry("open_basedir", strlen("open_basedir") + 1, (void *)openbasedir, strlen(openbasedir), PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
	}
#endif
	if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, 
			"[mod_vhost_ldap_ng.c] translate: "
			"translate failed; ServerName %s or DocumentRoot %s not defined", reqc->name, reqc->docroot);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	
	cursor = NULL;
	//From mod_alias: checking for redirects
	if(reqc->redirects){
		cursor = (alias_t *)reqc->redirects->elts;
		if (r->uri[0] != '/' && r->uri[0] != '\0') 
			return DECLINED;
		for(i = 0; i < reqc->redirects->nelts; i++){
			alias = (alias_t *) &cursor[i];
			if(alias_matches(r->uri, alias->src)){
				apr_table_setn(r->headers_out, "Location", alias->dst);
				/* OLD STUFF
				if(alias->redir_status){
					if (strcasecmp(alias->redir_status, "gone") == 0)
						return  HTTP_GONE;
					else if (strcasecmp(alias->redir_status, "permanent") == 0)
						return HTTP_MOVED_PERMANENTLY;
					else if (strcasecmp(alias->redir_status, "temp") == 0)
						return HTTP_MOVED_TEMPORARILY;
					else if (strcasecmp(alias->redir_status, "seeother") == 0)
						return HTTP_SEE_OTHER;
				}
				*/
				if(alias->flags & REDIR_GONE) return HTTP_GONE;
				else if(alias->flags & REDIR_TEMP) return HTTP_MOVED_TEMPORARILY;
				else if(alias->flags & REDIR_SEEOTHER) return HTTP_SEE_OTHER;
				else return HTTP_MOVED_PERMANENTLY;
			}
		}
	}
	
	/* Checking for aliases */
	if(reqc->aliases){
		cursor = (alias_t *)reqc->aliases->elts;
		for(i = 0; reqc->aliases && i < reqc->aliases->nelts; i++){
			alias = (alias_t *) &cursor[i];
			if (alias_matches(r->uri, alias->src)) {
				/* Set exact filename for CGI script */
				realfile = apr_pstrcat(r->pool, alias->dst, r->uri + strlen(alias->src), NULL);
				/* Add apacheRootDir config param IF realfile is a realative path*/
				if(conf->rootdir && (strncmp(realfile, "/", 1) != 0))
					realfile = apr_pstrcat(r->pool, conf->rootdir, "/", realfile, NULL);
				/* Let apache normalize the path */
				if((realfile = ap_server_root_relative(r->pool, realfile))) {
					ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
						"[mod_vhost_ldap_ng.c]: ap_document_root is: %s",
						ap_document_root(r));
					r->filename = realfile;
					if(alias->flags & ISCGI){
						//r->handler = "cgi-script";
						r->handler = "Script";
						apr_table_setn(r->notes, "alias-forced-type", r->handler);
					}
					return OK;
				}
				return OK;
			} else if (r->uri[0] == '/') {
				/* we don't set r->filename here, and let other modules do it
				* this allows other modules (mod_rewrite.c) to work as usual
				*/
				/* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */
			} else {
				/* We don't handle non-file requests here */
				return DECLINED;
			}
		}
	}
	
	if ((r->server = apr_pmemdup(r->pool, r->server, sizeof(*r->server))) == NULL) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, 
			"[mod_vhost_ldap_ng.c] translate: "
			"translate failed; Unable to copy r->server structure");
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	
	r->server->server_hostname = apr_pstrdup(r->pool,reqc->name);

	if (reqc->admin)
		r->server->server_admin = apr_pstrdup(r->pool, reqc->admin);

#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER <= 2)
	core->ap_document_root = apr_pstrdup(r->pool, reqc->docroot);
	if (!ap_is_directory(r->pool, reqc->docroot))
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
			"[mod_vhost_ldap_ng.c] set_document_root: Warning: DocumentRoot [%s] does not exist", core->ap_document_root);
#else
	ap_set_document_root(r, reqc->docroot);
#endif
	//ap_set_module_config(r->server->module_config, &core_module, core);

	/* Hack to allow post-processing by other modules (mod_rewrite, mod_alias) */
	return DECLINED;
}
示例#3
0
文件: authldaplib.c 项目: zixia/wmail
static int auth_ldap_do3(const char *attrname,
			 const char *user, const char *pass,
			 int (*callback)(struct authinfo *, void *),
			 void *arg, const char *newpass,
			 const char *authaddr)
{
	char *newpass_crypt=0;
	const char *attributes[10], *ldap_attributes[10];
  
	struct timeval timeout;

	LDAPMessage *result;
	LDAPMessage *entry;
	char *filter, *dn;
	int i, j;

	struct authinfo auth;
	char *homeDir=0;
	char *mailDir=0;
	char *userPassword=0;
	char *cryptPassword=0;
	char *cn=0;
	uid_t au;
	gid_t ag;
	int rc;
	char *quota=0;
        int additionalFilter = 0;
        int hasAdditionalFilter = 0;

        hasAdditionalFilter = my_ldap.filter != 0;

	memset(&auth, 0, sizeof(auth));

        if (hasAdditionalFilter)
        {
            /* To add the additional filter, we need to add on the
             * additional size for "(&)" and the other filter.  So
             * filter+3
             */
            additionalFilter = strlen(my_ldap.filter) + 3;
        }

	if ((filter=malloc(additionalFilter+strlen(attrname)+strlen(user)+
			   (my_ldap.domain ? strlen(my_ldap.domain):0)+
			   sizeof ("(=@)"))) == 0)
	{
		perror("malloc");
		return 1;
	}
        strcpy(filter, "\0");

        if (hasAdditionalFilter)
        {
            strcat(filter, "(&");
            strcat(filter, my_ldap.filter);
        }

        strcat(strcat(strcat(strcat(filter, "("), attrname), "="), user);
	if ( my_ldap.domain && my_ldap.domain[0] && strchr(user, '@') == 0 )
		strcat(strcat(filter, "@"), my_ldap.domain);
	strcat(filter, ")");
        
        if (hasAdditionalFilter)
        {
            strcat(filter, ")");
        }

	timeout.tv_sec=my_ldap.timeout;
	timeout.tv_usec=0;

	read_env("LDAP_HOMEDIR", &attributes[0], "", 0, "homeDir");
	read_env("LDAP_MAILDIR", &attributes[1], "", 0, 0);
	read_env("LDAP_FULLNAME", &attributes[2], "", 0, "cn");
	read_env("LDAP_CLEARPW", &attributes[3], "", 0, 0);
	read_env("LDAP_CRYPTPW", &attributes[4], "", 0, 0);
	read_env("LDAP_UID", &attributes[5], "", 0, 0);
	read_env("LDAP_GID", &attributes[6], "", 0, 0);
	attributes[7]=my_ldap.mail;
	read_env("LDAP_MAILDIRQUOTA", &attributes[8], "", 0, 0);

	j=0;
	for (i=0; i<9; i++)
	{
		if (attributes[i])
			ldap_attributes[j++]=attributes[i];
	}

	ldap_attributes[j]=0;

	if (ldaperror(ldap_search_st(my_ldap_fp,
				     (char *)my_ldap.basedn,LDAP_SCOPE_SUBTREE,
				     filter, (char **)ldap_attributes, 0,
				     &timeout, &result)
		      != LDAP_SUCCESS))
	{
		free(filter);

		if (my_ldap_fp)	return (-1);
		return (1);
	}

	free(filter);

	/* If we are more than one result, reject */
	if (ldap_count_entries(my_ldap_fp,result)!=1)
	{
		ldap_msgfree(result);
		return -1;
	}
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"Nombre de résulat:    %d\n",ldap_count_entries(my_ldap_fp,result));
#endif

	dn = ldap_get_dn(my_ldap_fp, result);

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"DN:    %s\n",dn);
#endif

	if (dn == NULL) 
	{
		ldap_perror(my_ldap_fp, "ldap_get_dn");
		return -1;
	}

	/* Get the pointer on this result */
	entry=ldap_first_entry(my_ldap_fp,result);
	if (entry==NULL)
	{
		ldap_perror(my_ldap_fp,"ldap_first_entry");
		free(dn);
		return -1;
	}

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after ldap_first_entry\n");
#endif
	/* Copy the directory and the password into struct */
	copy_value(my_ldap_fp,entry,attributes[0],&homeDir, user);
	if (attributes[1])
		copy_value(my_ldap_fp,entry,attributes[1],&mailDir, user);
	copy_value(my_ldap_fp,entry,attributes[2],&cn, user);
	if (attributes[3])
		copy_value(my_ldap_fp,entry,attributes[3],&userPassword, user);
	if (attributes[4])
		copy_value(my_ldap_fp,entry,attributes[4],&cryptPassword, user);

	au=my_ldap.uid;
	ag=my_ldap.gid;
	if (attributes[5])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[5], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				au= (uid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"au= %d\n",au);
#endif
	}

	if (attributes[6])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[6], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				ag= (gid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"ag= %d\n",ag);
#endif
	}

	if (attributes[8])
		copy_value(my_ldap_fp,entry,attributes[8],&quota, user);

	if (homeDir != 0 && my_ldap.mailroot != 0 && *my_ldap.mailroot)
	{
		char *new_mailroot=malloc(strlen(homeDir)+
					  strlen(my_ldap.mailroot)+2);

		if (!new_mailroot)
		{
			syslog(LOG_DAEMON|LOG_CRIT, "authldap: malloc failed");
			rc= -1;
		}
		else
		{
			strcat(strcat(strcpy(new_mailroot, my_ldap.mailroot),
				      "/"), homeDir);
			free(homeDir);
			homeDir=new_mailroot;
		}
	}

	auth.sysusername=user;
	auth.sysuserid= &au;
	auth.sysgroupid= ag;
	auth.homedir=homeDir;
	auth.address=authaddr;
	auth.fullname=cn;
	auth.maildir=mailDir;
	auth.clearpasswd=userPassword;
	auth.passwd=cryptPassword;
	auth.quota=quota;

	if (auth.sysusername == 0)
		auth.sysusername=auth.address="";

	if (homeDir == 0)
		auth.homedir="";

	rc=0;

	if (au == 0 || ag == 0)
	{
		syslog(LOG_DAEMON|LOG_CRIT,
		       "authlib: refuse to authenticate %s: uid=%d, gid=%d\n",
		       user, au, ag);
		rc= 1;
	}

	if (pass)
	{
		if (my_ldap.authbind) 
		{
			LDAP *bindp=ldapconnect();

			if (!bindp)
				rc=1;
			else
			{
#if HAVE_LDAP_TLS
				if(my_ldap.tls && enable_tls_on(bindp)) {
#if HAVE_SYSLOG_H
					syslog(LOG_DAEMON|LOG_CRIT, "authlib: LDAP_TLS enabled but I'm unable to start tls, check your config\n");
#endif
					rc = 1;
				} else {
#endif
					switch (ldap_simple_bind_s(bindp, dn, (char *)pass))
					{
					case LDAP_SUCCESS:
						break;
					case LDAP_INVALID_CREDENTIALS:
						rc = -1;
						break;
					default:
						rc = 1;
						break;
					}
#if HAVE_LDAP_TLS
				}
#endif
				ldap_unbind(bindp);
			}
			if (rc == 0 && newpass)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   NULL))
				    == 0)
					rc= -1;
			}
		}
		else
		{
			if (auth.clearpasswd)
			{
				if (strcmp(pass,auth.clearpasswd))
					rc= -1;
			}
			else
			{
			const char *p=auth.passwd;

				if (p && strncasecmp(p, "{crypt}", 7) == 0)
					p += 7; /* For authcheckpassword */

				if (!p || authcheckpassword(pass, p))
					rc= -1;
			}

			if (rc == 0 && newpass && auth.passwd)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   auth.passwd)
				     ) == 0)
					rc= -1;
			}
		}
        }

	if (rc == 0 && newpass)
	{
		LDAPMod *mods[3];
		int mod_index=0;

		LDAPMod mod_clear, mod_crypt;
		char *mod_clear_vals[2], *mod_crypt_vals[2];

		if (attributes[3])
		{
			mods[mod_index]= &mod_clear;
			mod_clear.mod_op=LDAP_MOD_REPLACE;
			mod_clear.mod_type=(char *)attributes[3];
			mod_clear.mod_values=mod_clear_vals;

			mod_clear_vals[0]=(char *)newpass;
			mod_clear_vals[1]=NULL;
			++mod_index;
		}

		if (attributes[4] && newpass_crypt)
		{
			mods[mod_index]= &mod_crypt;
			mod_crypt.mod_op=LDAP_MOD_REPLACE;
			mod_crypt.mod_type=(char *)attributes[4];
			mod_crypt.mod_values=mod_crypt_vals;

			mod_crypt_vals[0]=newpass_crypt;
			mod_crypt_vals[1]=NULL;
			++mod_index;
		}
		if (mod_index == 0)
			rc= -1;
		else
		{
			mods[mod_index]=0;

			if (ldap_modify_s(my_ldap_fp, dn, mods))
			{
				rc= -1;
			}
		}
	}

	if (newpass_crypt)
		free(newpass_crypt);
	free (dn);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"before callback rc=%d\n",rc);
#endif

	if (rc == 0 && callback)
		rc= (*callback)(&auth, arg);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after callback rc=%d\n",rc);
#endif

	ldap_msgfree(result);

	if (homeDir)	free(homeDir);
	if (mailDir)	free(mailDir);
	if (userPassword)	free(userPassword);
	if (cryptPassword)	free(cryptPassword);
	if (cn)		free(cn);
	if (quota)	free(quota);
	return (rc);
}
static char *
getpassword(char *login, char *realm)
{
    LDAPMessage *res = NULL;
    LDAPMessage *entry;
    char **values = NULL;
    char **value = NULL;
    char *password = NULL;
    int retry = 0;
    char filter[8192];
    char searchbase[8192];
    char *universal_password = NULL;
    size_t universal_password_len = UNIVERSAL_PASS_LEN;
    int nmas_res = 0;
    int rc = -1;
    if (ld) {
	if (usersearchfilter) {
	    char escaped_login[1024];
	    snprintf(searchbase, sizeof(searchbase), "%s", userbasedn);
	    ldap_escape_value(escaped_login, sizeof(escaped_login), login);
	    snprintf(filter, sizeof(filter), usersearchfilter, 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, escaped_login);

	  retrysrch:
	    if (debug)
		fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, searchbase);

	    rc = ldap_search_s(ld, searchbase, searchscope, filter, NULL, 0, &res);
	    if (rc != LDAP_SUCCESS) {
		if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {
		    /* Everything is fine. This is expected when referrals
		     * are disabled.
		     */
		    rc = LDAP_SUCCESS;
		} 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
		    fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error, trying to recover'%s'\n", ldap_err2string(rc));
		    ldap_msgfree(res);
		    /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */
		    if (!retry) {
			retry++;
			ldap_unbind(ld);
			ld = NULL;
			ldapconnect();
			goto retrysrch;
		    }
		    return NULL;

		}
	    }
	} else if (userdnattr) {
	    sprintf(searchbase, "%s=%s, %s", userdnattr, login, userbasedn);

	  retrydnattr:
	    if (debug)
		fprintf(stderr, "searchbase '%s'\n", searchbase);
	    rc = ldap_search_s(ld, searchbase, searchscope, NULL, NULL, 0, &res);
	}
	if (rc == LDAP_SUCCESS) {
	    entry = ldap_first_entry(ld, res);
	    if (entry) {
		if (debug)
		    printf("ldap dn: %s\n", ldap_get_dn(ld, entry));
		if (edir_universal_passwd) {

		    /* allocate some memory for the universal password returned by NMAS */
		    universal_password = malloc(universal_password_len);
		    memset(universal_password, 0, universal_password_len);
		    values = malloc(sizeof(char *));

		    /* actually talk to NMAS to get a password */
		    nmas_res = nmasldap_get_password(ld, ldap_get_dn(ld, entry), &universal_password_len, universal_password);
		    if (nmas_res == NMAS_SUCCESS && universal_password) {
			if (debug)
			    printf("NMAS returned value %s\n", universal_password);
			values[0] = universal_password;
		    } else {
			if (debug)
			    printf("Error reading Universal Password: %d = %s\n", nmas_res, ldap_err2string(nmas_res));
		    }
		} else {
		    values = ldap_get_values(ld, entry, passattr);
		}
	    } else {
		ldap_msgfree(res);
		return NULL;
	    }
	    if (!values) {
		if (debug)
		    printf("No attribute value found\n");
		if (edir_universal_passwd)
		    free(universal_password);
		ldap_msgfree(res);
		return NULL;
	    }
	    value = values;
	    while (*value) {
		if (encrpass) {
		    if (strcmp(strtok(*value, delimiter), realm) == 0) {
			password = strtok(NULL, delimiter);
			break;
		    }
		} else {
		    password = *value;
		    break;
		}
		value++;
	    }
	    if (debug)
		printf("password: %s\n", password);
	    if (password)
		password = strdup(password);
	    if (edir_universal_passwd) {
		free(values);
		free(universal_password);
	    } else {
		ldap_value_free(values);
	    }
	    ldap_msgfree(res);
	    return password;
	} else {
	    fprintf(stderr, PROGRAM_NAME " WARNING, LDAP error '%s'\n", ldap_err2string(rc));
	    /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */
	    if (!retry) {
		retry++;
		ldap_unbind(ld);
		ld = NULL;
		ldapconnect();
		goto retrydnattr;
	    }
	    return NULL;
	}
    }
    return NULL;
}
示例#5
0
文件: authldaplib.c 项目: zixia/wmail
static int ldapopen()
{
int     ldrc;

	if (my_ldap_fp)	return (0);

	if (authldap_read_config(&my_ldap) == 0)
		return (1);

	my_ldap_fp=ldapconnect();

	if (!my_ldap_fp)
	{
		return (1);
	}

#if HAVE_LDAP_TLS
	if (my_ldap.tls && enable_tls_on(my_ldap_fp))
	{
		authldapclose();
		ldapconnfailure();
		return (-1);
	}
#endif

#ifdef LDAP_OPT_DEREF

	/* Set deferencing mode */
	if (ldaperror(ldrc = ldap_set_option(my_ldap_fp, LDAP_OPT_DEREF,
					 (void *) & my_ldap.deref)) != LDAP_SUCCESS)
	  {
		const char *s=ldap_err2string(ldrc);

#if	HAVE_SYSLOG_H
		syslog(LOG_DAEMON|LOG_CRIT, "ldap_set_option failed: %s", s);
#endif
		authldapclose();
		ldapconnfailure();
		return (-1);
	  }
#endif

  /* Bind to server */
#if DEBUG_LDAP
  syslog(LOG_DAEMON|LOG_CRIT,"BindDn:   %s\nBindPw:   %s\n",my_ldap.binddn,my_ldap.bindpw);
#endif

  if (ldaperror(ldrc = ldap_simple_bind_s(my_ldap_fp,
		(char *)my_ldap.binddn,
		(char *)my_ldap.bindpw)) != LDAP_SUCCESS)
    {
    const char *s=ldap_err2string(ldrc);

#if	HAVE_SYSLOG_H
	syslog(LOG_DAEMON|LOG_CRIT, "ldap_simple_bind_s failed: %s", s);
#endif
	authldapclose();
	ldapconnfailure();
	return (-1);
    }
	return (0);
}