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

📄 vldap.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: vldap.c,v 1.15 2004/01/07 16:06:16 tomcollins Exp $ * Copyright (C) 1999-2003 Inter7 Internet Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <pwd.h>#include <sys/types.h>#include <sys/time.h>#include <time.h>#include <utime.h>#include <lber.h>#include <ldap.h>#include "config.h"#include "vpopmail.h"#include "vauth.h"#include "vlimits.h"#include "vldap.h"LDAP *ld = NULL;LDAPMessage *glm = NULL;#ifdef CLEAR_PASS#  define NUM_LDAP_FIELDS  9#else#  define NUM_LDAP_FIELDS  8#endifchar *ldap_fields[NUM_LDAP_FIELDS] = {                                         "uid",   /* 0 pw_name   */                                         "userPassword",  /* 1 pw_passwd */                                         "qmailUID",   /* 2 pw_uid    */                                         "qmailGID",   /* 3 pw_gid    */                                         "qmaildomain",  /* 4 pw_gecos  */                                         "mailMessageStore",  /* 5 pw_dir    */                                         "mailQuota",   /* 6 pw_shell  */#ifndef CLEAR_PASS                                         "objectclass"   /* 7 ldap      */#else                                         "clearPassword",  /* 7 pw_clear_passwd */                                         "objectclass"   /* 8 ldap      */#endif                                     };/***************************************************************************/struct vqpasswd *vauth_getpw(char *user, char *domain) {    int ret = 0;    size_t len = 0;    struct vqpasswd *vpw = NULL;    LDAPMessage *res = NULL, *msg = NULL;    char *filter = NULL, **vals = NULL, *h = NULL, *t = NULL, *passwd = NULL;    char *dn = NULL;    uid_t myuid;    uid_t uid;    gid_t gid;    verrori = 0;    lowerit(user);    lowerit(domain);    vget_assign(domain,NULL,0,&uid,&gid);    myuid = geteuid();    if ( myuid != 0 && myuid != uid ) {        return(NULL);    }    /* take a given domain, and set dn to be this format :     * ou=somedomain.com,o=vpopmail     */    if (compose_dn(&dn,domain) != 0)        return NULL;    /* take the username and create set filter ot be in this format :     * (&(objectclass=qmailUser)(uid=someusername))     */    len = (strlen(user) + 32 + 1);    filter = (char *)safe_malloc(len);    memset((char *)filter, 0, len);    snprintf(filter, len, "(&(objectclass=qmailUser)(uid=%s))", user);    /* connect to the ldap server (if we havent already got a connection open) */    if (ld == NULL ) {        if (ldap_connect() != 0) {            safe_free((void **) &filter);            return NULL;        }    }    /* perform an ldap search     * int ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res)     *      * Will search synchronously, and not return until the operation completes.     * base : DN of the entry at which to start the search     * scope : scope of the search     *   LDAP_SCOPE_SUBTREE means to search the object and all of its descendents.     * filter : filter to apply to the search     * attrs : attribute types to return from entries that match filter     * attrsonly : set to 0 for attributes and attributetypes are wanted. 1 if only attributes are wanted.     */    ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,                        filter, vldap_attrs, 0, &res);    safe_free((void **) &filter);    /* see if the search ran without generating an error */    if (ret != LDAP_SUCCESS ) {        ldap_perror(ld,"Error");        return NULL;    }    /* grab a pointer to the 1st entry in the chain of search results */    msg = ldap_first_entry(ld, res);    if (msg == NULL) {        /* We had an error grabbing the pointer */        return NULL;    }    /* find out how many matches we found */    ret = ldap_count_entries(ld, msg);    if (ret == -1 ) {        /* an error occurred when counting the entries */        ldap_perror(ld,"Error");        return NULL;    }    /*       Fetch userPassword first so we can make sure       we're able to handle it's password encryption (if any)    */    /* userPasswd / pw_password */    vals = ldap_get_values(ld, msg, "userPassword");    if (vals == NULL) {        ldap_perror(ld,"Error");        return NULL;    }    t = h = NULL;    passwd = (char *)safe_malloc((strlen(*vals) + 1));    memset((char *)passwd, 0, (strlen(*vals) + 1));    memcpy((char *)passwd, (char *)(*vals), strlen(*vals));    if (*passwd == '{') {        for (t = h = (passwd + 1); *t; t++) {            if (*t == '}') {                *t++ = '\0';                /* This is not the best, but we keep the pointer as (h - 1) */                passwd = t;                /*                   Check against the encryption method, and if we see something                   we dont recognize or support, invalidate user login.                   vol@inter7.com                */                /* Steki <steki@verat.net> Thu Jan 24 17:27:18 CET 2002                 *  Added check for MD5 crypted passwords                 */                if (strcmp(h, "crypt")&& strcmp(h, "MD5")) {                    free(h - 1);                    ldap_value_free(vals);                    return NULL;                }                break;            }        }        /*           No terminating brace found, or empty password.           vol@inter7.com        */        if (!(*t)) {            ldap_value_free(vals);            return NULL;        }    }    /* create a vpw struct, which we will populate with the data we suck in from ldap */    vpw = (struct vqpasswd *) safe_malloc(sizeof(struct vqpasswd));    memset((struct vqpasswd *)vpw, 0, sizeof(struct vqpasswd));    vpw->pw_passwd = (char *)safe_malloc((strlen(passwd) + 1));    memset((char *)vpw->pw_passwd, 0, (strlen(passwd) + 1));    memcpy((char *)vpw->pw_passwd, (char *)(passwd), strlen(passwd));    if (vpw->pw_passwd == NULL) {        free(h - 1);        ldap_value_free(vals);        return NULL;    }    /*       Old passwd pointer.       ..and don't forget to check if you even set the pointer *smack*       vol@inter7.com    */    if (h)        free(h - 1);    ldap_value_free(vals);    /* uid / pw_name */    vals = ldap_get_values(ld, msg, "uid");    if (vals == NULL) {        safe_free((void **) &vpw->pw_passwd);        ldap_perror(ld,"Error");        return NULL;    }    vpw->pw_name = (char *)safe_malloc((strlen(*vals) + 1));    memset((char *)vpw->pw_name, 0, (strlen(*vals) + 1));    memcpy((char *)vpw->pw_name, (char *)(*vals), strlen(*vals));    ldap_value_free(vals);    /* mailQuota / pw_shell */    vals = ldap_get_values(ld, msg, "mailQuota");    if (vals)        vpw->pw_shell = (char *)safe_malloc((strlen(*vals) + 1));    else        vpw->pw_shell = (char *)safe_malloc(1);    if (vals) {        memset((char *)vpw->pw_shell, 0, (strlen(*vals) + 1));        memcpy((char *)vpw->pw_shell, (char *)(*vals), strlen(*vals));        ldap_value_free(vals);    } else {        *vpw->pw_shell = '\0';        ldap_perror(ld,"Error");    }    /* qmaildomain / pw_gecos */    vals = ldap_get_values(ld, msg, "qmaildomain");    if ( vals ) {        vpw->pw_gecos = (char *)safe_malloc((strlen(*vals) + 1));        memset((char *)vpw->pw_gecos, 0, (strlen(*vals) + 1));        memcpy((char *)vpw->pw_gecos, (char *)(*vals), strlen(*vals));        ldap_value_free(vals);    } else        ldap_perror(ld,"Error");    /* mailMessageStore / pw_dir */    vals = ldap_get_values(ld, msg, "mailMessageStore");    if ( vals ) {        vpw->pw_dir = (char *)safe_malloc((strlen(*vals) + 1));        memset((char *)vpw->pw_dir, 0, (strlen(*vals) + 1));        memcpy((char *)vpw->pw_dir, (char *)(*vals), strlen(*vals));        ldap_value_free(vals);    } else        ldap_perror(ld,"Error");    /* qmailUID / pw_uid */    vals = ldap_get_values(ld, msg, "qmailUID");    if ( vals ) {        vpw->pw_uid = atoi(*vals);        ldap_value_free(vals);    } else        ldap_perror(ld,"Error");    /* qmailGID / pw_gid */    vals = ldap_get_values(ld, msg, "qmailGID");    if ( vals ) {        vpw->pw_gid = atoi(*vals);        ldap_value_free(vals);    } else        ldap_perror(ld,"Error");#ifdef CLEAR_PASS    /* clearPasswd /  pw_clear_passwd */    vals = ldap_get_values(ld, msg, "clearPassword");    if ( vals ) {        vpw->pw_clear_passwd = (char *)safe_malloc((strlen(*vals) + 1));        memset((char *)vpw->pw_clear_passwd, 0, (strlen(*vals) + 1));        memcpy((char *)vpw->pw_clear_passwd, (char *)(*vals), strlen(*vals));        ldap_value_free(vals);    }#endif    vlimits_setflags (vpw, domain);    return vpw;}/***************************************************************************/void vauth_end_getall() {}/***************************************************************************/struct vqpasswd *vauth_getall(char *domain, int first, int sortit) {    int ret = 0;    size_t len = 0;    struct vqpasswd *pw = NULL;    LDAPMessage *res = NULL;    char *filter = NULL, **vals = NULL;    char *basedn = NULL;    /* if 1st time through, extract all users from this chosen domain */    if (first) {        lowerit(domain);        len = (32 + 1);        filter = (char *)safe_malloc(len);        memset((char *)filter, 0, len);        /* set basedn to be of the format :         *   ou=somedomain,o=vpopmail         */        if (compose_dn(&basedn,domain) != 0)  {            safe_free((void **) &filter);            return NULL;        }        snprintf(filter, len, "(objectclass=qmailUser)");        /* connect to the ldap server if we havent already done so */        if (ld == NULL ) {            if (ldap_connect() != 0) {                safe_free((void **) &filter);                return NULL;            }        }        /* perform the lookup for all users in a given domain */        ret = ldap_search_s(ld, basedn, LDAP_SCOPE_SUBTREE,                            filter, vldap_attrs, 0, &res);        safe_free((void **) &basedn);        safe_free((void **) &filter);        if (ret != LDAP_SUCCESS) {            ldap_perror(ld,"Error");            return NULL;        }        /* sort the entries alphabetically by username if required */        if ( sortit ) {            if ( ldap_sort_entries( ld, &res, "uid", &strcasecmp ) != 0)  {                ldap_perror(ld,"Error");                return NULL;            }            if (ret != LDAP_SUCCESS)                return NULL;        }        /* get a pointer to the first user in the list */        glm = ldap_first_entry(ld, res);        if (glm == NULL)            return NULL;        /* grab the ldap properties of this user */        vals = ldap_get_values(ld, glm, "uid");        if (vals == NULL) {            ldap_perror(ld,"Error");            return NULL;        }        /* grab the vpopmail properties of this user */        pw = vauth_getpw(*vals, domain);        return pw;    }    else {        /* not 1st time through, so get next entry from the chain */        if (glm == NULL)  /* Just to be safe. (vol@inter7.com) */            return NULL;        res = glm;        glm = ldap_next_entry(ld, res);        if (glm == NULL)            return NULL;        vals = ldap_get_values(ld, glm, "uid");        if (vals == NULL) {            ldap_perror(ld,"Error");            return NULL;        }        pw = vauth_getpw(*vals, domain);        ldap_value_free(vals);        return pw;    }}/***************************************************************************//*   Higher-level functions no longer crypt.   Lame.    vol@inter7.com*/int vauth_adduser(char *user, char *domain, char *password, char *gecos, char *dir, int apop ) {    char *dn = NULL;    char *dn_tmp = NULL;    LDAPMod **lm = NULL;    char dom_dir[156];    uid_t uid;    gid_t gid;    int ret = 0, vd = 0;    int i,len;    char *b = NULL;    char crypted[100] = { 0 };    if ((dir) && (*dir))        vd = 1;    if ( gecos==0 || gecos[0]==0)        gecos=user;    /* take a given domain, and lookup the dom_dir, uid, gid */    if ( vget_assign(domain, dom_dir, 156, &uid, &gid ) == NULL ) {        fprintf(stderr, "failed to vget_assign the domain : %s", domain);        return (-1);    }    if (vd) {        ret = strlen(dom_dir) + 5 + strlen(dir) + strlen(user);    } else {        ret = strlen(dom_dir) + 5 + strlen(user);    }    b = (char *)safe_malloc(ret);    memset((char *)b, 0, ret);    if (vd) {        snprintf(b, ret, "%s/%s/%s", dom_dir, dir, user);    } else {

⌨️ 快捷键说明

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