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],"a, 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); }
int auth_pgsql_setpass(const char *user, const char *pass) { char *newpass_crypt; const char *newpass_crypt_ptr; const char *p; int l; char *sql_buf; const char *comma; int rc=0; const char *clear_field=NULL; const char *crypt_field=NULL; const char *defdomain=NULL; const char *where_clause=NULL; const char *user_table=NULL; const char *login_field=NULL; const char *chpass_clause=NULL; /* [email protected] */ if (!pgconn) return (-1); if (!(newpass_crypt=authcryptpasswd(pass, "{crypt}"))) return (-1); if (!(newpass_crypt_ptr=strchr(newpass_crypt, '}'))) { free(newpass_crypt); /* WTF???? */ return (-1); } ++newpass_crypt_ptr; for (l=0, p=pass; *p; p++) { if ((int)(unsigned char)*p < ' ') { free(newpass_crypt); return (-1); } if (*p == '"' || *p == '\\') ++l; ++l; } /* [email protected] */ chpass_clause=read_env("PGSQL_CHPASS_CLAUSE"); defdomain=read_env("DEFAULT_DOMAIN"); user_table=read_env("PGSQL_USER_TABLE"); if (!chpass_clause) { login_field = read_env("PGSQL_LOGIN_FIELD"); if (!login_field) login_field = "id"; crypt_field=read_env("PGSQL_CRYPT_PWFIELD"); clear_field=read_env("PGSQL_CLEAR_PWFIELD"); where_clause=read_env("PGSQL_WHERE_CLAUSE"); sql_buf=malloc(strlen(crypt_field ? crypt_field:"") + strlen(clear_field ? clear_field:"") + strlen(defdomain ? defdomain:"") + strlen(login_field) + l + strlen(newpass_crypt) + strlen(user_table) + strlen(where_clause ? where_clause:"") + 200); } else { sql_buf=parse_chpass_clause(chpass_clause, user, defdomain, pass, newpass_crypt_ptr); } if (!sql_buf) { free(newpass_crypt); return (-1); } if (!chpass_clause) /* [email protected] */ { sprintf(sql_buf, "UPDATE %s SET", user_table); comma=""; if (clear_field && *clear_field) { char *q; strcat(strcat(strcat(sql_buf, " "), clear_field), "='"); q=sql_buf+strlen(sql_buf); while (*pass) { if (*pass == '"' || *pass == '\\') *q++= '\\'; *q++ = *pass++; } strcpy(q, "'"); comma=", "; } if (crypt_field && *crypt_field) { strcat(strcat(strcat(strcat(strcat(strcat(sql_buf, comma), " "), crypt_field), "='"), newpass_crypt_ptr), "'"); } free(newpass_crypt); strcat(strcat(strcat(sql_buf, " WHERE "), login_field), "='"); append_username(sql_buf+strlen(sql_buf), user, defdomain); strcat(sql_buf, "'"); if (where_clause && *where_clause) { strcat(sql_buf, " AND ("); strcat(sql_buf, where_clause); strcat(sql_buf, ")"); } } /* end of: if (!chpass_clause) */ pgresult=PQexec (pgconn, sql_buf); if (!pgresult || PQresultStatus(pgresult) != PGRES_COMMAND_OK) { rc= -1; auth_pgsql_cleanup(); } PQclear(pgresult); free(sql_buf); return (rc); }
int auth_mysql_setpass(const char *user, const char *pass, const char *oldpass) { char *newpass_crypt; char *sql_buf; int rc=0; char *clear_escaped; char *crypt_escaped; const char *clear_field =NULL, *crypt_field =NULL, *defdomain =NULL, *where_clause =NULL, *user_table =NULL, *login_field =NULL, *chpass_clause =NULL; /* [email protected] */ if (do_connect()) return (-1); if (!(newpass_crypt=authcryptpasswd(pass, oldpass))) return (-1); clear_escaped=malloc(strlen(pass)*2+1); if (!clear_escaped) { perror("malloc"); free(newpass_crypt); return -1; } crypt_escaped=malloc(strlen(newpass_crypt)*2+1); if (!crypt_escaped) { perror("malloc"); free(clear_escaped); free(newpass_crypt); return -1; } mysql_real_escape_string(mysql, clear_escaped, pass, strlen(pass)); mysql_real_escape_string(mysql, crypt_escaped, newpass_crypt, strlen(newpass_crypt)); /* [email protected] */ chpass_clause=read_env("MYSQL_CHPASS_CLAUSE"); defdomain=read_env("DEFAULT_DOMAIN"); user_table=read_env("MYSQL_USER_TABLE"); if (!chpass_clause) { int has_domain=strchr(user, '@') != NULL; char *username_escaped; char dummy_buf[1]; size_t sql_buf_size; username_escaped=malloc(strlen(user)*2+1); if (!username_escaped) { perror("malloc"); free(clear_escaped); free(crypt_escaped); free(newpass_crypt); return -1; } mysql_real_escape_string(mysql, username_escaped, user, strlen(user)); login_field = read_env("MYSQL_LOGIN_FIELD"); if (!login_field) login_field = "id"; crypt_field=read_env("MYSQL_CRYPT_PWFIELD"); clear_field=read_env("MYSQL_CLEAR_PWFIELD"); where_clause=read_env("MYSQL_WHERE_CLAUSE"); if (!where_clause) where_clause=""; if (!crypt_field) crypt_field=""; if (!clear_field) clear_field=""; if (!defdomain) defdomain=""; #define DEFAULT_SETPASS_UPDATE \ "UPDATE %s SET %s%s%s%s %s %s%s%s%s WHERE %s='%s%s%s' %s%s%s", \ user_table, \ *clear_field ? clear_field:"", \ *clear_field ? "='":"", \ *clear_field ? clear_escaped:"", \ *clear_field ? "'":"", \ \ *clear_field && *crypt_field ? ",":"", \ \ *crypt_field ? crypt_field:"", \ *crypt_field ? "='":"", \ *crypt_field ? crypt_escaped:"", \ *crypt_field ? "'":"", \ login_field, \ username_escaped, \ has_domain || !*defdomain ? "":"@", \ has_domain ? "":defdomain, \ *where_clause ? " AND (":"", where_clause, \ *where_clause ? ")":"" sql_buf_size=snprintf(dummy_buf, 1, DEFAULT_SETPASS_UPDATE); sql_buf=malloc(sql_buf_size+1); if (sql_buf) snprintf(sql_buf, sql_buf_size+1, DEFAULT_SETPASS_UPDATE); free(username_escaped); } else { sql_buf=parse_chpass_clause(chpass_clause, user, defdomain, clear_escaped, crypt_escaped); } free(clear_escaped); free(crypt_escaped); free(newpass_crypt); if (courier_authdebug_login_level >= 2) { DPRINTF("setpass SQL: %s", sql_buf); } if (mysql_query (mysql, sql_buf)) { DPRINTF("setpass SQL failed"); rc= -1; auth_mysql_cleanup(); } free(sql_buf); return (rc); }