?? vldap.c
字號:
/* * $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 + -